- ASP.NET中的身份模拟
- 模拟IIS认证帐号
- 在某个ASP.NET应用程序中模拟指定的用户帐号
- 在代码中模拟IIS认证帐号
- 在代码中模拟指定的用户帐号
- 更多信息
- 模拟IIS认证帐号
- 在某个ASP.NET应用程序中模拟指定的用户帐号
- 在代码中模拟IIS认证帐号
- 在代码中模拟指定的用户帐号
<identity impersonate="true" />
<identity impersonate="true" userName="accountname" password="password" />
Dim impersonationContext As System.Security.Principal.WindowsImpersonationContext Dim currentWindowsIdentity As System.Security.Principal.WindowsIdentity currentWindowsIdentity = 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()
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="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 = 2 Dim LOGON32_PROVIDER_DEFAULT As Integer = 0 Dim impersonationContext As WindowsImpersonationContext 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 Integer Declare Auto Function DuplicateToken Lib "advapi32.dll"(ByVal ExistingTokenHandle As IntPtr, _ ImpersonationLevel As Integer, _ ByRef DuplicateTokenHandle As IntPtr) As Integer Public Sub Page_Load(s As Object, 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 If End Sub Private Function impersonateValidUser(userName As String, _ domain As String, password As String) As Boolean Dim tempWindowsIdentity As WindowsIdentity Dim token As IntPtr Dim tokenDuplicate As IntPtr If LogonUser(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 impersonationContext Is Nothing Then impersonateValidUser = False Else impersonateValidUser = True End If Else impersonateValidUser = False End If Else impersonateValidUser = False End If End Function Private Sub undoImpersonation() impersonationContext.Undo() End Sub </script>
<%@ 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", CharSet=CharSet.Auto)] public static extern int LogonUser(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken); [DllImport("advapi32.dll", CharSet=System.Runtime.InteropServices.CharSet.Auto, SetLastError=true)] public extern static int DuplicateToken(IntPtr hToken, int impersonationLevel, ref IntPtr hNewToken); 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(LogonUser(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) return true; else return false; } else return false; } else return false; } private void undoImpersonation() { impersonationContext.Undo(); } </script>
bool a = File.Exists("D://Share//test.txt");
<identity impersonate="true" userName="FileExist" password="password" />
使用模拟时,ASP.NET 应用程序可以选择以这些应用程序当前正为之操作的客户的身份执行。通常这样做的原因是为了避免在 ASP.NET 应用程序代码中处理身份验证和授权问题。而您依赖于 Microsoft Internet 信息服务 (IIS) 来验证用户,然后将已通过验证的标记传递给 ASP.NET 应用程序;或者,如果无法验证用户,则传递未经身份验证的标记。不论何种情况,如果启用了“模拟”,则 ASP.NET 应用程序会模拟所收到的任何标记。当前模拟客户的 ASP.NET 应用程序依赖于 NTFS 目录和文件中的设置来允许客户获得访问权限或拒绝其访问。务必将服务器文件空间格式化为 NTFS,以便可以设置访问权限。
默认情况下禁用模拟。为了 ASP 的兼容性,用户必须显式启用模拟。如果为给定的应用程序启用模拟,则 ASP.NET 总是模拟 IIS 提供给 ISAPI 扩展的访问标记。该标记既可以是已验证用户标记,也可以是匿名用户的标记(如 IUSR_MACHINENAME)。不论应用程序中使用哪种身份验证类型,模拟都会发生。
只能模拟应用程序代码,编译和配置作为进程标记读取。编译的结果放在“Temporary ASP.NET files”目录中。所模拟的帐户需要对该目录的读/写访问权。如果应用程序位于通用命名规则 (UNC) 共享上,除非使用配置帐户,否则,ASP.NET 将总是模拟提供给 IIS 的标记来访问该共享。如果提供了显式配置的帐户,ASP.NET 将使用该帐户取代 IIS UNC 标记。确实需要基于每个请求的模拟的应用程序可以直接配置为模拟提交请求的用户。
默认情况下,在计算机级别上禁用模拟。而且除非被重写,否则所有的应用程序域都继承此设置。可以通过将配置文件放置在应用程序根目录下来启用模拟。有关 ASP.NET 配置系统的更多信息,请参见 ASP.NET 配置。
与其他配置指令的情况相同,此指令分层应用。除非被显式重写,否则,层次结构中的嵌套程序将遵从它。此设置的默认值如下所示。
<impersonation enable="false"/>
为应用程序启用模拟的最小配置文件可能看上去和下面的示例类似。
<!-- Web.config file. -->
<identity impersonate="true"/>
还有以可配置身份运行应用程序的名称支持。例如:
<identity impersonate="true" userName="contoso/Jane" password="pass"/>
这将允许整个应用程序以 contoso/Jane 运行,不论请求的身份如何,只要密码正确即可。可以将这种类型的模拟委托给另一台计算机。
您可以以编程的方式读取被模拟用户的标识,如下例所示。
[Visual Basic]
Dim username As String = System.Security.Principal.WindowsIdentity.GetCurrent().Name
[C#]
String username = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
在上例中,userName 和 password 以明文形式存储在配置文件中。虽然 IIS 不传输 .config 文件来响应用户代理请求,但是可以通过其他途径读取配置文件,例如通过在包含服务器的域上具有适当凭据的已经过身份验证的用户。为了增强安全性,标识部分支持在注册表中存储加密的 userName 和 password 属性,如下例所示。
userName="registry:HKLM/Software/AspNetIdentity,Name"
password="registry:HKLM/Software/AspNetIdentity,Password"
字符串中位于关键字 registry 之后和逗号之前的部分表示 ASP.NET 打开的注册表项的名称。逗号之后的部分包含一个字符串值的名称,ASP.NET 从此名称中读取凭据。必须有逗号,并且凭据必须存储在 HKLM 配置单元中。如果配置格式不正确,则 ASP.NET 不会启动辅助进程,然后将显示造成当前帐户创建失败的代码路径。
凭据必须为 REG_BINARY 格式,并且包含 Windows API 函数 CryptProtectData 调用的输出。可以用 ASP.NET 设置注册表控制台应用程序 (Aspnet_setreg.exe) 来创建加密凭据并将它们存储在注册表中。该应用程序使用 CryptProtectData 完成加密。若要同 Visual C++ 源代码和文档一起下载 Aspnet_setreg.exe,请访问 Web 站点 www.asp.net 并搜索“aspnet_setreg”。
应该对存储加密凭据的密钥的访问权限进行配置,仅向 Administrators 和 SYSTEM 提供访问权。由于密钥会被作为 SYSTEM 运行的 ASP.NET 进程读取,因此应设置以下权限:
Administrators:F
SYSTEM:F
CREATOR OWNER:F
ProcessAccount:R
这可以提供两道保护数据的防线:
ACL 权限要求访问数据的身份是 Administrator。
攻击者必须在服务器上运行代码 (CryptUnprotectData) 才能恢复帐户的凭据。