我有两个系统都在运行C#客户端/服务器软件代码。我想从计算机1作为计算机2上的给定Active Directory域用户创建一个进程,而不必让我的客户端/服务器软件将AD用户的纯文本用户名和密码从计算机1发送到计算机2。
我得到的最接近的信息似乎是我可以在计算机1上使用函数KerberosRequestorSecurityToken来生成kerberos票证,然后通过我的客户机/服务器代码将该byte []结果发送到计算机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;
答案 0 :(得分:1)
第一段代码的来源在功能上是错误的。 SPN必须是接收票证的目标,而不是请求票证的用户。因此,您需要执行以下操作...
foo/host.domain.com
格式的帐户中,其中foo是您的服务名称,例如http
或host
或myapp
。foo/host.domain.com
的票证KerberosReceiverSecurityToken
应该解析那个票据现在,您具有不同的模拟级别身份。该模拟级别决定了您是否可以以该用户身份启动进程。碰巧的是……您不能,因为那不是Windows安全性的工作方式。因为您要模拟用户,所以您具有模拟NT令牌,而您需要一个主NT令牌才能启动进程。
因此,您需要使用DuplicateTokenEx将其转换为主要令牌,并且您实际上需要成为SYSTEM来这样做。
拥有主要令牌后,您就可以致电CreateProcessAsUser。
这时,您可能已经以用户身份启动了该过程,但是它没有任何凭据可访问其他网络属性,例如网络共享或Web服务。您可以在服务主体上启用约束委派,以便对此进行任何下游服务。
另一种选择,也许是更安全,更容易的选择,而是以低特权用户身份启动工作进程,并告知 该进程要模拟。参见this answer for more information。