如何使用SSPI从Kerberos获取服务令牌

时间:2016-06-14 17:15:24

标签: c# .net single-sign-on kerberos sspi

目的: 我正在尝试使用SSPI构建Proof Of Concept客户端应用程序以实现单点登录。我是C#的新手,我很困惑。

到目前为止我所知道并做了什么: 所有用户都是Active Directory域的一部分,因此我知道Kerberos在登录期间用于身份验证。此时我需要做的就是从Kerberos获取服务令牌,这样我就可以将它传递给服务资源而不是用户名和密码(如果我错了,请纠正我)。我已经获得了服务原则名称(SPN)和已在Kerberos中注册的服务密码。

我希望不使用平台调用服务来调用SSPI函数,但如果必须的话,我会这样做。我通读了“.NET Remoting身份验证和授权示例 - 第一部分”并使用Microsoft.Samples.Security.SSPI进行测试。我也尝试使用C#/.Net Interface To The Win32 SSPI Authentication API

到目前为止,我可以获取用户/客户端凭据,构建客户端安全上下文。但是,如何为给定的SPN请求服务票证?

感谢您的帮助和指导。如果您有任何疑问,请具体说明。

2 个答案:

答案 0 :(得分:3)

您可以使用以下内容通过提供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;
            }
        }

    }

答案 1 :(得分:2)

Hasanthi提供的代码完全符合我的需要,我没有必要使用SSPI。我问的是错误的问题,但我学到了很多关于Kerberos和SSPI的知识。简而言之,这是我的代码:

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());
}