Sytem.IntPtr
クライアントが偽装を使用してコードを呼び出すことができるように、サービス呼び出しからを返そうとしています。WCF サービスからトークンを返さない場合、私の偽装コードは正しく機能します。なぜこれが機能しないのかわかりません。次のエラーが表示されます。
「偽装の無効なトークン - 複製できません。」
これは、トークンをサービスから 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」を使用すると、サーバー プロセスはリモート システムでクライアントのセキュリティ コンテキストを偽装できます。
ありがとう!