C# 调用模拟令牌的DuplicateTokenEx后仍获取重复令牌错误

C# 调用模拟令牌的DuplicateTokenEx后仍获取重复令牌错误,c#,impersonation,C#,Impersonation,我试图从服务调用返回一个Sytem.IntPtr,以便客户端可以使用模拟来调用一些代码。如果不从WCF服务传回令牌,我的imersonation代码将正常工作。我不知道这为什么不起作用。我得到以下错误: “模拟的令牌无效-无法复制。” 下面是我的代码,除了我尝试将令牌从服务传递回WinForm C#客户机,然后进行模拟时,它确实可以工作 [DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")] public extern stati

我试图从服务调用返回一个
Sytem.IntPtr
,以便客户端可以使用模拟来调用一些代码。如果不从WCF服务传回令牌,我的imersonation代码将正常工作。我不知道这为什么不起作用。我得到以下错误:

“模拟的令牌无效-无法复制。”

下面是我的代码,除了我尝试将令牌从服务传递回WinForm C#客户机,然后进行模拟时,它确实可以工作

[DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")]
public extern static bool DuplicateTokenEx(IntPtr ExistingTokenHandle, uint dwDesiredAccess, ref SECURITY_ATTRIBUTES lpThreadAttributes, int TokenType, int ImpersonationLevel, ref IntPtr DuplicateTokenHandle);

private IntPtr tokenHandle = new IntPtr(0);
private IntPtr dupeTokenHandle = new IntPtr(0);

[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
    public int Length;
    public IntPtr lpSecurityDescriptor;
    public bool bInheritHandle;
}



public enum SecurityImpersonationLevel
{
    SecurityAnonymous = 0,
    SecurityIdentification = 1,
    SecurityImpersonation = 2,
    SecurityDelegation = 3
}

public enum TokenType
{
    TokenPrimary = 1,
    TokenImpersonation = 2
}

private const int MAXIMUM_ALLOWED = 0x2000000;


[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public System.IntPtr GetWindowsUserToken(string UserName, string Password, string DomainName)
{

    IntPtr tokenHandle = new IntPtr(0);
    IntPtr dupTokenHandle = new IntPtr(0);

    const int LOGON32_PROVIDER_DEFAULT = 0;
    //This parameter causes LogonUser to create a primary token.
    const int LOGON32_LOGON_INTERACTIVE = 2;

    //Initialize the token handle            
    tokenHandle = IntPtr.Zero;

    //Call LogonUser to obtain a handle to an access token for credentials supplied.
    bool returnValue = LogonUser(UserName, DomainName, Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref tokenHandle);        

    //Make sure a token was returned; if no populate the ResultCode and throw an exception:
    int ResultCode = 0;
    if (false == returnValue)
    {
        ResultCode = Marshal.GetLastWin32Error();
        throw new System.ComponentModel.Win32Exception(ResultCode, "API call to LogonUser failed with error code : " + ResultCode);
    }

    SECURITY_ATTRIBUTES sa = new SECURITY_ATTRIBUTES();
    sa.bInheritHandle = true;
    sa.Length = Marshal.SizeOf(sa);
    sa.lpSecurityDescriptor = (IntPtr)0;


    bool dupReturnValue = DuplicateTokenEx(tokenHandle, MAXIMUM_ALLOWED, ref sa, (int)SecurityImpersonationLevel.SecurityDelegation, (int)TokenType.TokenImpersonation, ref dupTokenHandle);

    int ResultCodeDup = 0;
    if (false == dupReturnValue)
    {
        ResultCodeDup = Marshal.GetLastWin32Error();
        throw new System.ComponentModel.Win32Exception(ResultCode, "API call to DuplicateToken failed with error code : " + ResultCode);
    }

    //Return the user token
    return dupTokenHandle;

}
知道我是否正确使用了对
DuplicateTokenEx
的调用吗?根据我阅读的MSDN文档,我应该能够创建一个有效的令牌,以便在远程系统上跨上下文进行授权和使用。使用“SecurityDelegation”时,服务器进程可以在远程系统上模拟客户端的安全上下文


谢谢

您正在使用TokenAccessLevel.MaximumAllowed值,就好像它是允许的最大权限一样,这意味着:就好像它会给您所有权限一样

……但事实并非如此

TokanAccesslevels.MaximumAllowed的值为0x020000000,这是枚举在任何时候都可以增长到的最大值,供将来实现时参考

有关枚举的实际实现,请参见

要使代码正常工作,需要通过逐位操作逐个设置所需的访问级别

如果您将允许的最大_替换为

(uint)(TokenAccessLevels.Query | TokenAccessLevels.Duplicate | TokenAccessLevels.Impersonate)
在PInvoke中调用DuplicateTokenEx函数


我知道你不再有这个问题了,但这可以帮助其他人,毕竟,你可能会再次遇到同样的问题……;)

你能做到吗?不,我甚至没有反映这个场景的代码了。无论如何,谢谢康威。