ASP.NET 1.1 - Remote Enterprise Services to SQL Server
- J.D. Meier, Alex Mackman, Michael Dunner, Srinath Vasireddy, and Prashant Bansode
Applies To
- ASP.NET 1.1
- Enterprise Services (.NET 1.1)
Scenario
In this scenario, ASP.NET pages call business components hosted in a remote Enterprise Services application that in turn talk to a database.
Characteristics
- Users have Internet Explorer 5.x or later.
- All computers are Windows 2000 or later.
- User accounts are maintained in Active Directory within a single forest.
- The application flows the original caller's security context (at the operating system level) all the way to the database.
- All tiers use Windows authentication.
- Domain user accounts are configured for delegation and the account used to run the Enterprise Services application must be marked as "Trusted for delegation" within Active Directory.
Solution
The original caller's security context flows all the way from the browser to the database.
The Web server authenticates the caller. You must then configure ASP.NET for impersonation in order to flow the original caller's security context to the remote Enterprise Services application. Within the Enterprise Services application, component code must explicitly impersonate the caller (using CoImpersonateClient) in order to ensure the caller's context flows to the database.
Solution Summary
Authentication |
|
Authorization |
|
Secure Communication |
|
Web Server
IIS
- Disable Anonymous access for your Web application's virtual root directory
- Enable Windows Integrated authentication
ASP.NET
- Configure your ASP.NET Web application to use Windows authentication. Edit Web.config in your Web application's virtual directory root. Set the <authentication> element to:
<authentication mode="Windows" />
- Configure your ASP.NET Web application for impersonation. Edit Web.config in your Web application's virtual directory. Set the <identity> element to:
<identity impersonate="true" />
- Configure the DCOM impersonation level used by the ASP.NET Web application for outgoing calls The ASP.NET Web application calls the remote serviced components over DCOM. The default impersonation level used for outgoing calls from ASP.NET is Impersonate. This must be changed to Delegate in Machine.config. Edit Machine.config, locate the <processModel> element, and set the comImpersonateLevel attribute to "Delegate" as shown below.
<processModel comImpersonationLevel="Delegate"
- Configure the DCOM authentication level at the client DCOM authentication levels are determined by both client and server. The DCOM client in this case is ASP.NET. Edit Machine.config, locate the <processModel> element and set the comAuthenticationLevel attribute to "PktPrivacy" as shown below.
<processModel comAuthenticationLevel="PktPrivacy"
Application Server
- Managed class(es) must inherit from the ServicedComponent class
- Add code to the serviced component to impersonate the caller by calling the CoImpersonateClient()and CoRevertToSelf()APIs from OLE32.DLL before accessing remote resources (for example, a database) in order for the caller's context to be used. By default, the Enterprise Services process context is used for outgoing calls. Add references to OLE32.DLL:
class COMSec { [DllImport("OLE32.DLL", CharSet=CharSet.Auto)] public static extern long CoImpersonateClient();
[DllImport("OLE32.DLL", CharSet=CharSet.Auto)] public static extern long CoRevertToSelf(); }
Call these external functions before calling remote resources:
COMSec.CoImpersonateClient(); COMSec.CoRevertToSelf();
- Configure the Enterprise Services application as a server application. This can be configured using the Component Services tool, or via the following .NET attribute placed in the service component assembly.
[assembly:
ApplicationActivation (ActivationOption.Server)]
- Configure the Enterprise Services application to use packet privacy authentication (to provide secure communication with encryption) Add the following .NET attribute to the serviced component assembly.
[assembly: ApplicationAccessControl( Authentication = AuthenticationOption.Privacy)]
- Configure the Enterprise Services application for component level role-based security. To configure role checks at the process and component level (including interfaces and classes) use the following attribute.
[assembly: ApplicationAccessControl(AccessChecksLevel= AccessChecksLevelOption. ApplicationComponent)]
Decorate classes with the following attribute:
[ComponentAccessControl(true)]
- Create a custom account for running Enterprise Services and mark it as Trusted for delegation in Active Directory. The Enterprise Services application needs to run as domain account marked as Trusted for Delegation in Active Directory.
- Configure Enterprise Services to run as your custom account This must be configured using the Component Services tool or script. You cannot use .NET attributes within the serviced component assembly.
Database Server
- Configure SQL Server for Windows authentication.
- Create SQL Server Logins for the Windows groups that the users belong to.
- Create new database users for each SQL Server login.
- Establish database permissions for the database users.
Analysis
- The key to flowing the original caller's security context is Kerberos authentication, which generates a delegate-level token. After the server process (IIS) receives the delegate-level token, it can pass it to any other process, running under any account on the same computer, without changing its delegation level. It does not matter whether the worker process is running as a local or domain account. It does matter what IIS is running as. If it's running as something other than LocalSystem, the account it is running under needs to be marked as "Trusted for delegation" in Active Directory. If IIS is running as LocalSystem, the computer account must be marked as "Trusted for delegation". For more information, see How To: Implement Kerberos Delegation for Windows 2000 in the Reference section of this guide.
- Integrated Windows authentication (with Kerberos) in IIS is ideal in this scenario because all users have Windows accounts and they are using Internet Explorer 5.x or later. The benefit of Integrated Windows authentication is that the user's password is never sent over the wire. Additionally, the logon will be transparent because Windows will use the current interactive user's logon session.
- ASP.NET constructs a WindowsPrincipal object and attaches it to the current Web request context (HttpContext.User). If you need to perform authorization checks within the Web application you can use the following code:
WindowsPrincipal wp = (HttpContext.Current.User as WindowsPrincipal); if ( wp.IsInRole("Manager") ) { // User is authorized to perform manager-specific functionality }
Note - Additionally, if you are running ASP.NET 2.0 and have enabled the Role Manager feature, you can use the Roles APIs for role checks.
The ASP.NET FileAuthorizationModule provides ACL checks against the original caller for ASP.NET file types that are mapped within IIS to the Aspnet_isapi.dll. For static file types such as .jpg, .gif and .htm files, IIS acts as the gatekeeper and performs access checks using the original caller's identity.
- By using Windows authentication to SQL, you avoid storing credentials in files on the application server and avoid passing them across the network. For example include the Trusted_Connection attribute in the connection string:
ConStr="server=YourServer; database=yourdatabase; Trusted_Connection=Yes;"
- The original caller's context flows across all tiers, which makes auditing extremely easy. You can use platform-level auditing (for example, auditing features provided by Windows and SQL Server).
Pitfalls
- If you are using Internet Explorer 6.0 on Windows 2000, the default authentication mechanism that is negotiated is NTLM (and not Kerberos). For more information, see article Q299838, Can't Negotiate Kerberos Authentication After Upgrading to Internet Explorer 6, in the Microsoft Knowledge Base. Note - This applies only to Internet Explorer version 6 or later for Windows 2000; it works correctly on Windows Server 2003.
- Delegating users across tiers is expensive in terms of performance and application scalability compared to using the trusted subsystem model. You cannot take advantage of connection pooling to the database, because connections to the database are tied to original caller's security context and therefore cannot be efficiently pooled.
- This approach also relies on the granularity of Windows groups matching your application's security needs. That is, Windows groups must be set up at the correct level of granularity to match the categories of users (sharing the same security privileges) who access the application.