I am attempting to obtain a Kerberos Token from a C# Application (not web-based, a standalone executable).
I have referred to this question to figure out how to do it, but even trying both answers, I get the same problem.
When I reach the GetToken line (using Furkat's answer as a reference here), I get an exception:
KerberosRequestorSecurityToken securityToken = tokenProvider.GetToken(TimeSpan.FromMinutes(1)) as KerberosRequestorSecurityToken;
Here is the exception and the nested innerExceptions:
Exception: The NetworkCredentials provided were unable to create a Kerberos credential, see inner exception for details.
innerException: Authenticating to a service running under a user account which requires Kerberos multilegs, is not supported.
innerException: The function completed successfully, but must be called again to complete the context
I have some serious problems trying to find any examples of this working for a non-web based application, the StackOverflow question I linked is pretty much the closest I've got to getting what I need.
I also have problems figuring out exactly how things are supposed to work, since I can't get an example to work on my side. I'm looking for some sort of unique token for the user, that can then be passed to a SAML POST call to a server for Single Sign On. What will this token look like? Is it right to use TokenImpersonationLevel.Impersonation, instead of Identification here? (Identification gives me the same problem).
So my question is about my error and how to fix it, but I would really appreciate an explanation with the answer, telling me about the context (what was going wrong, what I misunderstood, etc).
Here's my complete Method. It's in Proof-Of-Concept stage right now, so forgive the temporary bad naming and ugly code. I'm making lots of trial-and-error.
public string Method5()
{
try
{
var userName1 = new WindowsPrincipal(WindowsIdentity.GetCurrent()).Identity.Name;
var domainName = userName1.Split('\\').First();
var userName = userName1.Split('\\').Last();
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
var domain = Domain.GetCurrentDomain().ToString();
using (var domainContext = new PrincipalContext(ContextType.Domain, domain))
{
string spn = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName).UserPrincipalName;
KerberosSecurityTokenProvider tokenProvider = new KerberosSecurityTokenProvider(spn, TokenImpersonationLevel.Impersonation, CredentialCache.DefaultNetworkCredentials);
KerberosRequestorSecurityToken securityToken = tokenProvider.GetToken(TimeSpan.FromMinutes(1)) as KerberosRequestorSecurityToken;
string serviceToken = Convert.ToBase64String(securityToken.GetRequest());
return serviceToken;
}
}
catch (Exception ex)
{
return "Failure";
}
}