为 ASP.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>
要解决权限问题(我的程序要运行一个exe文件),请使用下列方法之一:
- 为 ASPNET 帐户授予“作为操作系统的一部分”权限。将应用程序授予Internet来宾帐户执行访问权限.(IIS匿名访问的情况)
注意:我们不建议使用这种方法解决此问题。 - 在 Machine.config 文件的 <processModel> 配置节中,将运行 Aspnet_wp.exe 进程所使用的帐户更改为 System 帐户。
常见错误:
- 错误:
-
Could not create Windows user token from the credentials specified in the config file. Error from the operating system 'Logon failure: unknown user name or bad password.
- 分析:
- 有非常大的可能性是我们输入了错误的userName或password,这里要非常注意它们的大小写,与及userName最好要加上域(domain),例如msdomain1/rick
- 错误:
Could not create Windows user token from the credentials specified in the config file. Error from the operating system 'Logon failure: the user has not been granted the requested logon type at this computer.分析:这是因为在LogOnLocal用户组中不存在当前的impersonate用户.我们需要打开用户管理,再点击LogOnLocal用户组,在这里面加入web.config中配置的userName.
最后,总结一下. Internet Information Services (IIS)中的Integrated Windows authentication (NTLM)是针对网站或虚拟目录里的文件实现身份验证. 而ASP.NET中impersonate针对的是Web应用程序域,例如当程序执行到某一步需要访问到内部网中的某一个网络资源.