WCF/basicHttp and NTLM authentication - wcf

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

Related

AD authentication in REST wcf

I am new to adding security to WCF service. I have developed a REST based WCF service which works fine.
This service is consumed by HTTP POST (outside the domain). I need to incorporate domain (AD) authentication.
How can I incorporate AD authentication in WCF? Additionally, what should I be asking details related to AD to client? Please guide me.
Updated:
Added authenticationScheme="Negotiate" to httpTransport.
Hosted service in IIS & disabled Anonymous authentication. Also tried enabling Forms authentication.
At wcf client, passing domain/id/pwd like: webrequest.Credentials = new NetworkCredential("user", "userpwd", "domain");
I am getting HTTP Error 401.2 - Unauthorized. You are not authorized to view this page due to invalid authentication headers.
Am I missing something?
You need to a biding configuration in your WCF web.config:
<bindings>
<basicHttpBinding>
<binding name="SecurityByTransport">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
You can read more about here:
http://msdn.microsoft.com/en-us/library/ms733089(v=vs.110).aspx
For javascript ajax calls you can follow this recommendation:
Cross domain jQuery ajax call with credentials

Authentication on WCF Service using BasicHttpBinding and Authorization header

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.

Accessing ServiceSecurityContext.Current.PrimaryIdentity.Name from within a WCF service

I'm very new to WCF, but I've searched this topic pretty thoroughly and haven't come up with a satisfactory answer, so here goes my question:
While within my WCF service, I need to access the user's username. From everything I've read, I should be able to get that from ServiceSecurityContext.Current.PrimaryIdentity.Name. However, instead of returning Domain\Username as I had hoped, it always returns NT AUTHORITY\NETWORK SERVICE . How can I get the actual Domain and Username of the individual that is logged in to the machine accessing my service?
Thanks.
Have you looked at the ServiceSecurityContext Class?
Represents the security context of a remote party. On the client,
represents the service identity and, on the service, represents the
client identity.
e.g.
ServiceSecurityContext.Current.WindowsIdentity.Name
...ensuring that you have your service set up to authenticate via Windows security.
To Use Windows credentials , set the clientCredentialType to "Windows". use wsHttpBinding, or netTcpBinding if its within LAN
<bindings>
<netTcpBinding>
<binding name="WindowsCredentials">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>

wcf Binding configuration and security

I'm reading a book on Wcf. I always get confused when there is topic on binding configuration. Eg. In one chapter for securing service in internet environment, author used the following code in the config file.
<bindings>
<wsHttpBinding>
<binding name="ProductsServiceWSHttpBindingConfig">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None"/>
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
Everything works fine as described in the book. But I don't see any description in book, why TransportWithMessageCredential is used in place of Transport. Similarly why the <transport ... is None and <message ... is not None. Is there any matrix (or any other way to figure out) about which options to use with which binding (and in which environment)? My hunch is that certain options will go with certain binding. Thanks in advance.
Yep, here's a few:
http://msdn.microsoft.com/en-us/library/ms730879.aspx
http://mkdot.net/blogs/dejan/archive/2008/03/31/wcf-binding-decision.aspx
http://architectopia.blogspot.com/2008/01/wcf-binding-decision-chart.html
I know this question is already been answered however heres are some thoughts for those who are looking for quick answer.
TransportWithMessageCredential is basically saying that the transmission is over https (secure) and the username and password will be in security header.
"Client authentication is performed by putting the client credential directly in the message. This allows you to use any credential type that is supported by the message security mode for the client authentication while keeping the performance benefit of transport security mode."
http://msdn.microsoft.com/en-us/library/aa354508.aspx

WCF - Preventing Unauthorized Clients

I have a WCF service that I only want my applications to have access to. My applications consist of a traditional web interface that uses JQuery and a Silverlight interface. Neither of these interfaces require the user to login.
Is there a way that I can tell a WCF service to only allow clients that originated from my domain? If so, how?
Thank you!
Yes, of course you can - just require Windows credentials (i.e. an Active Directory account in your domain) from your callers.
Anyone not authenticated against your domain will be rejected.
You can do this by specifying either netTcpBinding with transport security (if everything is behind a corporate firewall), or wsHttpBinding with message security:
<bindings>
<netTcpBinding>
<binding name="DomainUsersOnly">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
<wsHttpBinding>
<binding name="HttpDomainUsersOnly">
<security mode="Message">
<message clientCredentialType="Windows" />
</security>
</binding>
</wsHttpBinding>
</bindings>
Now, all you need to do is reference one of those binding configurations in your endpoints:
<endpoint name="whatever"
address="......"
binding="netTcpBinding"
bindingConfiguration="DomainUsersOnly"
contract="IYourservice" />
and you should be good to go.
If all of your legitimate users are supposed to be on your internal corporate LAN (on the same subnet), then you could lock it down by IP address using an approach like this. You could also clamp it down to several specific IP masks that way if you wanted to.
But if you want to allow legitimate users to hit it from anywhere, then this is not a good approach. Authentication would be better in that case.
You could add a security restriction in IIS to only allow calls from the domain to the webservice.
Unless you consider windows auth (since requests are coming from your domain), the preferred way to do this would be at a different level, via firewalls. At that level, you can restrict incoming traffic to a known set of IP addresses. This will only go so far, since IPs can be spoofed, but this is an open service, so there you go. A better alternative would be both firewalls and windows auth.
Alternatively, you could check client IP addresses in WCF by querying OperationContext.Current.IncomingMessageProperties.