1

I am trying to get a Kerberos token for the current user logged into Windows to make a request to a REST service that accepts Kerberos authentication.

I am using the following C code based on the solution to this question: How to get Service Token from Kerberos using SSPI

The variables domain and foundUser seem to be getting set correctly. But the Network Credentials are empty. This causes the call k1.GetToken() to throw the error System.IdentityModel.Tokens.SecurityTokenValidationException.

How can I get the Kerberos token for the user?

    public String getToken(string userName)
    {
        AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
        var domain = System.DirectoryServices.ActiveDirectory.Domain.GetCurrentDomain().ToString();
        using (var domainContext = new PrincipalContext(ContextType.Domain, domain))
        {
            using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName))
            {
                NetworkCredential networkCred = System.Net.CredentialCache.DefaultNetworkCredentials;
                string spn = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName).UserPrincipalName;
                KerberosSecurityTokenProvider k1 = new KerberosSecurityTokenProvider(spn, System.Security.Principal.TokenImpersonationLevel.Impersonation, networkCred);
                KerberosRequestorSecurityToken T1 = k1.GetToken(TimeSpan.FromMinutes(1)) as KerberosRequestorSecurityToken;
                string sret = Convert.ToBase64String(T1.GetRequest());
                return sret;
            }
        }

    }
abatishchev
  • 98,240
  • 88
  • 296
  • 433
George Hernando
  • 2,550
  • 7
  • 41
  • 61

1 Answers1

4

The following line is incorrect:

KerberosSecurityTokenProvider k1 = new KerberosSecurityTokenProvider(spn, System.Security.Principal.TokenImpersonationLevel.Impersonation, networkCred);

You're telling it to get a Kerberos ticket for the current user targeted to a service with the name of SPN, which happens to be the name of the current user.

The point of the SPN parameter is to specify the name of the service you want a ticket to. Kerberos does not let you just get a ticket that can be used anywhere. You must request a ticket for a particular service.

An SPN takes the form of service/host.com@optional.realm.com. Since it's a REST service it's most likely going to be HTTP/your.service.com.

Keep in mind that SPN must be registered to the service principal in Active Directory, otherwise the client will have no way to look up the service.

Steve
  • 4,463
  • 1
  • 19
  • 24
  • The only thing to add to that is that the principal your code is running under should have the right to request tickets. If that is failing event viewer security logs would have failed authorization attempts. – zaitsman Mar 27 '19 at 22:27