This project has moved. For the latest updates, please go here.

Web API v2: OWIN SelfHost with SSL and Windows Authentication

May 31, 2014 at 12:02 AM
Edited May 31, 2014 at 12:06 AM
I have an OWIN SelfHost (Console Application) and a Test Client (HttpClient, Console Application as well). Both use the latest OWIN and Web API v2 stuff from Nuget (using VS 2013, .NET 4.5.1)

I have configured a SSL certificate on my dev machine. The SSL configuration is done by netsh.

Scenario 1:

OWIN SelfHost and Test Client via SSL (https://....) without any authentication (anonymous): WORKS FINE! :-)

Scenario 2:

OWIN Selfhost and Test Client without SSL (http://...) with Windows Authentication and [Authorize]-Attribute at Controller-Class: WORKS FINE! :-)

Scenario 3:

OWIN SelfHost and Test Client via SSL (https://....) and Windows Authentication and [Authorize]-Attribute at Controller-Class: EXCEPTION in Test Client (401) :-(

"Response status code does not indicate success: 401 (Unauthorized)."

What's wrong here? As soon as I try the combination of SSL and Windows Authentication, I get this exception at the Test Client.

Thanks
Felix
Coordinator
May 31, 2014 at 3:06 AM
When you combine Windows Auth + SSL the server may more strictly validate the host name (SPN). It may also be trying to use Extended Protection, but I doubt you've tried to turn that on.

Some info first:
  • Are the client and server on the same machine, or separate ones?
  • What's the exact address registered on the server?
  • What's the full address used by the client?
  • What AuthenticationSchemes values are you using? (Anonymous | IntegratedWindowsAuthentication)?
I ask because it's possible to register a wildcard host on the server, but that makes the host name validation more fragile. It also matters if you end up using Kerberos or NTLM.
May 31, 2014 at 7:17 AM
Client and server process are running on the same machine (Windows 8.1 64 Bit). Everything runs in a Domain (AD). The user is a domain user and local admin.

Registration on the server (OWIN SelfHost):
            // Start OWIN host 
            using ( WebApp.Start<Startup>( new StartOptions( __"https://+:444/"__ ) { ServerFactory = "Microsoft.Owin.Host.HttpListener" } ) )
            {
                 Console.WriteLine( "\nPress any key to exit..." );
                 Console.ReadLine(); 
            }
The URL is the same as in the SSL configuration for the server (netsh http add urlacl .....)

URL used by the client:
            var handler = new HttpClientHandler
            {
                UseDefaultCredentials = true
            };

            var client = new HttpClient( handler )
            {
                BaseAddress = new Uri( __"https://nfengine.local:444/api/"__ )
            };
nfengine.local is the hostname used for the SSL certificate.

Used AuthenticationSchemes on the server side::
        public static IAppBuilder UseWindowsAuthentication ( this IAppBuilder app )
        {
            object value;
            if ( app.Properties.TryGetValue( "System.Net.HttpListener", out value ) )
            {
                var listener = value as HttpListener;
                if ( listener != null )
                {
                    listener.AuthenticationSchemes = AuthenticationSchemes.__IntegratedWindowsAuthentication__;
                }
            }

            return app;
         }
Again, both mechanisms (SSL, Windows Authentication) work quite well on their own. But not the combination of both (on one machine, did not test the same with two distinct boxes yet).

Thanks.
May 31, 2014 at 7:46 AM
How to turn on Extended Protection? I am not a real security expert (depths of TLS, NTLM, etc.).

May be this is the reason for the 401 result when using the combination of SSL and Windows Authentication.
Coordinator
May 31, 2014 at 3:47 PM
Ok, first try making the registration host match what the client is sending "https://nfengine:444/". Is the .local on there for fiddler? I suggest removing it. You may also want to try using the full domain name at each end "nfengine.mydomain.com".

If none of those things work, try changing the auth type to NTLM as to disable Negotiate/Kerberos.

Side note: specifying IntegratedWindowsAuthentication without also including Anonymous will always require users to login. This makes your [Authorize] attribute redundant.
Jun 1, 2014 at 8:44 AM
Edited Jun 1, 2014 at 8:59 AM
A matching URI for registration at the server side does not work. I have to use the syntax from the registration with netsh:
https://+:444/
Only this works. See this blog entry as well:

HttpSelfHostServer hosted Web API with HTTPS and Windows authentication enabled

The .local is just for naming reasons (local machine). I tried "nfengine.mydomain.com" as well, but that doesn't change anything.

And I changed the auth type to NTLM. No success. :-(

Is there any running sample with step by step instructions available for this scenario (OWIN Selfhost, SSL, Windows Authentication, .NET Client using HttpClient)?

I could imagine that this scenario will be a very common one in the future for the Web API when migrating Enterprise Multi Tier Solutions in the Intranet based on WCF for the service layer to a RESTful Service infrastructure based on Web API.
Coordinator
Jun 1, 2014 at 3:03 PM
Yes, what you register with Katana has to match what you register with netsh. For the sake of troubleshooting I was suggesting you try running the server on https://nfengine.mydomain.com:444/, while updating the netsh registration to match.

Yes this is a common scenario, and we haven't had any other complaints about it.
Jun 1, 2014 at 7:00 PM
Okay, now I have used the complete DN of my machine for the SSL Certificate, the SSL Registration and the URI used by the OWIN Selfhost and the .NET client.

And now it works. :-) Thank you so much!