How to force soap header authentication for my scenario? - asp.net

The problem is: I need to connect to a soap web service; generated by java code; using ASP.Net client via C# through MS Visual Studio 2013.
Try 1, The usual way:
I have added a web service reference using the wsdl and by assigning the credentials like:
Credentials.Username.Username = "test";
Credentials.Password.Password = "test";
When executing, the following exception is being encountered:
The login information is missing!
Try 2:
I have searched for similar problems like:
how-to-go-from-wsdl-soap-request-envelope-in-c-sharp
Dynamic-Proxy-Creation-Using-C-Emit
c# - Client to send SOAP request and received response
I had chosen to generate a proxy class using the wsdl tool, then added the
header attribute, but I have found the following note from Microsoft:
Note: If the Web service defines the member variables representing the SOAP headers of type SoapHeader or SoapUnknownHeader instead of a class deriving from SoapHeader, a proxy class will not have any information about that SOAP header.
Try 3:
I have tried to change the service model in the client web.config:
<bindings>
<basicHttpBinding>
<binding name="CallingCardServicePortBinding">
<security mode="TransportWithMessageCredential" >
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
Then added the credentials like the first try, but the following error appears:
MustUnderstand headers:[{http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] are not understood
So, now I don't know what to do !
I have no control over the web service and I need to build a client that understands it.
Help Please!
The Soap Request template is the following:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="...">
<soapenv:Header>
<credentials>
<userName>someUserName</userName>
<password>somePassword</password>
</credentials>
</soapenv:Header>
<soapenv:Body>
<ser:someRequest>
.......
.......
.......
</ser:someRequest>

If the destination web service uses authentication, then just ASMX won't do, since it is not aware of authentication, encryption etc. You have 2 options:
Use Microsoft WSE: http://www.microsoft.com/en-us/download/details.aspx?id=14089
this is nothing but an extension of ASMX which makes it Security/Encryption aware. (and some other features) technically, you'll be adding a reference to the WSE DLL and your Soap Proxy will extend from the WSE SOAP Client instead of the System one.
once you do that, the proxy class will have additional username/password properties that you can use to authenticate properly.
set the properties and see the outgoing request using fiddler. if the header is not what you want (because of namespaces etc.), then you can write a custom outgoing message inspector and modify the soap request nicely.
The other option (preferred) is to use WCF.
ASMX and WSE are older than WCF. WCF tries to bring all the web service nuances under one roof. if you get a WCF service reference, it (svcutil.exe) will automatically create the proxy class and the right bindings for you. (mostly custom)
once you do that, try setting the user name and password.
if that doesn't work, (i have frequently struggled to generate the right soap header for remote java based services that require username/password authentication), you can define a static header chunk in the web.config/app.config, that'll be sent as part of every request.
e.g.
<client>
<endpoint>
<headers>
<credentials>
<userName>someUserName</userName>
<password>somePassword</password>
</credentials>
</headers>
</endpoint>
</client>

Related

ASP.Net Web.config client endpoint name

I have a service that has references to other services with some of them being references to different environments of the same service (e.g. prod/test).
I am using the #if precompile directive to include different versions of these references with the using statement. Example:
#if Debug
using ServiceTest
#else
using ServiceProd
#endif
In the Web.config file I have two child nodes inside the <client> node. Example:
<client>
<endpoint address="http://test.domain.com/Service"
binding="basicHttpBinding" bindingConfiguration="Service"
contract="ServiceTest" name="Service" />
<endpoint address="http://prod.domain.com/Service"
binding="basicHttpBinding" bindingConfiguration="Service"
contract="ServiceProd" name="Service" />
</client>
Is the above part of the Web.config valid or not? More precisely, can there be any side-effects because of having two endpoints with the same name and binding configurations? The main concern is having a wrong endpoint called (e.g. calling prod endpoint instead of test or the other way around).
Any guidance and advice regarding the above will be really appreciated.
Is the above part of the Web.config valid or not?
Every time when you run your application CLR reads web.config file and deserialize it as an object. To deserialize XML it's uses classes declaration in "configSections" section of your config file.
So, the answer "valid or not" depends on implementation of "client" configuration section. I believe this should be part of your application or code from nuget library. This is why we can't answer you with confidence.
More precisely, can there be any side-effects because of having two endpoints with the same name and binding configurations?
Frankly, I don't understand how this should work. In what manner 3rd library should know that it needs to load first but not second client endpoint?
Possible solutions.
You can use web.config transformation. There are tons of resources about this feature of .NET Framework.
The simplest scenario would be to substitute endpoint address keeping the same endpoint name.
Another common scenario is to give different endpoint names and keep "alive" endpoint name in AppSettings. In this case your code should resolve endpoint name first and then actual endpoint address.

Forms Authentication Cookie and WCF

I have an asp.net 4.0 application (client) that makes ajax/json calls to a http facade that then passes on the calls to our wcf service layer.
Users must authenticate on the client using forms authentication. The idea then being that the authentication cookie will be passed to and be accessible at the http facade. [Design based on Dino Esposito's book - Microsoft ASP.NET and AJAX: Architecting Web Applications]
The problem is, that at the facade, HttpContext.Current.User.Identity.Name is an empty string and IsAuthenticated is false.
I have enabled compatibility by adding the following to my system.ServiceModel section in my web.config (http facade level):
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
I have decorated my service with the following:
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Required)]
When I am debugging in the ajax/facade app I can see that cookies exist at HttpContext.Current.Request.Cookies. It appears that Anonymous is being used and not my authenticated user.
Both applications are running on the same IIS server.
Calls to the AJAX enabled wcf service are made via serviceProxy.js. Perhaps this method is not passing the necessary cookie?
WCF tracing is currently showing '..ASPXANONYMOUS=.....; ASP.NET_SessionId=....; .ASPXAUTH=.....' in the message log.
I get the feeling I am missing something simple but am too close to the problem.
Any suggestions welcomed.
I am not sure I completely understand the context of what you are trying to accomplish, but if these are two separate applications you are going to need to share machine keys in order to decrypt/encrypt the auth cookies in both.
in your web.config, make sure you have the following set:
<machineKey
validationKey="[generated key]"
validation="HMACSHA512"
decryptionKey="[generated key]"
decryption="AES"
/>
see how to generate these keys (and more info about them) on this codeproject article:
ASP.Net machineKey Generator - CodeProject
Let me know if this helps...

Can't get FormsAuthentication to properly work with WCF

I have both the wcf and asp.net project together in the same project. (I'm running on Azure, so this is more convenient).
I have this set in the web.config:
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
My wcf service is decorated with:
[AspNetCompatibilityRequirements(
RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
With those attributes set, shouldn't the HttpContext.Current.User be automatically set for me when I run methods in my wcf service? Currently, HttpContext.Current.User is null and not being set for me automatically.
I thought if I used aspNetCompatibilityEnabled then the Application_AuthenticationRequest method would fire in the Global.asax when the wcf method is executed, but, it does not.
The .aspxauth cookie is getting correctly passed to the wcf service, and I'm able to manually decrypt the cookie and set the current user.
Suggestions of why this is not working the way I expect?
Are you getting the expected user identity in the
ServiceSecurityContext.Current.PrimaryIdentity
field which is available inside your server method's code?? It should be some form of an IIdentity descendant giving you the user info, if available.

How to expose a wcf service to different clients

I am creating a wcf service. When i add the service as a "Web reference" to my web site (I do this by using the url: http://localhost/myservice.svc?wsdl ) and then call the web methods exposed by the service, I get a "Operation has timed out" exception. However when i add the service as a "Service Reference" to the site, the calls work fine.
The reason iam adding it as a web reference is, i want to expose the wcf service to all clients like java, php .....
I have looked at the article in "http://blogs.msdn.com/juveriak/archive/2008/03/18/wcf-proxy-that-works-with-different-clients.aspx", but i have not tried converting the wsdl to a typed proxy as suggested by this article.
Any ideas on why i get a time out error when using it as a web reference?
Likely you're using WsHttpBinding rather than BasicHttpBinding. .NET 2.0 web services cannot consume a WsHttpBinding service.
The problem is one of protocol. Web service protocols are constantly changing, adding security, federated identity, and so forth. As they change, older technologies can't communicate using the newer protocols.
Thankfully, WCF will allow you to use multiple protocols in a single service -- just set up separate endpoints for each protocol you want to use. Be wary, however, as some are more secure than others.
Regarding versioning, the MessageVersion class is a good starting point.
Edit: I should have mentioned that you need to use MessageVersion as part of a custom TextMessageEncodingBindingElement binding, like so:
<bindings>
<customBinding>
<binding name="MyBinding">
<textMessageEncoding messageVersion="Soap11WSAddressing10"/>
<httpTransport/>
</binding>
</customBinding>
</bindings>

Public WCF service requires authentication, despite no security being specified

I have published a WCF service (MyService.svc) on an ASP.NET site, in a sub-folder called WebServices.
When running on the local ASP.NET web server it works fine. When published to an IIS-run site and I try to access, for example, /WebServices/MyService.svc/jsdebug, I get 401 Unauthorized. The rest of the site works fine.
Does anyone have any idea why?
Here are the contents of MyService.svc:
<%#ServiceHost
Language="C#"
Debug="true"
Service="MyApp.Core.MyService, MyApp.Core"
Factory="System.ServiceModel.Activation.WebScriptServiceHostFactory"
%>
MyApp.Core.MyService is a class implementing IMyService (which has the attribute ServiceContract and method declarations with the attribute OperationContract).
By default, a WCF service will do Windows authentication unless configured otherwise. I think the following should do the trick:
<bindings>
<wsHttpBinding>
<binding name="wsHttp">
<security mode="None"/>
</binding>
</wsHttpBinding>
</bindings>
..and configure your endpoint to use this binding config.
There are 3 possible places where the call is getting blocked:
The IIS Settings, check that anonymous authentication is enabled
NTFS File access settings, check that the user that is the identity of the application pool has read access.
the web.config, check that authentication mode is None.
All of the above are before it gets to what could be blocking it in the WCF configuration. But from your comment to blowdart it looks like you have not configured WCF security.
Check also your IIS log for 401 errors. And check if this post is relevant.
And what does the web.config say? Do you have authentication there, either on the service itself, or the directory? Is transport security on or off? Message security?
The svc files do not configure security, that's part of the config file

Resources