C# 跨多个进程使用WindowsIdentity令牌

C# 跨多个进程使用WindowsIdentity令牌,c#,wcf,active-directory,asp.net-web-api2,windows-identity,C#,Wcf,Active Directory,Asp.net Web Api2,Windows Identity,我概述了以下体系结构: API网关(Web API),仅在内部网上可用,因此站点配置为使用Windows身份验证。此API允许用户与Dll(C++非托管)进行交互,并且由于Dll提供的函数尚未准备好进行多用户交互,还因为必须维护使用Dll时的状态,因此有一个windows服务负责调用Dll。因此,本质上,用户向网关发出请求,然后网关使用WCF(命名管道)调用windows服务中的方法。当处理给定用户的第一个请求时,WCF将创建一个AppDomain,从中运行Dll代码。现在,应用程序用户被映射到

我概述了以下体系结构:

API网关(Web API),仅在内部网上可用,因此站点配置为使用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));
  }
这是当服务中的代码运行时我得到的例外:

mscorlib.dll中发生“System.ArgumentException”类型的异常,但未在用户代码中处理

其他信息:模拟的令牌无效-无法复制

很明显,我在这里遗漏了一些东西,但我找不到它是什么。我的理解是,令牌是在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);
            }
        }
    }
}
使用系统;
使用System.Runtime.InteropServices;
使用System.Security.Principal;
使用System.ServiceModel;
命名空间控制台应用程序1
{
班级计划
{
[DllImport(“advapi32.dll”,SetLastError=true)]
公共静态外部bool LogonUser(字符串lpszUsername、字符串lpszDomain、字符串lpszPassword、int dwLogonType、int dwLogonProvider、out IntPtr phToken);
[DllImport(“advapi32.dll”,SetLastError=true)]
公共外部静态bool DuplicateToken(IntPtr ExistingTokenHandle、int安全性\模拟\级别、out IntPtr DuplicateTokenHandle);
公共枚举安全性模拟级别:int
{
SecurityAnonymous=0,
SecurityIdentification=1,
SecurityImpersonation=2,
SecurityDelegation=3,
}
静态void Main(字符串[]参数)
{
IntPtr令牌;
IntPtr令牌复制;
如果(登录用户(“xxxxx”、“xxxxx”、“xxxxx”、2、0、out令牌))
{
if(DuplicateToken(token,(int)SecurityImpersonationLevel.SecurityImpersonation,out tokenDuplicate))
{
//var channel=new ChannelFactory(new NetNamedPipeBinding(),
//新端点地址(“net。pipe://localhost/balance))创建通道();
//测试它,我们可以使用重复的令牌
var windowsnidentity=新的windowsnidentity(令牌复制);
//channel.CreateSession(Guid.Parse(“88fb01c7-41b5-4460-9ce5-fc72f9b0aa33”),令牌重复;
}
}
}
}
}

我可以使用重复的令牌创建WindowsIdentity的新实例,问题是当我使用WCF通过线路将此令牌发送到另一个进程时,仍然会收到重复的异常,这让我抓狂。我还需要做什么来确保复制的令牌可以在创建它的范围之外使用


谢谢

你看过这一页了吗


在没有看到此代理如何工作的情况下,我不确定,但我希望您需要在AD中配置您的应用程序池正在运行的任何上下文(服务帐户或机器帐户,如果是网络服务),以委托给WCF服务正在运行的上下文。这还需要在两个帐户上定义Kerberos SPN(如果它们还没有)

你看过这一页了吗


在没有看到此代理如何工作的情况下,我不确定,但我希望您需要在AD中配置您的应用程序池正在运行的任何上下文(服务帐户或机器帐户,如果是网络服务),以委托给WCF服务正在运行的上下文。这还需要在两个帐户上定义Kerberos SPN(如果它们还没有)

我可能错了,但我认为您需要复制令牌和/或在调用
CreateSession
之前模拟它。我会看看是否可以找到与复制令牌相关的内容,谢谢@Gread.and.power.OzI可能错了,但是我想你需要复制令牌和/或模拟它,然后再调用
CreateSession
我会看看是否能找到与复制令牌相关的内容,谢谢@Gread.and.power.oz谢谢你的输入Brian,但我能让他们选择不同的路径。谢谢你的输入Brian,但我让他们选择了另一条路。