Authentication on WCF Service using BasicHttpBinding and Authorization header - wcf

I'm having some issue with authentication on a third party's WCF service. I don't know how it's configured, it's like a black box for me. The only thing that I know, that those webservice should use Basic authentication, but may not.
I've added fiddler, and even wireshark to analyze what's happening inside of those requests, and found out that requests with authorization header do get authenticated. So basically, using a SoapUI I was able to authenticate on those WCF service.
I've generated a test client using svcutil and specified config file like this:
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_1" useDefaultWebProxy="false" >
<security mode="Message" >
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://theurl.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_1"
contract="CA_TestMediaSaturn.IDCIntegration" name="BasicHttpBinding_2" />
</client>
Also I've added authorization information to client in code file:
client.ClientCredentials.UserName.UserName = "one";
client.ClientCredentials.UserName.Password = "two";
But I wasn't able to get those Authorization header encoded in base64.
I wonder how can I configure my client to obtain those header in order to get authorized on webservice side. I did found an article describing how to make it on your own. But maybe there is a way to make it a lot easier?
UPDATE 1:
I've just receiver service configuration settings from 3rd party vendor. Mb it can somehow help in finding out the reason of error.
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_1" >
<security mode="TransportCredentialOnly">
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>

you should set mode="Transport" instead of "Message". This will generate Authorization header. current setting is message security so authentication is inside SOAP.
EDIT: seems like you need pre-authenitcate.
in general wcf will first not send authorization header, and if the service returns a challenge to do it then it will send the message again with the header. some servers do not support this challenge mechanism and will require to send authorization header already at first shot. this is called pre authentication in .net 2. unfortunetely wcf does not support it. but you could do it yourself: first set security mode to None so WCF will not send security at all. then see example here how to add this header yourself to the wcf call.

Related

WCF client https request

I am trying to send SOAP message to endpoint starting with HTTPS. This is one way SSL, so I should not need certificate to send request.
While using the config from below I get following exception:
Could not establish secure channel for SSL/TLS with authority 'some.domain.com/endpoint'.
I tried many different transport settings, sometimes it asks for username or certification in ClientCredentials, but hey - I should not need them! I could visit the requested endpoint via browser window without any authentication.
Am I missing something in configuration? I feel a little confused right now.
<bindings>
<basicHttpBinding>
<binding name="PublisherBinding">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://some.domain.com/endpoint"
binding="basicHttpBinding" bindingConfiguration="PublisherBinding"
contract="PublisherContract" name="NotificationsEndpoint"/>
</client>
unfortunately wcf test client does not support invalid certificates. you can make it work like this Is it possible to force the WCF test client to accept a self-signed certificate? or you can use wcfstorm. second solution is better.

UsernameToken and SSL in WCF 4 web service

I am creating a web service that will be consumed by a single client in another part of the world. I don't have any knowledge or control over the technology they are using but have been asked to
"use SSL to encrypt the message during transport and use UsernameToken
for client authentication"
I'm planning to use WCF4 to create the service and know generally how to set this all up. However I'm struggling to find the correct configuration for bindings etc. Google gives me lots of results around WSE 3.0 but I'm pretty sure (please correct me if I'm wrong) that I shouldn't be using WSE for a WCF service.
This article initially seems to suggest I should be using a custom binding but then also says I should "consider using the WCF system-defined bindings with appropriate security settings instead of creating a custom binding". However I can't see any examples of what this should be.
I would be grateful if anyone can point me in the right direction.
tl;dr: What are the WCF4 config settings to support SSL and UsernameToken?
Take a look at the WsHttpBinding. You can use a security mode of TransportWithMessageCredential to use SSL and a message credential of UserName. If you are hosting in IIS set up SSL there.
You can set up the binding in config as follows.
<bindings>
<wsHttpBinding>
<binding name="secureBinding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" negotiateServiceCredential="false" establishSecurityContext="false" />
</security>
</binding>
</wsHttpBinding>
</bindings>
You can then use this binding config as follows
<services>
<service name="ServiceName">
<endpoint address="" binding="wsHttpBinding" contract="ContractType" bindingConfiguration="secureBinding" />
</service>
</services>
Both these elements are children of the system.serviceModel element in config.

WCF security in an internet scenario

I have a WCF service hosted in a Windows Service. Clients from various platforms will access the service. Now I would like to add a basic security mechanism. Ideally, the clients should use username/password for authentication.
Which binding settings do I have to use in this scenario and how can I authenticate the client? Interoperability is more important than a very secure solutions. If possible the client should not be forced to use a certificate or something the like. Additionally, authentication should not be strongly coupled with a SQL Server database. I would like to manually inspect the client credentials.
Thanks for your help
The best for your case can be BasicHttpBinding with security set to TransportWithMessageCredentials and credential type set to UserName. In this case your service will be secured with HTTPS (requires server certificate for SSL which has to be trusted on clients) and authentication will be provided on message level with UserName Token Profile (SOAP header). You can implement your own password validator.
BasicHttpBinding configuration skeleton:
<bindings>
<basicHttpBinding>
<binding name="Secured">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
If you don't want to use HTTPS you can create custom binding with HttpTransport, TextMessageEncoding and with security mode set to UserNameOverTransport. But you have to set allowInsecureTransport to true (be aware that there is some bug with WSDL generation in this setting).
Custom binding configuration skeleton:
<bindings>
<customBinding>
<binding name="Secured">
<security authenticationMode="UserNameOverTransport" allowInsecureTransport="true" />
<textMessageEncoding messageVersion="Soap11" />
<httpTransport />
</binding>
</cutomBinding>
</bindings>
See the Internet section of the Application Scenarios for guides on how to achieve this:CodePlex Application Scenarios

WCF call with windows authentication

We have a system where the users access a web server, the web server then calls a WCF service.
We would like the call to the WCF service to be made in the security context of the windows identity of the application pool on the web server.
What is the best way to do this? Can it be done purely through configuration in the web.config file.
Thanks
Shiraz
Yes, you should be able to do this, all in config:
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="WinAuth" mode="Transport">
<transport clientCredentialType="Windows" />
<bindings>
</netTcpBinding>
</bindings>
</system.serviceModel>
Of course, depending on your binding, you'd have to use a different tag under the <bindings> parent node - and of course, not all bindings support all security modes.....
In your endpoint, use the appropriate binding and then just reference this config:
<endpoint name="WCFService" address="......."
binding="netTcpBinding"
bindingConfiguration="WinAuth"
contract="......" />
That should do it! And of course, if you need message security instead of transport security, you can do that, too.
In your WCF service method, you can check to see whether or not the Windows credentials have been sent over, and what they are, by checking:
ServiceSecurityContext.Current.WindowsIdentity
This will be NULL if you don't have a Windows caller, otherwise it will show who called you.
Marc

WCF/basicHttp and NTLM authentication

Does anyone know how exactly NTLM authentication works in WCF/basicHttp? I wonder if user credentials are passed for every single service method call, or if some kind of security token is being used for subsequent service method calls.
The exact binding configuration that I am using:
<bindings>
<basicHttpBinding>
<binding name="winAuthBasicHttpBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Ntlm" />
</security>
</binding>
</basicHttpBinding>
</bindings>
I found this type of configuration on the MSDN reference. But I am not sure if this a good idea performance wise. An alternative would be providing a custom GetAuthenticationToken() kind of method to provide a security token for all subsequent requests of the client. This could be done via the Enterprise Library - Security Application Block.
Further details: The service is being consumed by Browsers/Silverlight Clients.
In this case here, every single method call will be authenticated.
What you're talking about would be what is called "secure sessions", where the client authenticates once against the server and then a common token is used for subsequent exchanges. That secure sessions features however is only available with wsHttpBinding - not with basicHttpBinding.
Marc