缺省情况下,ASP.NET应用程序以本机的ASPNET帐号运行,该帐号属于普通用户组,权限受到一定的限制,以保ASP.NET应用程序运行的安全。但是有时需要某个ASP.NET应用程序或者程序中的某段代码执行需要特定权限的操作,比如某个文件的存取,这时就需要给该程序或相应的某段代码赋予某个帐号的权限以执行该操作,这种方法称之为身份模拟(Impersonation)。
如果要在 ASP.NET 中的线程上模拟用户,可以根据您的要求使用以下方法之一:
注意:可以使用以下代码来确定线程作为哪个用户执行:
System.Security.Principal.WindowsIdentity.GetCurrent().Name
模拟 IIS 验证的帐户或用户
若要在收到 ASP.NET 应用程序中每个页的每个请求时模拟 Microsoft Internet 信息服务 (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
"
/>
注意:在线程上模拟特定用户的进程的标识必须具有“作为操作系统的一部分”权限。默认情况下,Aspnet_wp.exe 进程在名为 ASPNET 的计算机帐户下运行。不过,此帐户没有模拟特定用户所需的权限。如果您尝试模拟特定用户,则会出现一条错误信息。此信息只适用于 .NET Framework 1.0。.NET Framework 1.1 不要求此权限。
要解决此问题,请使用下列方法之一:
a. 为 ASPNET 帐户(权限最低的帐户)授予“作为操作系统的一部分”权限。
注意:虽然此方法可以解决问题,但 Microsoft 不建议使用此方法。
b. 在 Machine.config 文件的 <processModel> 配置节中,将运行 Aspnet_wp.exe 进程所使用的帐户更改为 System 帐户。
在代码中模拟身份验证用户
若要仅在运行代码的特定部分时模拟身份验证用户 (
User.Identity),您可以使用以下代码。此方法要求身份验证用户标识的类型为
WindowsIdentity。
代码
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();
在代码中模拟特定用户
若要仅在运行代码的特定部分时模拟特定用户,请使用以下代码:
代码
<%
@ 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
>
注意:在线程上模拟特定用户的进程的标识必须具有“作为操作系统的一部分”权限。默认情况下,Aspnet_wp.exe 进程在名为 ASPNET 的计算机帐户下运行。不过,此帐户没有模拟特定用户所需的权限。如果您尝试模拟特定用户,则会出现一条错误信息。此信息只适用于 .NET Framework 1.0。.NET Framework 1.1 不要求此权限。
要解决此问题,请使用下列方法之一:
a. 为 ASPNET 帐户授予“作为操作系统的一部分”权限。
注意:我们不建议使用这种方法解决此问题。 b. 在 Machine.config 文件的 <processModel> 配置节中,将运行 Aspnet_wp.exe 进程所使用的帐户更改为 System 帐户。
b. 在 Machine.config 文件的 <processModel> 配置节中,将运行 Aspnet_wp.exe 进程所使用的帐户更改为 System 帐户。
MSDN资源:在ASP.NET应用程序中使用身份模拟(Impersonation)