Manuel
Manuel

Reputation: 2213

WCF Rest service Windows authentication via Browser

Given is a wcf rest service which runs with HttpClientCredentialType.Windows and enforces a user to authenticate via kerberos.

        private static void Main(string[] args)
    {
        Type serviceType = typeof (AuthService);
        ServiceHost serviceHost = new ServiceHost(serviceType);

        WebHttpBinding binding = new WebHttpBinding();
        binding.Security.Mode = WebHttpSecurityMode.TransportCredentialOnly;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

        ServiceEndpoint basicServiceEndPoint = serviceHost.AddServiceEndpoint(typeof(IAuthService), binding,  "http://notebook50:87");
        basicServiceEndPoint.Behaviors.Add(new WebHttpBehavior());

        Console.WriteLine("wcf service started");
        serviceHost.Open();
        Console.ReadLine();
    }

    public class AuthService : IAuthService
{
    public List<string> GetUserInformation()
    {
        List<string> userInfo = new List<string>();
        userInfo.Add("Environment.User = " + Environment.UserName);
        userInfo.Add("Environment.UserDomain = " + Environment.UserDomainName);
        if (OperationContext.Current != null && OperationContext.Current.ServiceSecurityContext != null)
        {
            userInfo.Add("WindowsIdentity = " + OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name);
            userInfo.Add("Auth protocol = " + OperationContext.Current.ServiceSecurityContext.WindowsIdentity.AuthenticationType);
        }
        else
        {
            userInfo.Add("WindowsIdentity = empty");
        }
        WebOperationContext.Current.OutgoingResponse.ContentType = "text/plain";
        return userInfo;
    }
}

[ServiceContract]
public interface IAuthService
{
    [OperationContract]
    [WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "test/")]
    List<string> GetUserInformation();
}

When i run this as a console application, and then open the website http://notebook50:87/test/ in internet explorer from another computer, i get a 'bad request' response. I did enable kerberos logging, and it shows me KDC_ERR_PREAUTH_REQUIRED

I can solve this problem by creating a windows service, and run it under 'Local System account'. In this case, a client is able to authenticate.

Question: What permission/settings does a user(which runs this wcf service) need in order to get the same behavior as when the application is running as windows service under local system? Is this related with the Service Principle Name?

Upvotes: 5

Views: 977

Answers (2)

Manuel
Manuel

Reputation: 2213

It is working now. It really was a problem with the SPN At the beginning, I've set the SPN like setpn -A HTTP/notebook50.foo.com, and with this, the kerberos authentication didn't work.

Now, i've set it like setspn -A HTTP/notebook50.foo.com username where username is the user under which the service runs.

From the SPN documentation i've read, it was not clear to me that i have to set the user account in this way.

It would be great if one could explain what happens here, and probably a link to a documentation for this scenario.

Upvotes: 3

Frix33
Frix33

Reputation: 1241

You can stop this error pops up via enable the "Do not require Kerberos preauthentication" option for that user account in Active directory users & computers -> properties -> account.

Upvotes: 0

Related Questions