【发布时间】:2019-04-10 23:40:22
【问题描述】:
我有两个系统都运行我的 C# 客户端/服务器软件代码。我想从计算机 1 创建一个进程作为计算机 2 上的给定 Active Directory 域用户,而不必让我的客户端/服务器软件将 AD 用户的纯文本用户名和密码从计算机 1 发送到计算机 2。
我得到的最接近的是,我似乎可以在计算机 1 上使用函数 KerberosRequestorSecurityToken 来生成 kerberos 票证,然后通过我的客户端/服务器代码将该字节 [] 结果发送到计算机 2,然后它应该能够针对已传递的 byte[] kerberos 票证调用 KerberosReceiverSecurityToken。如果一切正常,那么 KerberosReceiverSecurityToken 将有一个 WindowsIdentity 属性,然后我可以使用该属性在计算机 2 上创建一个进程,并使用最初通过 KerberosRequestorSecurityToken 流在计算机 1 上指定的用户帐户。
我需要使用要模拟的现有域用户帐户,而不是注册服务帐户 SPN。这是我最初发布问题时未能提及的问题的症结所在。
我似乎无法让它工作,但更多,所以我什至不知道这是否真的可能 - 例如这些 API 甚至可以让我做我想做的事吗?
用于生成 kerberos 票证的计算机 1 代码。 byte[] 结果通过我的客户端/服务器应用程序发送到计算机 2。
public static byte[] GetRequestToken(string userName, string password, string domain)
{
using (var domainContext = new PrincipalContext(ContextType.Domain, domain))
{
using (var foundUser = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName))
{
Console.WriteLine("User Principal name" + UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName).UserPrincipalName);
string spn = UserPrincipal.FindByIdentity(domainContext, IdentityType.SamAccountName, userName).UserPrincipalName;
KerberosSecurityTokenProvider k1 = new KerberosSecurityTokenProvider(spn, TokenImpersonationLevel.Impersonation, new NetworkCredential(userName, password, domain));
KerberosRequestorSecurityToken T1 = k1.GetToken(TimeSpan.FromMinutes(1)) as KerberosRequestorSecurityToken;
var req = T1.GetRequest();
return req;
}
}
}
计算机 2 获取生成的 byte[] kerberos 票证并尝试接收它以访问 WindowsIdentity,但它引发了一个异常,提示登录无效。
KerberosReceiverSecurityToken receiverToken = new KerberosReceiverSecurityToken(requestToken);
byte[] receiverTokenTicket = receiverToken.GetRequest();
//Identity for impersonation
var impersonatedIdentity = receiverToken.WindowsIdentity;
【问题讨论】:
标签: c# kerberos windows-identity