Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Rest service Windows authentication via Browser

Tags:

c#

wcf

kerberos

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?

like image 222
Manuel Avatar asked Oct 20 '22 02:10

Manuel


1 Answers

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.

like image 96
Manuel Avatar answered Oct 23 '22 19:10

Manuel