问题
Objective: I am trying to build Proof Of Concept client app to implement Single Sign On by using SSPI. I am new to C# and I am getting confused.
What I know and have done so far: All users are part of Active Directory domain, so I know Kerberos is being used for authentication during login. All I need to do at this point is to get service token from Kerberos so I can pass it to the service resource instead of username and password (correct me if I am wrong). I have been provided Service Principle Name (SPN) and password that has been registered with Kerberos for the service.
I was hoping not to use Platform Invocation Services to call SSPI functions, but I will if I have to. I read through ".NET Remoting Authentication and Authorization Sample - Part I" and used Microsoft.Samples.Security.SSPI for testing. I also tried using C#/.Net Interface To The Win32 SSPI Authentication API.
So far, I can get user/client credentials, build client security context. But how do I request a Service Ticket for a given SPN?
I would appreciate your help and guidance. Please be specific if you can and let me know if you have any questions.
回答1:
You can use below to get the token by giving the SPN
public String getToken(string userName)
{
using (var domainContext = new PrincipalContext(ContextType.Domain, "domain"))
{
using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName))
{
Console.WriteLine("User Principale name" + UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName).UserPrincipalName);
string spn = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName).UserPrincipalName;
KerberosSecurityTokenProvider k1 = new KerberosSecurityTokenProvider(spn, System.Security.Principal.TokenImpersonationLevel.Impersonation, new System.Net.NetworkCredential(userName, "password", "domain"));
KerberosRequestorSecurityToken T1 = k1.GetToken(TimeSpan.FromMinutes(1)) as KerberosRequestorSecurityToken;
string sret = Convert.ToBase64String(T1.GetRequest());
Console.WriteLine("=====sret========" + sret);
return sret;
}
}
}
回答2:
Code provided by Hasanthi worked perfectly for my need and I didn't have to use SSPI. I was asking wrong questions but I learned a lot about Kerberos and SSPI. Here is my code in a nutshell:
AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal);
var domain = Domain.GetCurrentDomain().ToString();
using (var domainContext = new PrincipalContext(ContextType.Domain, domain))
{
string spn = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, serviceName).UserPrincipalName;
KerberosSecurityTokenProvider tokenProvider = new KerberosSecurityTokenProvider(spn, System.Security.Principal.TokenImpersonationLevel.Impersonation, CredentialCache.DefaultNetworkCredentials);
KerberosRequestorSecurityToken securityToken = tokenProvider.GetToken(TimeSpan.FromMinutes(1)) as KerberosRequestorSecurityToken;
string serviceToken = Convert.ToBase64String(securityToken.GetRequest());
}
来源:https://stackoverflow.com/questions/37818333/how-to-get-service-token-from-kerberos-using-sspi