在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
How To: Use Impersonation and Delegation in ASP.NET 2.0
patterns & practices Developer Center J.D. Meier, Alex Mackman, Blaine Wastell, Prashant Bansode, Andy Wigley, Kishore Gopalan Microsoft Corporation August 2005 Applies To
SummaryThis How To shows you how and when you should use impersonation in ASP.NET 2.0 applications. By default, impersonation is turned off, and you can access resources by using the ASP.NET Web application's process identity. However, you can use impersonation to access local resources and perform operations by using the authenticated user's identity or by using a specific Windows identity. You can enable impersonation programmatically or by applying appropriate configuration settings in the Web.config file. Delegation allows you to use an impersonation token to access network resources. Your ability to use delegation depends on your selected authentication mechanism and appropriate account configuration. You should be careful when you use impersonation and delegation because of the additional security and scalability issues it can cause. ContentsObjectives Objectives
OverviewBy default, ASP.NET does not use impersonation, and your code runs using the ASP.NET application's process identity. On the Microsoft® Windows Server™ 2003 operating system, ASP.NET applications run in an Internet Information Services (IIS) 6.0 application pool by default. The IIS application pool runs under the NT AUTHORITY\Network Service identity. On the Microsoft Windows® 2000 Server operating system with IIS 5.0 or on Windows Server 2003 with IIS 6.0 configured for IIS 5.0 isolation mode, ASP.NET applications run in a worker process that uses the local ASPNET account identity. Because impersonation is disabled, the application gains access to all resources by using the process identity. Any Windows resources, such as files and registry keys, must have an access control list (ACL) that grants access to the process identity. If you need to access resources by using the authenticated caller's identity or by using a specific Windows identity other than the process identity, you can configure your ASP.NET application to use impersonation. If you need to impersonate at the method level to perform specific operations or access particular resources, then you can use programmatic impersonation by using the WindowsIdentity.Impersonate method. LogonUser vs. WindowsIdentidy(userPrincipalName)If your application authenticates callers by using custom authentication, such as forms authentication, then you cannot impersonate the original caller through ASP.NET configuration. Instead you must call the Impersonate method of a WindowsIdentity object that you create for the original caller. You can obtain an impersonation token for the original caller, provided that the caller has a Windows account, by calling the Win32 LogonUser API (on Windows 2000 Server or Windows Server 2003) or by using a special form of the WindowsIdentity constructor that takes a single parameter of a user principal name (UPN). The technique you should use depends on the following:
What's New in 2.0In ASP.NET 2.0 applications, you can now change the default behavior to flow the impersonation token to newly created threads, when you create the thread with any of the managed threading techniques (such as Thread.Start, an asynchronous delegate, or QueueUserWorkItem). With .NET Framework 1.1, you have to manually propagate impersonation tokens to new threads you create. The impersonation token does not propagate across threads if you use COM interop with components that have incompatible threading models, or if you use unmanaged techniques to create new threads (for example, when you use the Win32 CreateThread API). In these situations, the behavior is the same as in .NET Framework 1.1. For more information, see, PRB: 'Access Denied' Error Message Occurs When You Impersonate an Account in ASP.NET and then Call STA COM Components. Impersonation ScenariosThe most common situations where you might require impersonation and delegation are:
This How To shows you when and how to use each approach on Windows Server 2003 and on Windows 2000 Server. Impersonating the Original CallerIf you need to access local resources, such as the file system or a local database, while assuming the identity of the original caller (the authenticated user), you need to use an appropriate IIS authentication type. Ideally, you should use IIS to configure your application's virtual directory for integrated Windows authentication, and then configure your ASP.NET application for Windows authentication and impersonation. This approach is shown in Figure 1. Figure 1. Impersonating the original caller This configuration is generally required if you need to control access to Windows resources with ACLs set against the individual user of your application. To impersonate the original caller, you need to use IIS to configure appropriate authentication for your application's virtual directory and use appropriate configuration in the Web.config file. To impersonate the original caller
With this configuration, ASP.NET impersonates the IIS authenticated user, and the ASP.NET request threads that execute your Web application's code have the impersonation token attached to them. IIS passes a Windows token for the authenticated user to ASP.NET. The token can represent the authenticated user, if IIS is configured for Integrated Windows authentication, or another form of authentication such as basic, digest, or client certificate authentication. The token represents the anonymous user identity (IUSR_MACHINENAME) if IIS is configured to enable anonymous access. While the above configuration ensures that all resource access is performed using the identity of the original caller, if you need to access specific resources such as local files by using the process identity, you can temporarily remove the impersonation token from the ASP.NET request thread by using the following code: // Stop impersonation WindowsImpersonationContext ctx = WindowsIdentity.Impersonate(IntPtr.Zero); try { // Thread is now running under the process identity. // Any resource access here uses the process identity. } finally { // Resume impersonation ctx.Undo(); } Impersonating the Original Caller TemporarilyIf you need to use the process identity for most resource access, and then impersonate the original caller to perform specific operations or to access specific resources, you need to use programmatic impersonation. (See Figure 2.) Figure 2. Using programmatic impersonation to temporarily impersonate the original caller. To temporarily impersonate the original caller within a particular method, you need to obtain the WindowsIdentity object that represents the authenticated user, and then call its Impersonate method. To temporarily impersonate the original caller
Exception HandlingNotice how the preceding code uses a finally block to ensure that impersonation is reverted even in the event of an exception. The code also uses a catch block to ensure that an exception cannot propagate itself up the call stack while the thread is impersonating. Impersonating by Using LogonUserIf your users have Windows domain accounts, but you are using custom authentication, such as forms authentication, IIS does not authenticate the caller and it passes a logon token that represents the anonymous user account to ASP.NET. To impersonate the caller in this instance, you must programmatically create a WindowsIdentity object for the caller, which you can use to impersonate. Create a WindowsIdentity object either by using a logon token returned from the Win32 LogonUser API, or by using the WindowsIdentity(userPrincipalName) constructor that takes a single parameter of a user principal name (UPN). The underlying extensions for the Kerberos protocol required by this constructor are only available on Windows Server 2003. For more information, see the section Impersonating by Using the WindowsIdentity Constructor in this document. You can create a Windows token and associated logon session for a domain or local account by using the Win32 LogonUser API. You must pass the user name and password to this API, together with other parameters including the type of logon session you require. Note You should protect the credentials passed to LogonUser by encrypting them. You can impersonate with the returned token and check which Windows groups the user is a member of. Whether you can access local resources or network resources depends on the logon session type that you request (you specify the logon session type in the third argument of LogonUser). The most commonly used logon session types when calling this API are the following:
To check whether you have the Access this computer from the network user right
Note The name of the network logon session type sometimes causes confusion. It is called a network logon because it is equivalent to a user accessing the local computer from somewhere else on the network. The resulting logon session does not have network credentials, and therefore cannot be used to access network resources. When you request an interactive logon, LogonUser returns a primary token that allows you to create processes while impersonating. When you request a network logon, LogonUser returns an impersonation token that can be used to access local resources, but not to create processes. If required, you can convert an impersonation token to a primary token by calling the Win32 DuplicateToken function. The following example shows how to use the Win32 LogonUser API, construct a WindowsIdentity object from the token, attach the token to the current thread to begin impersonation, and then cancel the impersonation. The preceding example passes LogonSessionType.Network to LogonUser. This results in a network logon session which has no network credentials. If you need a token and logon session that you can use to access network resources use LogonSessionType.Interactive. For more information, see Delegation in this document. For clarity, the code example shown above uses literal strings to specify the credentials passed to LogonUser. If you use LogonUser, you should store the credentials that you pass to the method in encrypted format in your Web.config file. Store credentials in the <appSettings> section as shown in the following example, and then use the Aspnet_regiis.exe utility and a protected configuration provider to encrypt this section. <appSettings> <add key="ImpIdentity" value="Domainname\Username;secretpassword"/> </appSettings> The following example shows how to access this configuration data to pass to LogonUser. string domain; string username; string password; // Access the <appSettings> value string[] userAndPassword = ((string)ConfigurationManager.AppSettings["ImpIdentity"]).Split(';'); // Parse out the domain, username and password domain = userAndPassword[0].Substring(0, userAndPassword[0].IndexOf(@"\")); userName = userAndPassword[0].Substring(userAndPassword[0].IndexOf(@"\")+1); password = userAndPassword[1]; // Call LogonUser bool result = LogonUser(userName, domain, password, LogonSessionTypes.Network, LogonProviders.Default, out token); For more information about encrypting the configuration file sections, see:
Using LogonUser on Windows Server 2003When you use the LogonUser API for impersonation on Windows Server 2003, you do not need to grant your application's process identity the Act as part of the operating system user right. On Windows Server 2003, instead of using LogonUser, you can generate a token by using the WindowsIdentity constructor. The advantage of this approach is that you do not have to store credentials on your Web server. The downside is that to get an impersonate-level token to use to access local resources, your process identity requires the Act as part of the operating system user right. For more information, see the section, Impersonating by Using the WindowsIdentity Constructor in this document. Using LogonUser on Windows 2000 ServerWhen you use the LogonUser API for impersonation on Windows 2000 Server, you must grant the application's process account the Act as part of the operating system privilege. You should avoid this approach if possible to avoid raising the privileges of your Web application. Impersonating by Using the WindowsIdentity ConstructorOne of the overloads for the constructor on the WindowsIdentity class permits you to obtain a Windows token and logon session for a given domain account by supplying a user principal name (UPN). With this approach (shown in the following example), you do not need the account's password. using System.Security.Principal; ... WindowsIdentity wi = new WindowsIdentity(userName@fullyqualifieddomainName); WindowsImpersonationContext ctx = null; try { ctx = wi.Impersonate(); // Thread is now impersonating } catch { // Prevent exceptions propagating. } finally { // Ensure impersonation is reverted ctx.Undo(); } This WindowsIdentity constructor relies on a Windows Server 2003 extension to the Kerberos protocol called Service for User to Self (S4U2Self). You can use this approach if your application runs on a Windows Server 2003 in a Windows Server 2003 domain. The advantage of this approach is that you do not have to store credentials as you do for LogonUser. However, the disadvantage is that if your code needs to access local resources, you must grant the Act as part of the operating system privilege to your Web application process account to get an impersonation-level token. To grant the Act as part of the operating system privilege
Token TypesThe type of token generated with the S4U2Self extension determines what you can do with the token while impersonating. You can obtain the following token types:
Impersonating a Fixed IdentityIf you need to impersonate the same identity throughout the lifetime of your application, you can specify credentials on the <identity> element in your Web.config file. The following example shows how to impersonate a Windows account with the name TestUser. If you use this approach, you should encrypt the credentials. With ASP.NET version 2.0, you can use the Aspnet_regiis.exe tool. With ASP.NET version 1.1, you can use the Aspnet_setreg.exe tool. To encrypt the <identity> element by using Aspnet_regiis
To decrypt the <identity> element
Note that the above commands use the default protected configuration provider named, which uses RSA encryption. To choose an alternative provider, add the -prov option naming the required provider. If your application runs in a Web farm, you should generally use the RSA provider. For more information about how to use DPAPI and RSA encryption and advice about when to use machine-level key storage versus user-level key storage, see:
Using Fixed Identities on Windows Server 2003You can configure credentials on the <identity> element on Windows 2000 Server or Windows Server 2003 to use a fixed identity for resource access on ASP.NET applications. However, if you are running on Windows Server 2003 with IIS 6.0 configured to run in worker isolation mode (the default), you can avoid impersonation by configuring your ASP.NET application to run in a custom application pool that runs under a specific domain identity. For more information, see How To: Create a Service Account for an ASP.NET 2.0 Application. DelegationTo obtain an impersonation token so that you can access network resources, you have a number of options.
Impersonation / Delegation vs. Trusted SubsystemWhen you design the authentication that you require in your application, consider whether to use impersonation to use the original caller's identity for access to back-end resources, or whether to use the trusted subsystem model, where the Web or application server is responsible for authenticating users and the server then uses a service identity to access back-end resources. The two techniques have different advantages and disadvantages as explained in the following subsections. Trusted SubsystemA trusted subsystem model is where the database server trusts the Web application identity. The Web application identity is trusted to make calls on behalf of the original caller. (See Figure 3.) Figure 3. Trusted subsystem model Trusted Subsystem AdvantagesThe advantages of the trusted subsystem model include:
Trusted Subsystem DisadvantagesThe trusted subsystem model has the following disadvantages:
Impersonation / DelegationThe impersonation and delegation model also has advantages and disadvantages. Impersonation / Delegation AdvantagesThe advantages of the impersonation / delegation model include:
Impersonation / Delegation DisadvantagesThe disadvantages of the impersonation / delegation model include:
Delegation TableThe IIS authentication type that you use affects whether or not you can impersonate the original caller and use the impersonation token to access network resources. To do so requires delegation. Table 1 shows the various IIS authentication types and whether or not you can impersonate the caller to access network resources. Table 1: IIS Authentication Types and Delegation Capability
Windows 2000 Server ConsiderationsKeep the following in mind if you are using Windows 2000 Server.
Windows Server 2003 ConsiderationsKeep the following in mind if you are using Windows Server 2003:
Additional Resources
FeedbackProvide feedback by using either a Wiki or e-mail:
We are particularly interested in feedback regarding the following:
Technical SupportTechnical support for the Microsoft products and technologies referenced in this guidance is provided by Microsoft Support Services. For product support information, please visit the Microsoft Support Web site at http://support.microsoft.com. Community and NewsgroupsCommunity support is provided in the forums and newsgroups:
To get the most benefit, find the newsgroup that corresponds to your technology or problem. For example, if you have a problem with ASP.NET security features, you would use the ASP.NET Security forum. Contributors and Reviewers
|
请发表评论