WindowsIdentity.Impersonate メソッド
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
コードによって別の Windows ユーザーを偽装できるようにします。
オーバーロード
Impersonate() |
WindowsIdentity オブジェクトによって表されるユーザーを偽装します。 |
Impersonate(IntPtr) |
指定したユーザー トークンによって表されるユーザーを偽装します。 |
Impersonate()
WindowsIdentity オブジェクトによって表されるユーザーを偽装します。
public:
virtual System::Security::Principal::WindowsImpersonationContext ^ Impersonate();
public virtual System.Security.Principal.WindowsImpersonationContext Impersonate ();
abstract member Impersonate : unit -> System.Security.Principal.WindowsImpersonationContext
override this.Impersonate : unit -> System.Security.Principal.WindowsImpersonationContext
Public Overridable Function Impersonate () As WindowsImpersonationContext
戻り値
偽装前の Windows ユーザーを表すオブジェクト。このオブジェクトを使用して、元のユーザーのコンテキストに戻すことができます。
例外
偽装を実行しようとした匿名 ID。
Win32 エラーが発生しました。
例
次の例では、アンマネージド Win32 LogonUser
関数を呼び出して Windows アカウント トークンを取得する方法と、そのトークンを使用して別のユーザーを偽装し、元の ID に戻す方法を示します。
// This sample demonstrates the use of the WindowsIdentity class to impersonate a user.
// IMPORTANT NOTES:
// This sample requests the user to enter a password on the console screen.
// Because the console window does not support methods allowing the password to be masked,
// it will be visible to anyone viewing the screen.
// On Windows Vista and later this sample must be run as an administrator.
#using <System.dll>
using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Security::Principal;
using namespace System::Security::Permissions;
[DllImport("advapi32.dll",SetLastError=true)]
bool LogonUser( String^ lpszUsername, String^ lpszDomain, String^ lpszPassword, int dwLogonType, int dwLogonProvider, IntPtr * phToken );
[DllImport("kernel32.dll",CharSet=CharSet::Auto)]
bool CloseHandle( IntPtr handle );
// Test harness.
// If you incorporate this code into a DLL, be sure to demand FullTrust.
[PermissionSetAttribute(SecurityAction::Demand,Name="FullTrust")]
int main()
{
IntPtr tokenHandle = IntPtr(0);
try
{
String^ userName;
String^ domainName;
// Get the user token for the specified user, domain, and password using the
// unmanaged LogonUser method.
// The local machine name can be used for the domain name to impersonate a user on this machine.
Console::Write( "Enter the name of the domain on which to log on: " );
domainName = Console::ReadLine();
Console::Write( "Enter the login of a user on {0} that you wish to impersonate: ", domainName );
userName = Console::ReadLine();
Console::Write( "Enter the password for {0}: ", userName );
const int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
const int SecurityImpersonation = 2;
tokenHandle = IntPtr::Zero;
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser( userName, domainName, Console::ReadLine(), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &tokenHandle );
Console::WriteLine( "LogonUser called." );
if ( false == returnValue )
{
int ret = Marshal::GetLastWin32Error();
Console::WriteLine( "LogonUser failed with error code : {0}", ret );
throw gcnew System::ComponentModel::Win32Exception( ret );
}
Console::WriteLine( "Did LogonUser Succeed? {0}", (returnValue ? (String^)"Yes" : "No") );
Console::WriteLine( "Value of Windows NT token: {0}", tokenHandle );
// Check the identity.
Console::WriteLine( "Before impersonation: {0}", WindowsIdentity::GetCurrent()->Name );
// The token that is passed to the following constructor must
// be a primary token in order to use it for impersonation.
WindowsIdentity^ newId = gcnew WindowsIdentity( tokenHandle );
WindowsImpersonationContext^ impersonatedUser = newId->Impersonate();
// Check the identity.
Console::WriteLine( "After impersonation: {0}", WindowsIdentity::GetCurrent()->Name );
// Stop impersonating the user.
impersonatedUser->Undo();
// Check the identity.
Console::WriteLine( "After Undo: {0}", WindowsIdentity::GetCurrent()->Name );
// Free the tokens.
if ( tokenHandle != IntPtr::Zero )
CloseHandle( tokenHandle );
}
catch ( Exception^ ex )
{
Console::WriteLine( "Exception occurred. {0}", ex->Message );
}
}
// This sample demonstrates the use of the WindowsIdentity class to impersonate a user.
// IMPORTANT NOTES:
// This sample requests the user to enter a password on the console screen.
// Because the console window does not support methods allowing the password to be masked,
// it will be visible to anyone viewing the screen.
// On Windows Vista and later this sample must be run as an administrator.
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Security;
public class ImpersonationDemo
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
// Test harness.
// If you incorporate this code into a DLL, be sure to demand FullTrust.
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public static void Main(string[] args)
{
SafeTokenHandle safeTokenHandle;
try
{
string userName, domainName;
// Get the user token for the specified user, domain, and password using the
// unmanaged LogonUser method.
// The local machine name can be used for the domain name to impersonate a user on this machine.
Console.Write("Enter the name of the domain on which to log on: ");
domainName = Console.ReadLine();
Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName);
userName = Console.ReadLine();
Console.Write("Enter the password for {0}: ", userName);
const int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(userName, domainName, Console.ReadLine(),
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
out safeTokenHandle);
Console.WriteLine("LogonUser called.");
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
Console.WriteLine("LogonUser failed with error code : {0}", ret);
throw new System.ComponentModel.Win32Exception(ret);
}
using (safeTokenHandle)
{
Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
Console.WriteLine("Value of Windows NT token: " + safeTokenHandle);
// Check the identity.
Console.WriteLine("Before impersonation: "
+ WindowsIdentity.GetCurrent().Name);
// Use the token handle returned by LogonUser.
using (WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle()))
{
using (WindowsImpersonationContext impersonatedUser = newId.Impersonate())
{
// Check the identity.
Console.WriteLine("After impersonation: "
+ WindowsIdentity.GetCurrent().Name);
}
}
// Releasing the context object stops the impersonation
// Check the identity.
Console.WriteLine("After closing the context: " + WindowsIdentity.GetCurrent().Name);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception occurred. " + ex.Message);
}
}
}
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeTokenHandle()
: base(true)
{
}
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
' This sample demonstrates the use of the WindowsIdentity class to impersonate a user.
' IMPORTANT NOTES:
' This sample requests the user to enter a password on the console screen.
' Because the console window does not support methods allowing the password to be masked,
' it will be visible to anyone viewing the screen.
' On Windows Vista and later this sample must be run as an administrator.
Imports System.Runtime.InteropServices
Imports System.Security.Principal
Imports System.Security.Permissions
Imports Microsoft.Win32.SafeHandles
Imports System.Runtime.ConstrainedExecution
Imports System.Security
Module Module1
Public Class ImpersonationDemo
'Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
' ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
' ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
' ByRef phToken As IntPtr) As Boolean
Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
<Out()> ByRef phToken As SafeTokenHandle) As Boolean
Public Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Boolean
' Test harness.
' If you incorporate this code into a DLL, be sure to demand FullTrust.
<PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
Public Overloads Shared Sub Main(ByVal args() As String)
Dim safeTokenHandle As SafeTokenHandle = Nothing
Dim tokenHandle As New IntPtr(0)
Try
Dim userName, domainName As String
' Get the user token for the specified user, domain, and password using the
' unmanaged LogonUser method.
' The local machine name can be used for the domain name to impersonate a user on this machine.
Console.Write("Enter the name of a domain on which to log on: ")
domainName = Console.ReadLine()
Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName)
userName = Console.ReadLine()
Console.Write("Enter the password for {0}: ", userName)
Const LOGON32_PROVIDER_DEFAULT As Integer = 0
'This parameter causes LogonUser to create a primary token.
Const LOGON32_LOGON_INTERACTIVE As Integer = 2
' Call LogonUser to obtain a handle to an access token.
Dim returnValue As Boolean = LogonUser(userName, domainName, Console.ReadLine(), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, safeTokenHandle)
Console.WriteLine("LogonUser called.")
If False = returnValue Then
Dim ret As Integer = Marshal.GetLastWin32Error()
Console.WriteLine("LogonUser failed with error code : {0}", ret)
Throw New System.ComponentModel.Win32Exception(ret)
Return
End If
Using safeTokenHandle
Dim success As String
If returnValue Then success = "Yes" Else success = "No"
Console.WriteLine(("Did LogonUser succeed? " + success))
Console.WriteLine(("Value of Windows NT token: " + safeTokenHandle.DangerousGetHandle().ToString()))
' Check the identity.
Console.WriteLine(("Before impersonation: " + WindowsIdentity.GetCurrent().Name))
' Use the token handle returned by LogonUser.
Using newId As New WindowsIdentity(safeTokenHandle.DangerousGetHandle())
Using impersonatedUser As WindowsImpersonationContext = newId.Impersonate()
' Check the identity.
Console.WriteLine(("After impersonation: " + WindowsIdentity.GetCurrent().Name))
' Free the tokens.
End Using
End Using
End Using
Catch ex As Exception
Console.WriteLine(("Exception occurred. " + ex.Message))
End Try
End Sub
End Class
End Module
Public NotInheritable Class SafeTokenHandle
Inherits SafeHandleZeroOrMinusOneIsInvalid
Private Sub New()
MyBase.New(True)
End Sub
Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
ByRef phToken As IntPtr) As Boolean
<DllImport("kernel32.dll"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), SuppressUnmanagedCodeSecurity()> _
Private Shared Function CloseHandle(ByVal handle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Protected Overrides Function ReleaseHandle() As Boolean
Return CloseHandle(handle)
End Function 'ReleaseHandle
End Class
注釈
Windows NT プラットフォームでは、現在のユーザーは偽装を許可するための十分な権限を持っている必要があります。
警告
async/await パターンでは、このメソッドを使用しないでください。 場合によっては、結果 WindowsImpersonationContext
が破棄された場合でも、偽装が元に戻されないために信頼性の問題が発生する可能性があります。 代わりに、RunImpersonated
を使用してください。
注意 (呼び出し元)
を使用 Impersonate()した後、 メソッドを Undo() 呼び出して偽装を終了することが重要です。
適用対象
Impersonate(IntPtr)
指定したユーザー トークンによって表されるユーザーを偽装します。
public:
static System::Security::Principal::WindowsImpersonationContext ^ Impersonate(IntPtr userToken);
public static System.Security.Principal.WindowsImpersonationContext Impersonate (IntPtr userToken);
static member Impersonate : nativeint -> System.Security.Principal.WindowsImpersonationContext
Public Shared Function Impersonate (userToken As IntPtr) As WindowsImpersonationContext
パラメーター
- userToken
-
IntPtr
nativeint
Windows アカウント トークンのハンドル。 通常、このトークンは、Windows API の LogonUser
関数の呼び出しなど、アンマネージド コードの呼び出しによって取得します。
戻り値
偽装前の Windows ユーザーを表すオブジェクト。このオブジェクトを使用して、元のユーザーのコンテキストに戻すことができます。
例外
Windows は、Windows NT ステータス コード STATUS_ACCESS_DENIED を返しました。
使用できるメモリが不足しています。
呼び出し元に、正しいアクセス許可がありません。
例
次の例では、アンマネージド Win32 LogonUser
関数を呼び出して Windows アカウント トークンを取得する方法と、そのトークンを使用して別のユーザーを偽装し、元の ID に戻す方法を示します。
// This sample demonstrates the use of the WindowsIdentity class to impersonate a user.
// IMPORTANT NOTES:
// This sample requests the user to enter a password on the console screen.
// Because the console window does not support methods allowing the password to be masked,
// it will be visible to anyone viewing the screen.
// On Windows Vista and later this sample must be run as an administrator.
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Security;
public class ImpersonationDemo
{
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
// Test harness.
// If you incorporate this code into a DLL, be sure to demand FullTrust.
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public static void Main(string[] args)
{
SafeTokenHandle safeTokenHandle;
try
{
string userName, domainName;
// Get the user token for the specified user, domain, and password using the
// unmanaged LogonUser method.
// The local machine name can be used for the domain name to impersonate a user on this machine.
Console.Write("Enter the name of the domain on which to log on: ");
domainName = Console.ReadLine();
Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName);
userName = Console.ReadLine();
Console.Write("Enter the password for {0}: ", userName);
const int LOGON32_PROVIDER_DEFAULT = 0;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(userName, domainName, Console.ReadLine(),
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
out safeTokenHandle);
Console.WriteLine("LogonUser called.");
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
Console.WriteLine("LogonUser failed with error code : {0}", ret);
throw new System.ComponentModel.Win32Exception(ret);
}
using (safeTokenHandle)
{
Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
Console.WriteLine("Value of Windows NT token: " + safeTokenHandle);
// Check the identity.
Console.WriteLine("Before impersonation: "
+ WindowsIdentity.GetCurrent().Name);
// Use the token handle returned by LogonUser.
using (WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle()))
{
// Check the identity.
Console.WriteLine("After impersonation: "
+ WindowsIdentity.GetCurrent().Name);
}
// Releasing the context object stops the impersonation
// Check the identity.
Console.WriteLine("After closing the context: " + WindowsIdentity.GetCurrent().Name);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception occurred. " + ex.Message);
}
}
}
public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeTokenHandle()
: base(true)
{
}
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
' This sample demonstrates the use of the WindowsIdentity class to impersonate a user.
' IMPORTANT NOTES:
' This sample requests the user to enter a password on the console screen.
' Because the console window does not support methods allowing the password to be masked,
' it will be visible to anyone viewing the screen.
' On Windows Vista and later this sample must be run as an administrator.
Imports System.Runtime.InteropServices
Imports System.Security.Principal
Imports System.Security.Permissions
Imports Microsoft.Win32.SafeHandles
Imports System.Runtime.ConstrainedExecution
Imports System.Security
Module Module1
Public Class ImpersonationDemo
'Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
' ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
' ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
' ByRef phToken As IntPtr) As Boolean
Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
<Out()> ByRef phToken As SafeTokenHandle) As Boolean
Public Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Boolean
' Test harness.
' If you incorporate this code into a DLL, be sure to demand FullTrust.
<PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
Public Overloads Shared Sub Main(ByVal args() As String)
Dim safeTokenHandle As SafeTokenHandle
Dim tokenHandle As New IntPtr(0)
Try
Dim userName, domainName As String
' Get the user token for the specified user, domain, and password using the
' unmanaged LogonUser method.
' The local machine name can be used for the domain name to impersonate a user on this machine.
Console.Write("Enter the name of a domain on which to log on: ")
domainName = Console.ReadLine()
Console.Write("Enter the login of a user on {0} that you wish to impersonate: ", domainName)
userName = Console.ReadLine()
Console.Write("Enter the password for {0}: ", userName)
Const LOGON32_PROVIDER_DEFAULT As Integer = 0
'This parameter causes LogonUser to create a primary token.
Const LOGON32_LOGON_INTERACTIVE As Integer = 2
' Call LogonUser to obtain a handle to an access token.
Dim returnValue As Boolean = LogonUser(userName, domainName, Console.ReadLine(), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, safeTokenHandle)
Console.WriteLine("LogonUser called.")
If False = returnValue Then
Dim ret As Integer = Marshal.GetLastWin32Error()
Console.WriteLine("LogonUser failed with error code : {0}", ret)
Throw New System.ComponentModel.Win32Exception(ret)
Return
End If
Using safeTokenHandle
Dim success As String
If returnValue Then success = "Yes" Else success = "No"
Console.WriteLine(("Did LogonUser succeed? " + success))
Console.WriteLine(("Value of Windows NT token: " + safeTokenHandle.DangerousGetHandle().ToString()))
' Check the identity.
Console.WriteLine(("Before impersonation: " + WindowsIdentity.GetCurrent().Name))
' Use the token handle returned by LogonUser.
Using impersonatedUser As WindowsImpersonationContext = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle())
' Check the identity.
Console.WriteLine(("After impersonation: " + WindowsIdentity.GetCurrent().Name))
' Free the tokens.
End Using
End Using
Catch ex As Exception
Console.WriteLine(("Exception occurred. " + ex.Message))
End Try
End Sub
End Class
End Module
Public NotInheritable Class SafeTokenHandle
Inherits SafeHandleZeroOrMinusOneIsInvalid
Private Sub New()
MyBase.New(True)
End Sub
Private Declare Auto Function LogonUser Lib "advapi32.dll" (ByVal lpszUsername As [String], _
ByVal lpszDomain As [String], ByVal lpszPassword As [String], _
ByVal dwLogonType As Integer, ByVal dwLogonProvider As Integer, _
ByRef phToken As IntPtr) As Boolean
<DllImport("kernel32.dll"), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), SuppressUnmanagedCodeSecurity()> _
Private Shared Function CloseHandle(ByVal handle As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Protected Overrides Function ReleaseHandle() As Boolean
Return CloseHandle(handle)
End Function 'ReleaseHandle
End Class
注釈
Windows NT プラットフォームでは、現在のユーザーは偽装を許可するための十分な権限を持っている必要があります。
注意
値 が のImpersonate(IntPtr)ZeroメソッドのuserToken
呼び出しは、Win32 RevertToSelf
関数の呼び出しと同じです。 別のユーザーが現在偽装されている場合、コントロールは元のユーザーに戻ります。
アンマネージド コードの呼び出しの詳細については、「 アンマネージ DLL 関数の使用」を参照してください。
警告
async/await パターンでは、このメソッドを使用しないでください。 場合によっては、結果 WindowsImpersonationContext
が破棄された場合でも、偽装が元に戻されないために信頼性の問題が発生する可能性があります。 代わりに、RunImpersonated
を使用してください。
注意 (呼び出し元)
を使用 Impersonate(IntPtr)した後、 メソッドを Undo() 呼び出して偽装を終了することが重要です。
適用対象
.NET