为 SSO 获取 Kerberos 令牌
Getting Kerberos Token for SSO
我正在尝试为登录 Windows 的当前用户获取 Kerberos 令牌,以向接受 Kerberos 身份验证的 REST 服务发出请求。
我根据这个问题的解决方案使用了以下 C 代码:
变量 domain 和 foundUser 似乎设置正确。
但是网络凭据是空的。
这会导致调用 k1.GetToken() 抛出错误 System.IdentityModel.Tokens.SecurityTokenValidationException.
如何为用户获取 Kerberos 令牌?
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;
}
}
}
下面这行是不正确的:
KerberosSecurityTokenProvider k1 = new KerberosSecurityTokenProvider(spn, System.Security.Principal.TokenImpersonationLevel.Impersonation, networkCred);
您告诉它为当前用户获取 Kerberos 票证,该票证针对的是名为 SPN 的服务,而该名称恰好是当前用户的名称。
SPN 参数的要点是指定您想要票证的服务 的名称。 Kerberos 不会让您只获得一张可以在任何地方使用的票证。您必须申请特定服务的票。
SPN 采用 service/host.com@optional.realm.com
的形式。由于它是 REST 服务,因此很可能是 HTTP/your.service.com
。
请记住,SPN 必须注册到 Active Directory 中的服务主体,否则客户端将无法查找该服务。
我正在尝试为登录 Windows 的当前用户获取 Kerberos 令牌,以向接受 Kerberos 身份验证的 REST 服务发出请求。
我根据这个问题的解决方案使用了以下 C 代码:
变量 domain 和 foundUser 似乎设置正确。 但是网络凭据是空的。 这会导致调用 k1.GetToken() 抛出错误 System.IdentityModel.Tokens.SecurityTokenValidationException.
如何为用户获取 Kerberos 令牌?
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;
}
}
}
下面这行是不正确的:
KerberosSecurityTokenProvider k1 = new KerberosSecurityTokenProvider(spn, System.Security.Principal.TokenImpersonationLevel.Impersonation, networkCred);
您告诉它为当前用户获取 Kerberos 票证,该票证针对的是名为 SPN 的服务,而该名称恰好是当前用户的名称。
SPN 参数的要点是指定您想要票证的服务 的名称。 Kerberos 不会让您只获得一张可以在任何地方使用的票证。您必须申请特定服务的票。
SPN 采用 service/host.com@optional.realm.com
的形式。由于它是 REST 服务,因此很可能是 HTTP/your.service.com
。
请记住,SPN 必须注册到 Active Directory 中的服务主体,否则客户端将无法查找该服务。