5
votes

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?

2
What happens if you make a shared folder on notebook50, and try to access it from your other computer ? Does it prompt for login? If you login with the login form, and then try to access notebook50:87/test does it work then ? - Magic-Mouse
"Is this related with the Service Principle Name" quite possibly. My first question is WHY are you using Kerberos, I have in the past spend 2 man weeks fruitlessly debugging Kerberos (are you sure you can't use NTLM). Secondly, Kerberos requires a huge number of things to get right for it to work, one of which is that the client needs to authenticate the server...which is what the SPN is. The SPN MUST match the DNS entry you use to access the server (in this case notebook50, which is almost certainly DOES NOT, as by default , if that even happened, it would be set to the FQDN of your server). - Aron
@Magic-Mouse Sorry dude. Your comment is not helpful. This is clearly an issue with Kerberos auth. - Aron
What is the identity of the application pool which is running your application? - Peter Kiss
There is no application pool involved. It's a standalone windows service running the wcf rest service. - Manuel

2 Answers

3
votes

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.

0
votes

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.