Common security issues when you access remote resources from ASP.NET applications
It is very common for developers to remotely access file shares,
Web services, databases, or other resources from ASP.NET applications. This is
typically a file server or database server separate from the Web server where
the application is running. However, for this to work as expected, there are
some very important security considerations to know about with regard to
ASP.NET process identity, authentication, and permissions. We�ll explore some
of these key concepts and possible resolutions. Which option will work best for
a particular scenario will depend on your application architecture and security
requirements.
The first and most important concept to consider is how
the ASP.NET process and thread identity works. When the .NET Framework is
installed on a Web server, it creates a low-privileged, local account named
ASPNET, or on Microsoft Internet Information Services (IIS) 6.0, the NETWORK
SERVICE account. By default, the ASP.NET worker process identity runs in the
context of this account. Even more important is to understand that this is a
local account. Let�s look at an example:
If we have a Web server
(Server A) that runs an ASP.NET application that tries to access a file share
on a second server (Server B), with default ASP.NET and IIS configurations,
this will generate an
error. If
you are trying to access a remote SQL server computer, you may get a
�Login failed for user 'MachineName\ASPNET�
error. In either case, the root cause is the same--Server B cannot authenticate
an account local to another server. By default, the thread identity trying to
access Server B will run in the context of the local ASPNET account of Server
A. This thread identity we are referring to is the
WindowsIdentity.GetCurrent.Name property, which represents the Windows logon identity under which
the current code is executing. Here are some common workarounds to this issue:
- Duplicate the default ASPNET account on the remote server.
This involves creating an account with an identical user name and password. You
must manually change the password for the ASPNET account in the Local Users and
Groups on the Web server and also use this same password in the processModel password attribute of the Machine.config file.
- Change your ASP.NET process identity in the Machine.config
file with:
<processModel userName=�domain\username� password=�pword� />
This must be a domain account so both the Web server and
file server can authenticate the user. In IIS 5.x, this forces all ASP.NET
applications on the Web server to run as the identity of the domain account
specified. In IIS 6.0, the processModel section in the Machine.config file is
ignored, and the ASP.NET process identity is controlled by the Application Pool
identity. In IIS 6.0, you can create multiple AppPools with different
identities so each application can run within its own separate process
identity. - Enable Basic authentication in IIS, disable Anonymous and
Integrated authentication, and enable impersonation in ASP.NET. This will
prompt the user for their credentials, authenticate them, and also pass the
credentials as the WindowsIdentity to ASP.NET. Realize that Basic
authentication sends user credentials in Base64 encoding, which can easily be
decrypted. We recommend that Secure Sockets Layer (SSL) be used with this
configuration.
- There are other impersonation options you can implement in
your ASP.NET application. Depending on how you impersonate, ASP.NET will use
either the IIS-authenticated user credentials or credentials you specify
explicitly. With IIS integrated authentication, you can enable impersonation
only in the Web.config file with:
<identity impersonate = �true� />
This will force the ASP.NET process identity to be the
current authenticated user identity for the whole application. However, in a
three-computer scenario, where you have the client browser, Web server, and
separate file server, this presents what is referred to as a �double hop.�
After a user has been authenticated from the client to the server, a primary
security token is created, which is the first �hop.� This primary token can be
passed only once because this is a design feature of NTLM security. When the
Web server tries to authenticate against the file server again, it tries to
pass that same security token which cannot be passed again, and creates the
second �hop.� To work around this, you can enable impersonation and specify
credentials in the Web.config file with:
<identity impersonate = �true� username=�Domain\UserName� password=�pword�/>
This will force the ASP.NET process identity to be
whatever credentials you supplied for the �userName� and �password� attributes.
There are also other impersonation options, as described in following
Microsoft Knowledge Base article:
306158 How to implement impersonation in an ASP.NET application
The following link is to an ASP.NET identity matrix
from the book �Building Secure Microsoft ASP.NET Applications.� This is very
helpful in showing which identity is being used with different combinations of
IIS authentication and ASP.NET impersonation:
http://msdn2.microsoft.com/en-us/library/aa302377.aspx - Enable ASP.NET for delegation as described in the following
Knowledge Base article:
810572 How to configure an ASP.NET application for a delegation scenario
Note Whatever account is used to access any remote resource will still
need correct NTFS permissions. Also, any options that involve changing the
Machine.config or Web.config user names or passwords can be encrypted for
increased security as described in the following Knowledge Base
article:
329290 How to use the ASP.NET utility to encrypt credentials and session state connection strings