我概述了以下架构:
API网关(Web API),仅通过Intranet可用,因此该站点配置为使用Windows身份验证。此API允许用户与Dll(C ++非托管)进行交互,并且因为Dll提供的功能尚未准备好进行多用户交互,并且因为必须维护使用Dll时的状态,所以还有一个Windows服务负责调用Dll。因此,实质上,用户向网关发出请求,然后网关使用WCF(命名管道)调用Windows服务中的方法。处理给定用户的第一个请求时,WCF会创建一个AppDomain,从哪里运行Dll代码。现在,应用程序用户被映射到具有设置的读/写权限的SQL Server数据库用户(...),因此,在创建AppDomain以运行Dll时,必须在发起请求的用户的上下文中完成。到目前为止,这是我想出来的,但遗憾的是它还没有工作。
我的网关中有以下代码:
[Route("sessions/{sessionId}")]
[HttpPut]
public HttpResponseMessage CreateBalanceSession (Guid sessionId)
{
return Request.CreateResponse(GatewayBalanceProvider.Proxy.CreateSession(sessionId, WindowsIdentity.GetCurrent().Token)
? HttpStatusCode.OK
: HttpStatusCode.NotAcceptable, "Balance session could not be created");
}
在Windows服务端,我得到了这个:
public bool CreateSession(Guid sessionId, IntPtr windowsUserToken)
{
var windowsPrincipal = new WindowsPrincipal(new WindowsIdentity(windowsUserToken));
}
这是我在服务中的代码运行时获得的异常:
类型' System.ArgumentException'的例外情况发生在mscorlib.dll中但未在用户代码中处理
其他信息:用于模拟的无效令牌 - 无法复制。
显然我在这里遗漏了一些东西,但我找不到它的样子。我的理解是,令牌是在IIS进程的上下文中创建的,并且由于此时的所有内容都是同步的,因此该令牌是否仍然有效?
欢迎任何帮助。
由于
更新1
根据评论我开始研究如何复制我完成的令牌,只是一个简单的Api32调用,并让它在同一个过程中完成:
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.ServiceModel;
namespace ConsoleApplication1
{
class Program
{
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
[DllImport("advapi32.dll", SetLastError = true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, out IntPtr DuplicateTokenHandle);
public enum SecurityImpersonationLevel : int
{
SecurityAnonymous = 0,
SecurityIdentification = 1,
SecurityImpersonation = 2,
SecurityDelegation = 3,
}
static void Main(string[] args)
{
IntPtr token;
IntPtr tokenDuplicate;
if (LogonUser("xxxxx", "xxxxx", "xxxxx", 2, 0, out token))
{
if (DuplicateToken(token, (int)SecurityImpersonationLevel.SecurityImpersonation, out tokenDuplicate))
{
//var channel = new ChannelFactory<IBalanceProvider>(new NetNamedPipeBinding(),
// new EndpointAddress("net.pipe://localhost/balance")).CreateChannel();
//Test it we can use the duplicated token
var windowsIdentity = new WindowsIdentity(tokenDuplicate);
//channel.CreateSession(Guid.Parse("88fb01c7-41b5-4460-9ce5-fc72f9b0aa33"), tokenDuplicate);
}
}
}
}
}
我可以使用复制的令牌创建一个新的WindowsIdentity实例,问题是当我使用WCF通过线路将该令牌发送到另一个进程时,我仍然得到重复的异常,这让我很生气。我还需要做些什么来确保复制的令牌可以在创建它的范围之外使用吗?
由于
答案 0 :(得分:0)
您是否查看了此页面? https://msdn.microsoft.com/en-us/library/ms730088(v=vs.110).aspx
在没有看到此代理如何工作的情况下,我不确定,但我希望您需要配置App池运行的任何上下文(服务帐户或网络服务中的计算机帐户)以委托给WCF服务运行的上下文。这还需要在两个帐户上定义Kerberos SPN,如果它们不存在的话。