ASP.NET 2.0 Security Practices - Impersonation and Delegation

From Guidance Share
Jump to navigationJump to search

How to choose between trusted subsystem and impersonation/delegation

With the trusted subsystem model, you use your Web application's process identity to access downstream network resources such as databases. With impersonation/delegation, you use impersonation and use the original caller's identity to access the database.


Trusted subsystem offers better scalability because your application benefits from efficient connection pooling. You also minimize back-end ACL management. Only the trusted identity can access the database. Your end users have no direct access. In the trusted subsystem model, the middle-tier service is granted broad access to back-end resources. As a result, a compromised middle-tier service could potentially make it easier for an attacker to gain broad access to back-end resources. Keeping the service account's credentials protected is essential.


With impersonation/delegation, you benefit from operating system auditing because you can track which users have attempted to access specific resources. You can also enforce granular access controls in the database, and individual user accounts can be restricted independently of one another in the database.


How to impersonate the original caller

ASP.NET does not impersonate the original caller by default. If you need to impersonate the original caller, set the mode attribute of the <authentication> element in the Web.config file to Windows and the impersonate attribute of the <identity> element to true.


In IIS, disable anonymous access and select a Windows authentication mechanism. If you do not do this, the ASP.NET application will impersonate the anonymous IIS account IUSR_machineName.


How to temporarily impersonate the original caller

To temporarily impersonate the original caller in your application's Web.config file, set the mode attribute of the <authentication> element to Windows.


In IIS, disable anonymous access and select a Windows authentication mechanism. In your code, use the Impersonate method of the System.Security.Principal.WindowsIdentity class, as shown here.

using System.Security.Principal;
...
IIdentity WinId= HttpContext.Current.User.Identity;
WindowsIdentity userId = (WindowsIdentity)WinId;
// impersonate temporarily
WindowsImpersonationContext wic = userId.Impersonate();
try
{
  // run code, access resources using the original caller's
  // security context
}
catch (Exception ex)
{
  // handle the exception appropriately
}
finally
{
  // restore our old security context
  wic.Undo();
}


For more information, see How To: Use Impersonation and Delegation in ASP.NET 2.0.


How to use protocol transition and constrained delegation in ASP.NET

Protocol transition allows an application on a designated server to use any method to authenticate the original caller and then to transition to the Kerberos protocol to access back-end network resources. This is particularly useful in scenarios where your users access your application over the Internet but firewalls prevent them from communicating directly with the domain controller. In this scenario, you can authenticate your users by using forms, client certificates, or some alternative authentication mechanism, and then create valid Windows tokens on the server for your users; use those and Kerberos authentication to access back-end network resources. You can then use constrained delegation to ensure that these tokens and their associated logon sessions can only be used to communicate with designated services on specific servers.


To use protocol transition and constrained delegation, you must:

  • Be on a specially designated server that is trusted for delegation.
  • Use local security policy to grant the Act as part of the operating system privilege (TCB) to the account used to run ASP.NET on the Web tier (the Network Service account by default for IIS 6.0).
  • Configure Active Directory for protocol transition and constrained delegation.


On Windows Server 2003, the WindowsIdentity constructor uses the new Kerberos S4U extension to obtain a logon session and Windows token for a user without that user's password as shown here.

using System.Security.Principal;
...
WindowsIdentity wi = new WindowsIdentity("username@domainName");
WindowsImpersonationContext wic = wi.Impersonate();
try
{
// do work
}
catch (Exception ex)
{
  // handle the exception appropriately
}
finally
{
  // stop impersonating
  wic.Undo();
}


For more information, see How To: Use Protocol Transition and Constrained Delegation in ASP.NET 2.0.


How to retain impersonation in the new thread

ASP.NET does not flow the impersonation token across threads by default. If you need to flow the impersonation token across threads, set the enabled attribute to true on the alwaysFlowImpersonationPolicy element in the ASPNET.config file in the %Windir%Microsoft.NET\Framework\{Version} directory, as in the following example.

....
<configuration>
  <runtime>
    <alwaysFlowImpersonationPolicy enabled="true"/>
     </runtime>
</configuration>
....


If you need to prevent impersonation tokens from being passed to new threads programmatically, you can use the ExecutionContext.SuppressFlow method.