Authenticate with Kerberos in .NET Web API - wcf

I need to implement solution Desktop Client + Application server (Web Service) in .NET.
The Client shall Authenticate against Active Directory (Kerberos Single Sign On) and forward its verified Active Directory identity to Web Service (NET Web API or WCF).
Web-service should verify that the Client is signed against Active Directory. Both computers (Client and server) are running in one AD domain.
I suppose that this can be implemented using WCF (see code here), but today NET Web API is preferred over Windows Communication Foundation. It is possible to implement it in ASP Web API as well?
Similar question not answered is here.

Yes, it is possible. The answer is here: https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/integrated-windows-authentication
The API can use Windows authentication. The authentication is handled by IIS, as long as you have your web.config setup right, as described in that article.
From your application, you just need to tell it to pass the Windows credentials by using the UseDefaultCredentials property:
HttpClientHandler handler = new HttpClientHandler() {
UseDefaultCredentials = true
};
HttpClient client = new HttpClient(handler);

Related

Using Microsoft integrated windows authentication with WCF but without IIS

Is there a way to get the behavior of Microsoft Integrated Windows Authentication w/o having to deploy using IIS? We have our own standalone C#/WCF WebServer and we would like to add this functionality. We cannot use IIS as part of our deployment.
WCF is "self hosting". That's mean, you don't have to have an IIS in order to run it on the server (Depending on your implementations of of course). You can even run it on client's computers.
Look at this article for more information about WCF authentications:
Authentication and Authorization in WCF Services
And an example in this article:
Authenticate with a User Name and Password
You can set the ClientCredentialType
WebHttpBinding whb = ... ;
whb.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;
and later get the WindowsIdentity with
WindowsIdentity identity = ServiceSecurityContext.Current.WindowsIdentity;

Is delegation required to pass credentials between applications on the SAME server?

I have a Web API application and an MVC4 client application on the same web server. They are both configured for Windows Authentication. The client application has impersonation enabled.
When I run the client in Visual Studio, it successfully passes my windows credentials to the Web API.
When I hit the client on the web server, the Web API receives "NT AUTHORITY\NETWORK SERVICE" which I guess is coming from the application pool the client app is running in.
Client passes credentials as follows:
HttpClientHandler handler = new HttpClientHandler()
{
PreAuthenticate = true,
UseDefaultCredentials = true
};
HttpClient client = new HttpClient(handler);
So my question is...do I need delegation here?
The web server is not configured for this in Active Directory - but I thought as the applications are on the same server, that impersonation would be sufficient. I would turn delegation on but I need a system admin to do that - and have all sorts of hoops to jump through - so want to be sure that's what I need.
OK, in short, no - delegation was not required.
It turned out to be an impersonation issue. From what I'd read it sounded like that was what should be required since the applications are on the same server, but even though I thought I had configured it correctly, I was missing a crucial part. I needed to change two settings in aspnet.config:
<legacyImpersonationPolicy enabled="false"/>
<alwaysFlowImpersonationPolicy enabled="true"/>
More details here:
https://stackoverflow.com/a/10311823/1230905

WCF Rest with combined authentication modes

I have created a self-hosted WCF RESTful service with basic http authentication that runs over https with a self-signed SSL certificate. Everything works fine. Users access the service operations via a web browser.
The problem is that my customer now wants the service users to authenticate with BOTH basic authentication (user name + password) AND a certificate. I have not been able to achieve this.
I have seen that it could be possible to have multiple authentication schemes in WCF 4.5. I have looked into this but to no avail.
I have also come across this post (see the last answer), but when I tried it I got this error:
"An exception occurred: HTTPS listener factory was configured to require a client certificate and the authentication scheme 'Basic'. Only one form of authentication can be required at once."
My configuration is done in code, and here is what it looks like (this is the version that works):
Uri baseAdress = new Uri("https://localhost:8446/");
WebServiceHost host = new WebServiceHost(typeof(RestService));
WebHttpBinding wb = new WebHttpBinding();
wb.Security.Mode = WebHttpSecurityMode.Transport;
wb.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
host.AddServiceEndpoint(typeof(IRestService), wb, baseAdress);
host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNameValidator();
host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
host.Description.Endpoints[0].Behaviors.Add(new WebHttpBehavior { HelpEnabled = true });
host.Open();
Thanks for any tips,
Multi auth on a single endpoint is for web hosted scenarios (not selfhost). You can configure this in web host by saying clientCredentialType='InheritFromHost' and set all the auth schemes that you want to set for that particular endpoint in vdir authentication. Check out this documentation for title "Multiple authentication support".
Multiple Authentication Support
Support has been added to support multiple authentication modes, as supported by IIS, on a single WCF endpoint when using the HTTP transport and transport security. IIS allows you to enable multiple authentication modes on a virtual directory, this feature allows a single WCF endpoint to support the multiple authentication modes enabled for the virtual directory where the WCF service is hosted.

ASP.NET Client Application Services Authentication and WCF

I have a WPF application that uses Client Application Services to allow authentication (username/password logon) against a related web application that uses Forms authentication and the SqlMembershipProvider/SqlProfileProvider/SqlRoleProvider. This all works and I can reliably validate a user/password combination.
The WPF application also calls a number of WCF services that are exposed by the same web application as is used for the CAS authentication. I now want to be able to pass through the authentication details (from Client Application Services) to the WCF services in order that I can identify the user that was authenticated within those services. I also need to be able to prevent the WCF services from being used if no authentication has taken place.
I have found a couple of .NET 3.5 examples where CAS authentication is used against .asmx web services, or authentication is provided against WCF Data Services which does not use ClientBase and has authentication facilities built in, but I cannot find any examples with pure WCF. Can anybody point me toward instruction that will enable this scenario? I am using .NET 4.0 for this project.
I have also found this stackoverflow question but again this is answered for .asmx web services and not for WCF.
The closest I have gotten involves the creation of an OperationContextScope and then copying the cookie header from the ClientFormsIdentity object to an HttpRequestMessageProperty and adding this to the OutgoingMessageProperties of the current OperationContext. I then call one or more methods of the service within the lifespan of the OperationContextScope. Thing is, when I then get to the WCF service, I still cannot see anything that resembles authentication in such a way as I can identify the original user. This methodology has been taken from various examples but I am obviously missing a step at the WCF end.
I think you need to switch to the Web API that Microsoft is now having people use for WCF Services. Check out Using Forms Authentication with Web API and http://aamirposwal.blogspot.com/2012/05/aspnet-web-api-custom-authorize-and.html
Found it.
In my binding, I specified allowCookies="true".
According to Wiktor Zychla, "setting the AllowCookies property on a BasicHttpBinding to true turns on the automatic cookie management" - this means that any attempt to set a cookie in code will be ignored and this is what I was doing.

How can I simultaneously authenticate to an IIS7-hosted javascript web client and WCF service using Windows Authentication?

I have created and tested a WCF REST service that is protected with SSL and Windows Authentication through IIS 7. I have also created and tested a pure html/javascript web client that is hosted in IIS 7 that is protected with SSL and Windows Authentication -- same server, different "site" within IIS. The REST service is not public, but the web client is.
Without security, everything works beautifully, but now we are ready for field testing and security must be implemented.
My end goal is to have the user visit mywebclient.com and authenticate using their Active Directory accounts. Initially I thought it would be safe to leave the service calls from the client to the REST service unprotected (since the traffic from the web client to the web service would be internal), but this does not protect us from an internal attacker. Also, in the future, the REST services will be available to handhelds through native applications.
I've tried to gain as much information on this subject as possible, but every piece of Microsoft documentation contains client examples written in .NET.
How can I share the security context between these sites without converting the web client to a .NET-based application? Could this be accomplished by combining the web client and service into one IIS "site"?
Edit: If the client and service exist in the same app pool, does that mean they could share authentication information between client and server processes?