現在オフラインです。再接続するためにインターネットの接続を待っています

ASP.NET アプリケーションに偽装を実装する方法

この記事は、以前は次の ID で公開されていました: JP306158
この資料では、次の Microsoft .NET Framework クラス ライブラリの名前空間を参照しています。
  • System.Web.Security
  • System.Security.Principal
  • System.Runtime.InteropServices
概要
この資料では、ASP.NET アプリケーションに偽装を実装するさまざまな方法について説明します。
詳細
ASP.NET のスレッドでユーザーを偽装する場合、必要に応じて、以下のいずれかの方法を使用できます。
: 次のコードを使用すると、スレッドを実行しているユーザーを判断できます。
System.Security.Principal.WindowsIdentity.GetCurrent().Name				

IIS が認証済みのアカウントまたはユーザーを偽装する

ASP.NET アプリケーションのすべてのページに対するすべての要求で Microsoft インターネット インフォメーション サービス (IIS) が認証したユーザーを偽装するには、このアプリケーションの Web.config ファイルに <identity> タグを含め、impersonate 属性を true に設定する必要があります。以下に例を示します。
<identity impersonate="true" />				
先頭に戻る

ASP.NET アプリケーションのすべての要求に対し、特定のユーザーを偽装する

ASP.NET アプリケーションのすべてのページで、すべての要求に対して特定のユーザーを偽装するには、そのアプリケーションの Web.config 内の <identity> タグに userName 属性と password 属性を指定できます。以下に例を示します。
<identity impersonate="true" userName="accountname" password="password" />				
: スレッドで特定のユーザーを偽装するプロセスの ID は、"オペレーティング システムの一部として機能する" 特権を持つ必要があります。デフォルトでは、Aspnet_wp.exe プロセスは ASPNET というコンピュータ アカウントで実行されます。しかし、このアカウントには、特定のユーザーを偽装するために必要な特権がありません。特定のユーザーを偽装しようとすると、エラー メッセージが表示されます。このことは .NET Framework 1.0 にのみ当てはまります。この特権は .NET Framework 1.1 では必要ありません。

この問題を回避するには、以下のいずれかの方法を使用します。
  • ASPNET アカウント (最小限の特権を持つアカウント) に "オペレーティング システムの一部として機能する" 特権を与えます。

    : この方法を使用しても問題を回避できますが、この方法を使用することはお勧めできません。
  • Aspnet_wp.exe プロセスを実行するアカウントを、Machine.config ファイルの <processModel> 構成セクションにある System アカウントに変更します。
先頭に戻る

コード内で認証中のユーザーを偽装する

コードの特定部分を実行するときのみ、認証中のユーザー (User.Identity) を偽装するために、以下のコードを使用できます。この方法を実行するには、認証中のユーザーの ID が WindowsIdentity 型である必要があります。

Visual Basic .NET
Dim impersonationContext As System.Security.Principal.WindowsImpersonationContextDim currentWindowsIdentity As System.Security.Principal.WindowsIdentitycurrentWindowsIdentity = CType(User.Identity, System.Security.Principal.WindowsIdentity)impersonationContext = currentWindowsIdentity.Impersonate()'Insert your code that runs under the security context of the authenticating user here.impersonationContext.Undo()				
Visual C# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;impersonationContext =     ((System.Security.Principal.WindowsIdentity)User.Identity).Impersonate();//Insert your code that runs under the security context of the authenticating user here.impersonationContext.Undo();				
Visual J# .NET
System.Security.Principal.WindowsImpersonationContext impersonationContext;impersonationContext =     ((System.Security.Principal.WindowsIdentity)get_User().get_Identity()).Impersonate();//Insert your code that runs under the security context of the authenticating user here.impersonationContext.Undo();				
先頭に戻る

コード内で特定のユーザーを偽装する

コードの特定部分を実行するときのみ、特定のユーザーを偽装するために、以下のコードを使用します。

Visual Basic .NET
<%@ Page Language="VB" %><%@ Import Namespace = "System.Web" %><%@ Import Namespace = "System.Web.Security" %><%@ Import Namespace = "System.Security.Principal" %><%@ Import Namespace = "System.Runtime.InteropServices" %><script runat=server>Dim LOGON32_LOGON_INTERACTIVE As Integer = 2Dim LOGON32_PROVIDER_DEFAULT As Integer = 0Dim impersonationContext As WindowsImpersonationContextDeclare Function LogonUserA 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 IntegerDeclare Auto Function DuplicateToken Lib "advapi32.dll" ( _                        ByVal ExistingTokenHandle As IntPtr, _                        ByVal ImpersonationLevel As Integer, _                        ByRef DuplicateTokenHandle As IntPtr) As IntegerDeclare Auto Function RevertToSelf Lib "advapi32.dll" () As LongDeclare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As LongPublic Sub Page_Load(ByVal s As Object, ByVal e As EventArgs)    If impersonateValidUser("username", "domain", "password") Then        'Insert your code that runs under the security context of a specific user here.        undoImpersonation()    Else        'Your impersonation failed. Therefore, include a fail-safe mechanism here.    End IfEnd SubPrivate Function impersonateValidUser(ByVal userName As String, _ByVal domain As String, ByVal password As String) As Boolean    Dim tempWindowsIdentity As WindowsIdentity    Dim token As IntPtr = IntPtr.Zero    Dim tokenDuplicate As IntPtr = IntPtr.Zero    impersonateValidUser = False    If RevertToSelf() Then        If LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,                      LOGON32_PROVIDER_DEFAULT, token) <> 0 Then            If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then                tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)                impersonationContext = tempWindowsIdentity.Impersonate()                If Not impersonationContext Is Nothing Then                    impersonateValidUser = True                End If            End If        End If    End If    If Not tokenDuplicate.Equals(IntPtr.Zero) Then        CloseHandle(tokenDuplicate)    End If    If Not token.Equals(IntPtr.Zero) Then        CloseHandle(token)    End IfEnd FunctionPrivate Sub undoImpersonation()    impersonationContext.Undo()End Sub</script>
Visual C# .NET
<%@ Page Language="C#"%><%@ Import Namespace = "System.Web" %><%@ Import Namespace = "System.Web.Security" %><%@ Import Namespace = "System.Security.Principal" %><%@ Import Namespace = "System.Runtime.InteropServices" %><script runat=server>public const int LOGON32_LOGON_INTERACTIVE = 2;public const int LOGON32_PROVIDER_DEFAULT = 0;WindowsImpersonationContext impersonationContext; [DllImport("advapi32.dll")]public static extern int LogonUserA(String lpszUserName, 	String lpszDomain,	String lpszPassword,	int dwLogonType, 	int dwLogonProvider,	ref IntPtr phToken);[DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]public static extern int DuplicateToken(IntPtr hToken, 	int impersonationLevel,  	ref IntPtr hNewToken);                          [DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true)]public static extern bool RevertToSelf();[DllImport("kernel32.dll", CharSet=CharSet.Auto)]public static extern  bool CloseHandle(IntPtr handle);public void Page_Load(Object s, EventArgs e){	if(impersonateValidUser("username", "domain", "password"))	{		//Insert your code that runs under the security context of a specific user here.		undoImpersonation();	}	else	{		//Your impersonation failed. Therefore, include a fail-safe mechanism here.	}}private bool impersonateValidUser(String userName, String domain, String password){	WindowsIdentity tempWindowsIdentity;	IntPtr token = IntPtr.Zero;	IntPtr tokenDuplicate = IntPtr.Zero;	if(RevertToSelf())	{		if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, 			LOGON32_PROVIDER_DEFAULT, ref token) != 0)		{			if(DuplicateToken(token, 2, ref tokenDuplicate) != 0) 			{				tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);				impersonationContext = tempWindowsIdentity.Impersonate();				if (impersonationContext != null)				{					CloseHandle(token);					CloseHandle(tokenDuplicate);					return true;				}			}		} 	}	if(token!= IntPtr.Zero)		CloseHandle(token);	if(tokenDuplicate!=IntPtr.Zero)		CloseHandle(tokenDuplicate);	return false;}private void undoImpersonation(){	impersonationContext.Undo();}</script>
Visual J# .NET
<%@ Page language="VJ#" %><%@ Import Namespace="System.Web" %><%@ Import Namespace="System.Web.Security" %><%@ Import Namespace="System.Security.Principal" %><%@ Import Namespace="System.Runtime.InteropServices" %><script runat=server>public static int LOGON32_LOGON_INTERACTIVE = 2;public static int LOGON32_PROVIDER_DEFAULT = 0;WindowsImpersonationContext impersonationContext; /** @attribute DllImport("advapi32.dll") */ public static native int LogonUserA(String lpszUserName, 	String lpszDomain, 	String lpszPassword,	int dwLogonType, 	int dwLogonProvider, 	System.IntPtr[] phToken);/** @attribute DllImport("advapi32.dll", CharSet=CharSet.Auto, SetLastError=true) */ public static native int DuplicateToken(System.IntPtr hToken,	int impersonationLevel,	System.IntPtr[] hNewToken);/** @attribute DllImport("kernel32.dll",CharSet=CharSet.Auto) */ public static native  boolean CloseHandle(System.IntPtr[] handle);/** @attribute DllImport("advapi32.dll", 	 CharSet=CharSet.Auto,SetLastError=true) */	 public static native boolean RevertToSelf();public void Page_Load(Object s, System.EventArgs e){	if(impersonateValidUser("username", "domain", " password"))	{		//Insert your code that runs under the security context of a specific user here.		undoImpersonation();	}	else	{		//Your impersonation failed. Therefore, include a fail-safe mechanism here.	}}private boolean impersonateValidUser(String userName, String domain, String password){	WindowsIdentity tempWindowsIdentity;	System.IntPtr[] token = new System.IntPtr[1];	System.IntPtr[] tokenDuplicate = new System.IntPtr[1];	if(RevertToSelf())	{		if(LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, 			LOGON32_PROVIDER_DEFAULT, token) != 0)		{			if(DuplicateToken(token[0], 2, tokenDuplicate) != 0) 			{				tempWindowsIdentity = new WindowsIdentity(tokenDuplicate[0]);				impersonationContext = tempWindowsIdentity.Impersonate();				if (impersonationContext != null)				{					CloseHandle(tokenDuplicate);					CloseHandle(token);					return true;				}							}					} 	}	if(!token[0].Equals(System.IntPtr.Zero))		CloseHandle(token);	if(!tokenDuplicate[0].Equals(System.IntPtr.Zero))		CloseHandle(tokenDuplicate);	return false;}private void undoImpersonation(){	impersonationContext.Undo();}</script>				
: スレッドで特定のユーザーを偽装するプロセスの ID は、"オペレーティング システムの一部として機能する" 特権を持つ必要があります。デフォルトでは、Aspnet_wp.exe プロセスは ASPNET というコンピュータ アカウントで実行されます。しかし、このアカウントには、特定のユーザーを偽装するために必要な特権がありません。特定のユーザーを偽装しようとすると、エラー メッセージが表示されます。このことは .NET Framework 1.0 にのみ当てはまります。この特権は .NET Framework 1.1 では必要ありません。

この問題を回避するには、以下のいずれかの方法を使用します。
  • ASPNET アカウントに "オペレーティング システムの一部として機能する" 特権を与えます。

    : 問題の回避策としてこの方法を使用することはお勧めできません。
  • Aspnet_wp.exe プロセスを実行するアカウントを、Machine.config ファイルの <processModel> 構成セクションにある System アカウントに変更します。
先頭に戻る
関連情報
ASP.NET セキュリティの関連情報を参照するには、以下の「サポート技術情報」 (Microsoft Knowledge Base) をクリックしてください。
306590 [INFO] ASP.NET のセキュリティについて
関連情報
この資料は米国 Microsoft Corporation から提供されている Knowledge Base の Article ID 306158 (最終更新日 2004-11-03) を基に作成したものです。

この資料に含まれているサンプル コード/プログラムは英語版を前提に書かれたものをありのままに記述しており、日本語環境での動作は確認されておりません。
login failed null (null) impersonate
プロパティ

文書番号:306158 - 最終更新日: 07/11/2005 05:14:51 - リビジョン: 4.7

  • Microsoft ASP.NET 1.0
  • Microsoft ASP.NET 1.1
  • Microsoft Visual Basic .NET 2002 Standard Edition
  • Microsoft Visual Basic .NET 2003 Standard Edition
  • Microsoft Visual C# .NET 2002 Standard Edition
  • Microsoft Visual C# .NET 2003 Standard Edition
  • Microsoft Visual J# .NET 2003 Standard Edition
  • kbinfo kbsecurity KB306158
フィードバック