Building Secure ASP.NET Applications: Authentication, Authorization, and Secure Communication

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

 

patterns & practices Developer Center

.NET Remoting Security

J.D. Meier, Alex Mackman, Michael Dunner, and Srinath Vasireddy
Microsoft Corporation

Published: November 2002

Last Revised: January 2006

Applies to:

  • Remoting (.NET Framework 1.1)

See the "patterns & practices Security Guidance for Applications Index" for links to additional security resources.

See the Landing Page for the starting point and complete overview of Building Secure ASP.NET Applications.

Summary: The .NET Framework provides a remoting infrastructure that allows clients to communicate with objects, hosted in remote application domains and processes, or on remote computers. This chapter shows you how to implement secure .NET Remoting solutions. (27 printed pages)

Contents

.NET Remoting Architecture
.NET Remoting Gatekeepers
Authentication
Authorization
Authentication and Authorization Strategies
Accessing System Resources
Accessing Network Resources
Passing Credentials for Authentication to Remote Objects
Flowing the Original Caller
Trusted Subsystem
Secure Communication
Choosing a Host Process
Remoting vs. Web Services
Summary

The .NET Framework provides a remoting infrastructure that allows clients to communicate with objects, hosted in remote application domains and processes, or on remote computers. This chapter shows you how to implement secure .NET Remoting solutions.

.NET Remoting Architecture

Figure 11.1 shows the basic .NET Remoting architecture when a remote object is hosted within ASP.NET. An ASP.NET host, coupled with the HTTP channel for communication, is the recommended approach if security is the key concern, because it allows the remote object to utilize the underlying security services provided by ASP.NET and IIS.

For more information about the range of possible host and channel types, together with comparison information, see Choosing a Host Process later in this chapter.

Ff649353.f11sn01(en-us,PandP.10).gif

Figure 11.1. The .NET remoting architecture

The client communicates with an in-process proxy object. Credentials for authentication (for example, user names, passwords, certificates, and so on) can be set through the remote object proxy. The method call proceeds through a chain of sinks (you can implement your own custom sinks, for example, to perform data encryption) and onto a transport sink that is responsible for sending the data across the network. At the server side, the call passes through the same pipeline after which the call is dispatched to the object.

Note   The term proxy used throughout this chapter refers to the client-side, in-process proxy object through which clients communicate with the remote object. Do not confuse this with the term proxy server.

Remoting Sinks

.NET Remoting uses transport channels sinks, custom channel sinks, and formatter channel sinks when a client invokes a method call on a remote object.

Transport channel sinks

Transport channel sinks pass method calls across the network between the client and the server. .NET supplies the HttpChannel and the TcpChannel classes, although the architecture is fully extensible and you can plug in your own custom implementations.

  • HttpChannel. This channel is designed to be used when you host a remote object in ASP.NET. This channel uses the HTTP protocol to send messages between the client and the server.

    Note   In .NET Framework 2.0, HttpChannel supports encryption using the Security Support Provider Interface (SSPI).

  • TcpChannel. This channel is designed to be used when you host a remote object in a Microsoft® Windows® operating system service or other executable. This channel uses TCP sockets to send messages between the client and the server.

    Note   In .NET Framework 2.0, TcpChannel supports authentication and encryption using SSPI.

  • Custom channels. A custom transport channel can use any underlying transport protocol to send messages between the client and server. For example, a custom channel may use named pipes or mail slots.

    Note   The .NET Framework 2.0 introduces IpcChannel, which uses named pipes to provide high-speed inter-process communication for multiple process applications on the same computer. For more information on IpcChannel, refer to "Choosing a Channel."

Comparing Transport Channel Sinks

The following table provides a comparison of the two main transport channel sinks.

Table 11.1. Comparison of TcpChannel and HttpChannel

Feature TCP Channel HTTP Channel Comments
Authentication No Yes HttpChannel uses the authentication features provided by IIS and ASP.NET, although Passport and Forms authentication are not supported.
Note   In .NET Framework 2.0, TcpChannel supports authentication and encryption using SSPI.
Authorization No Yes HttpChannel supports the authorization features provided by IIS and ASP.NET. These features include NTFS permissions, URL authorization, and File authorization.
Secure Communication Yes Yes TcpChannel uses IPSec. The HttpChannel uses SSL and/or IPSec.
Note   In .NET Framework 2.0, both the TcpChannel and the HttpChannel support SSPI encryption, which can be used to secure communication.

Custom sinks

Custom channels sinks can be used at different locations within the channel sink pipeline to modify the messages sent between the client and the server. A channel sink that provides encryption and decryption is an example of a custom channel sink.

Formatter sinks

Formatter sinks take method calls and serialize them into a stream capable of being sent across the network. .NET supplies two formatter sinks:

  • Binary Formatter. This uses the BinaryFormatter class to package method calls into a serialized binary stream, which is subsequently posted (using an HTTP POST) to send the data to the server. The binary formatter sets the content-type in the HTTP request to "application/octet-stream."

    The binary formatter offers superior performance in comparison to the SOAP formatter.

  • SOAP Formatter. This uses the SoapFormatter class to package method calls into a SOAP message. The content type is set to "text/xml" in the HTTP request and is posted to the server with an HTTP POST.

Anatomy of a Request When Hosting in ASP.NET

Remote object endpoints are addressed by URLs that end with the .rem or .soap file name extension, for example http://someserver/vDir/remoteobject.soap. When a request for a remote object (with the extension .rem or .soap), is received by IIS, it is mapped (within IIS) to the ASP.NET ISAPI extension (Aspnet_isapi.dll). The ISAPI extension forwards the request to an application domain within the ASP.NET worker process. The sequence of events is shown in Figure 11.2.

Ff649353.f11sn02(en-us,PandP.10).gif

Figure 11.2. Server-side processing

Figure 11.2 shows the following sequence of events:

  1. A .soap or .rem request is received over HTTP and is mapped to a specific virtual directory on the Web server.

  2. IIS checks the .soap/.rem mapping and maps the file extension to the ASP.NET ISAPI extension, Aspnet_isapi.dll.

  3. The ISAPI extension transfers the request to an application domain inside the ASP.NET worker process. If this is the first request directed at this application, a new application domain is created.

  4. The HttpRemotingHandlerFactory handler is invoked and the remoting infrastructure reads the <system.runtime.remoting> section in the Web.config that controls the server-side object configuration (for example, single-call or singleton parameters) and authorization parameters (from the <authorization> element).

  5. The remoting infrastructure locates the assembly that contains the remote object and instantiates it.

  6. The remoting infrastructure reads the HTTP headers and the data stream, and then invokes the method on the remote object.

    Note   During this process, ASP.NET calls the normal sequence of event handlers. You can optionally implement one or more of these in Global.asax. For example, BeginRequest, AuthenticationRequest, AuthorizeRequest, and so on. By the time the request reaches the remote object method, the IPrincipal object that represents the authenticated user is stored in HttpContext.User (and Thread.CurrentPrincipal) and is available for authorization. For example, by using principal permission demands and programmatic role checks.

ASP.NET and the HTTP Channel

Remoting does not have its own security model. Authentication and authorization between the client (proxy) and server (remote object) is performed by the channel and host process. You can use the following combination of hosts and channels:

  • A custom executable and the TCP channel. This combination does not provide any inbuilt security features.
  • ASP.NET and the HTTP channel. This combination provides authentication and authorization through the underlying ASP.NET and IIS security features.

Objects hosted within ASP.NET benefit from the underlying security features of ASP.NET and IIS. These include:

  • Authentication Features. Windows authentication is configured within Web.config:

    <authentication mode="Windows"/>
    

    The settings in IIS control what type of HTTP authentication is used.

    Common HTTP headers are used to authenticate requests. You can supply credentials for the client by configuring the remote object proxy or you can use default credentials.

    You cannot use Forms or Passport authentication because the channel does not provide a way to allow the client to access cookies, which is a requirement for both of these authentication mechanisms. Also, Forms and Passport require a redirect to a logon page that requires client interaction. Remote, server side objects are designed for non-interactive use.

  • Authorization Features. Clients are authorized using standard ASP.NET authorization techniques.

    Configurable authorization options include:

    • URL authorization.
    • File authorization (this requires specific configuration, as described in "Using File Authorization" later in this chapter).

    Programmatic authorization options include:

    • Principal permission demands (declarative and imperative).

    • Explicit role checks using IPrincipal.IsInRole.

      Note   When using the Role Manager feature In ASP.NET 2.0, you can also use the Roles API for role checks. For more information, see "How To: Use Role Manager in ASP.NET 2.0."

  • Secure Communication Features. SSL (and/or IPSec) should be used to secure the transport of data between the client and server.

    Note   In .NET Framework 2.0, HttpChannel supports SSPI encryption.

More information

.NET Remoting Gatekeepers

The authorization points (or gatekeepers) available to a remote object hosted by ASP.NET are:

  • IIS. With anonymous authentication turned off, IIS only permits requests from users that it can authenticate either in its domain or in a trusted domain. IIS also provides IP address and DNS filtering.

  • ASP.NET

    • UrlAuthorizationModule. You can configure <authorization> elements within your application's Web.config to control which users and groups of users should have access to the application. Authorization is based on the IPrincipal object stored in HttpContext.User.

    • FileAuthorizationModule. The FileAuthorizationModule is available to remote components, although this requires specific configuration, as described in "Using File Authorization" later in this chapter.

      Note   Impersonation is not required for File authorization to work.

      The FileAuthorizationModule class only performs access checks against the requested file or URI (for example .rem and .soap), and not for files accessed by code within the remote object.

  • Principal Permission Demands and Explicit Role Checks. In addition to the IIS and ASP.NET configurable gatekeepers, you can also use principal permission demands (declaratively or imperatively) as an additional fine-grained access control mechanism. Principal permission checks allow you to control access to classes, methods, or individual code blocks based on the identity and group membership of individual users, as defined by the IPrincipal object attached to the current thread.

    Note   Principal permission checks used to demand role membership are different from calling IPrincipal.IsInRole to test role membership. The former results in an exception if the caller is not a member of the specified role, while the latter simply returns a Boolean value to confirm role membership.

    With Windows authentication, ASP.NET automatically attaches a WindowsPrincipal object that represents the authenticated user to the current Web request (using HttpContext.User).

Authentication

When you use remoting in conjunction with an ASP.NET Web application client, authentication occurs within the Web application and at the remote object host. The available authentication options for the remote object host depend on the type of host.

Hosting in ASP.NET

When objects are hosted in ASP.NET the HTTP channel is used to communicate method calls between the client-side proxy and the server. The HTTP channel uses the HTTP protocol to authenticate the remote object proxy to the server.

The following list shows the range of authentication options available when you host inside ASP.NET:

  • IIS Authentication Options. Anonymous, Basic, Digest, Windows Integrated and Certificate.

  • ASP.NET Authentication Options. Windows authentication or None (for custom authentication implementations).

    Note   Forms and Passport authentication cannot be used directly by .NET Remoting. Calls to remote objects are designed to be non-interactive. If the client of the remote object is a .NET Web application, the Web application can use Forms and Passport authentication and pass credentials explicitly to the remote object. This type of scenario is discussed further in the "Flowing the Original Caller" section later in this chapter.

Hosting in a Windows Service

When objects are hosted in a Windows service, the TCP channel is used to communicate method calls between the client and server. This uses raw socket-based communications. Because there is no authentication provided with sockets in .NET Framework 1.1, there is no way for the server to authenticate the client.

In this scenario, the remote object must use custom authentication.

Note   However, in .NET Framework 2.0, the TCP channel supports SPPI authentication.

Custom authentication

For simple custom authentication, the remote object can expose a Login method which accepts a user name and password. The credentials can be validated against a store, a list of roles retrieved, and a token sent back to the client to use on subsequent requests. When the token is retrieved at the server it is used to create an IPrincipal object (with roles) which is stored in Thread.CurrentPrincipal, where it is used for authorization purposes.

Other examples of custom authentication include creating a custom transport channel sink that uses an inter-process communication channel that provides authentication, such as named pipes, or creating a channel sink that performs authentication using the Windows Security Service Provider Interface (SSPI).

More information

Authorization

When objects are hosted by ASP.NET and the HTTP channel is used for communication, the client can be authenticated and authorization can be controlled by the following mechanisms:

  • URL authorization

  • File authorization

  • Principal permission demands (declarative and imperative)

  • IPrincipal.IsInRole checks in code

    Note   When using the Role Manager feature in ASP.NET 2.0, you can also use the Roles API for role checks. For more information, see "How To: Use Role Manager in ASP.NET 2.0."

When objects are hosted in a Windows service, there is no authentication provided by the TCP channel. As a result, you must perform custom authentication and then perform authorization by creating an IPrincipal object and storing it in Thread.CurrentPrincipal.

You can then annotate your remote object's methods with declarative principal permission demand checks, like the one shown below.

[PrincipalPermission(SecurityAction.Demand, 
                     Role="Manager")]
void SomeMethod()
{
}

Within your object's method code, imperative principal permission demands and explicit role checks using IPrincipal.IsInRole can also be used.

Using File Authorization

You may want to use built-in Windows access control to secure the remote object as a securable Windows resource. Without File authorization (using Windows ACLs), you only have URL authorization.

To use the FileAuthorizationModule to authorize access to remote object endpoints (identified with .rem or .soap URLs), you must create a physical file with the .rem or .soap extension within your application's virtual directory.

Note   The .rem and .soap extensions are used by IIS to map requests for object endpoints to the ASP.NET ISAPI extension (aspnet_isapi.dll). They do not usually exist as physical files.

To configure File authorization for .NET Remoting

  1. Create a file with the same name as the objectUri (for example, RemoteMath.rem) in the root of the application's virtual directory.

  2. Add the following line to the top of the file and save the file.

    <%@ webservice class="YourNamespace.YourClass" ... %>
    
  3. Add an appropriately configured ACL to the file using Windows Explorer.

    Note   You can obtain the objectUri from the web.config file used to configure the remote object on the server. Look for the <wellknown> element, as shown in the following example.

    <wellknown mode="SingleCall" objectUri="RemoteMath.rem" type="RemotingObjects.RemoteMath, RemotingObjects, Version=1.0.000.000 Culture=neutral, PublicKeyToken=4b5ae668c251b606"/>
    

More information

  • For more information about these authorization mechanisms, see Chapter 8, ASP.NET Security.
  • For more information about principal permission demands, see Chapter 8, ASP.NET Security.

Authentication and Authorization Strategies

In many applications that use .NET Remoting, the remote objects are used to provide business functionality within the application's middle tier and this functionality is called by ASP.NET Web applications. This arrangement is shown in Figure 11.3.

Ff649353.f11sn03(en-us,PandP.10).gif

Figure 11.3. Remote objects called by an ASP.NET Web application

In this scenario, the IIS and ASP.NET gatekeepers available to the Web application can be used to secure access to the client-side proxy, and the IIS and ASP.NET gatekeepers available to the ASP.NET host on the remote application server are available to secure access to the remote object.

There are essentially two authentication and authorization strategies for remote objects that are accessed by .NET Web applications.

  • You can authenticate and authorize callers at the Web server and then flow the caller's security context to the remote object by using impersonation. This is the impersonation/delegation model.

    With this approach you use an IIS authentication mechanism that allows you to delegate the caller's security context, such as Kerberos, Basic, or Forms authentication (the latter two allow the Web application to access the caller's credentials) and explicitly flow credentials to the remote object using the remote object's proxy.

    The ASP.NET configurable and programmatic gatekeepers (including URL authorization, File authorization, principal permission demands, and .NET roles) are available to authorize individual callers within the remote object.

  • You can authenticate and authorize callers at the Web server and then use a trusted identity to communicate with the remote object. This is the trusted subsystem model.

    This model relies on the Web application to authenticate and properly authorize callers before invoking the remote object. Any requests received by the remote object from the trusted identity projected from the Web application are allowed to proceed.

More Information

  • For more information about the impersonation/delegation and trusted subsystem models, see Choosing an Authentication Mechanism in Chapter 3, "Authentication and Authorization."
  • For more information about using the original caller model with remoting, Flowing the Original Caller later in this chapter.
  • For more information about using the trusted subsystem model with remoting, see Trusted Subsystem later in this chapter.

Accessing System Resources

For details about accessing system resources (for example, the event log and the registry) from a remote object hosted by ASP.NET, see Accessing System Resources in Chapter 8, "ASP.NET Security." The approaches and restrictions discussed in Chapter 8 also apply to remote objects hosted by ASP.NET.

Accessing Network Resources

When you access network resources from a remote object, you need to consider the identity that is used to respond to network authentication challenges from the remote computer. You have three options:

  • The Process Identity (this is the default). If you host within ASP.NET, the identity used to run the ASP.NET worker process and defined by the <processModel> element in Machine.config determines the security context used for resource access.

    Note   If you are running IIS 6.0 on Windows Server 2003 in process isolation mode, the application pool identity is used to determine the process identity instead of the process model setting. By default, this identity is Network Service, which is the least privileged account.

    If you host within a Windows service, the identity used to run the service process (configured with the Services MMC snap-in) determines the security context used for resource access.

  • A Fixed Service Identity. For example, one created by calling LogonUser.

    Note   Don't confuse this service identity with the identity used to run a Windows service. A fixed service identity refers to a Windows user account created specifically for the purposes of accessing resources from an application.

  • The Original Caller Identity. With ASP.NET configured for impersonation, or programmatic impersonation used within a Windows service.

For details about the relative merits of each of these approaches, together with configuration details, see Accessing Network Resources in Chapter 8, "ASP.NET Security."

Passing Credentials for Authentication to Remote Objects

When a client process calls a remote object, it does so by using a proxy. This is a local object that exposes the same set of methods as the target object.

Specifying Client Credentials

If the remote object is hosted within ASP.NET and is configured for Windows authentication, you must specify the credentials to be used for authentication using the credentials property of the channel. If you do not explicitly set credentials, the remote object is called without any credentials. If Windows authentication is required, this will result in an HTTP status 401, which is an access denied response.

Using DefaultCredentials

If you want to use the credentials of the process that hosts the remote object proxy (or the current thread token, if the thread that calls the proxy is impersonating), you should set the credentials property of the channel to the DefaultCredentials maintained by the process credential cache.

You can either specify the use of DefaultCredentials in a configuration file or set the credentials programmatically.

Explicit configuration

Within the client application configuration file (Web.config, if the client application is an ASP.NET Web application) set the useDefaultCredentials attribute on the <channel> element to true in order to specify that the proxy should use DefaultCredentials when it communicates with the remote object.

<channel ref="http" useDefaultCredentials="true" />

Programmatic configuration

For programmatic configuration, use the following code to establish the use of DefaultCredentials programmatically.

IDictionary channelProperties;
channelProperties = ChannelServices.GetChannelSinkProperties(proxy);
channelProperties ["credentials"] = CredentialCache.DefaultCredentials;

Using specific credentials

To use a specific set of credentials for authentication when you call a remote object, disable the use of default credentials within the configuration file, by using the following setting.

<channel ref="http" useDefaultCredentials="false" />

Note   Programmatic settings always override the settings in the configuration file.

Then, use the following code to configure the proxy to use specific credentials.

IDictionary channelProperties =  
                         ChannelServices.GetChannelSinkProperties(proxy);
NetworkCredential credentials;
credentials = new NetworkCredential("username", "password", "domain");
ObjRef objectReference = RemotingServices.Marshal(proxy);
Uri objectUri = new Uri(objectReference.URI);
CredentialCache credCache = new CredentialCache();
// Substitute "authenticationType" with "Negotiate", "Basic", 
// "Digest", 
// "Kerberos" or "NTLM"
credCache.Add(objectUri, "authenticationType", credentials);
channelProperties["credentials"] = credCache;
channelProperties["preauthenticate"] = true;

Always request a specific authentication type

You should always request a specific authentication type by using the CredentialCache.Add method, as illustrated above. Avoid direct use of the NetworkCredential class as shown in the following code.

IDictionary providerData = ChannelServices.GetChannelSinkProperties(yourProxy);
providerData["credentials"] = new NetworkCredential(uid, pwd);

This should be avoided in production code because you have no control over the authentication mechanism used by the remote object host and as a result you have no control over how the credentials are used.

For example, you may expect a Kerberos or NTLM authentication challenge from the server but instead you may receive a Basic challenge. In this case, the supplied user name and password will be sent to the server in clear text form.

Set the preauthenticate property

The proxy's preauthenticate property can be set to true or false. Set it to true (as shown in the above code) to supply specific authentication credentials to cause a WWW-Authenticate HTTP header to be passed with the initial request. This stops the Web server denying access on the initial request, and performing authentication on the subsequent request.

Using the connectiongroupname property

If you have an ASP.NET Web application that connects to a remote component (hosted by ASP.NET) and flows the security context of the original caller (by using DefaultCredentials and impersonation or by setting explicit credentials, as shown above), you should set the connectiongroupname property of the channel within the Web application. This is to prevent a new, unauthenticated client from reusing an old, authenticated connection to the remote component that is associated with a previous client's authentication credentials. Connection reuse can occur as a result of HTTP KeepAlives and authentication persistence which is enabled for performance reasons within IIS.

Set the connectiongroupname property to an identifier (such as the caller's user name) that distinguishes one caller from the next.

channelProperties["connectiongroupname"] = userName;

Note   You do not need to set the connectiongroupname property if the original caller's security context does not flow through the Web application and onto the remote component, but connects to the remote component using a fixed identity (such as the Web application's ASP.NET process identity). In this scenario, the connection security context remains constant from one caller to the next.

The next version of the .NET Framework will support connection pooling based on the SID of the thread that calls the proxy object, which will help to address the problem described above, if the Web application is impersonating the caller. Pooling will be supported for .NET Remoting clients and not for Web services clients.

Flowing the Original Caller

This section describes how you can flow the original caller's security context through an ASP.NET Web application and onto a remote component hosted by ASP.NET on a remote application server. You may need to do this in order to support per-user authorization within the remote object or within subsequent downstream subsystems (for example databases).

In Figure 11.4, the security context of the original caller (Bob) flows through the front-end Web server that hosts an ASP.NET Web application, onto the remote object, hosted by ASP.NET on a remote application server, and finally through to a back-end database server.

Ff649353.f11sn04(en-us,PandP.10).gif

Figure 11.4. Flowing the original caller's security context

In order to flow credentials to a remote object, the remote object client (the ASP.NET Web application in this scenario) must configure the object's proxy and explicitly set the proxy's credentials property, as described in "Passing Credentials for Authentication to Remote Objects" earlier in this chapter.

Note   IPrincipal objects do not flow across .NET Remoting boundaries.

There are two ways to flow the caller's context:

  • Pass default credentials and use Kerberos authentication (and delegation). This approach requires that you impersonate within the ASP.NET Web application and configure the remote object proxy with DefaultCredentials obtained from the impersonated caller's security context.
  • Pass explicit credentials and use Basic or Forms authentication. This approach does not require impersonation within the ASP.NET Web application. Instead, you programmatically configure the remote object proxy with explicit credentials obtained from either, server variables (with Basic authentication), or HTML form fields (with Forms authentication) that are available to the Web application. With Basic or Forms authentication, the username and password are available to the server in clear text.

Default Credentials with Kerberos Delegation

To use Kerberos delegation, all computers (servers and clients) must be running Windows 2000 or later. Additionally, client accounts that are to be delegated must be stored in Active Directory™ directory service and must not be marked as "Sensitive and cannot be delegated."

The following tables show the configuration steps required on the Web server and application server.

Configuring the Web server

Configure IIS  
Step More Information
Disable Anonymous access for your Web application's virtual root directory

Enable Windows Integrated Authentication for the Web application's virtual root




Kerberos authentication will be negotiated assuming clients and server are running Windows 2000 or above.
Note   If you are using Microsoft Internet Explorer 6 on Windows 2000, it defaults to NTLM authentication instead of the required Kerberos authentication. To enable Kerberos delegation, see article Q299838, Unable to Negotiate Kerberos Authentication after upgrading to Internet Explorer 6, in the Microsoft Knowledge Base.
Configure ASP.NET  
Step More Information
Configure your ASP.NET Web application to use Windows authentication Edit Web.config in your Web application's virtual directory.
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 Remoting (Client Side Proxy)  
Step More Information
Configure the remote object proxy to use default credentials for all calls to the remote object Add the following entry to Web.config:
<channel ref="http" 
         useDefaultCredentials="true" />

Credentials will be obtained from the Web application's thread impersonation token.

Configuring the remote application server

Configure IIS  
Step More Information
Disable Anonymous access for your Web application's virtual root directory

Enable Windows Integrated Authentication for the Web application's virtual root




Configure ASP.NET (Remote Object Host)  
Step More Information
Configure ASP.NET to use Windows authentication Edit Web.config in the application's virtual directory.
Set the <authentication> element to:
<authentication mode="Windows" />
Configure ASP.NET for impersonation Edit Web.config in the application's virtual directory.
Set the <identity> element to:
<identity impersonate="true" />
Note   This step is only required if you want to flow the original caller's security context through the remote object and onto the next, downstream subsystem (for example, database). With impersonation enabled here, resource access (local and remote) uses the impersonated original caller's security context. If your requirement is simply to allow per-user authorization checks in the remote object, you do not need to impersonate here.

More information

For more information about Kerberos delegation, see How To: Implement Kerberos Delegation for Windows 2000 in the Reference section of this guide.

Explicit Credentials with Basic or Forms Authentication

As an alternative to Kerberos delegation, you can use Basic or Forms authentication at the Web application to capture the client's credentials and then use Basic (or Integrated Windows) authentication to the remote object.

With this approach, the client's clear text credentials are available to the Web application. These can be passed to the remote object through the remote object proxy. For this, you must include code in the Web application to retrieve the client's credentials and configure the remote object proxy.

Basic authentication

With Basic authentication, the original caller's credentials are available to the Web application in server variables. The following code shows how to retrieve them and configure the remote object proxy.

// Retrieve client's credentials (available with Basic 
// authentication)
string pwd = Request.ServerVariables["AUTH_PASSWORD"];
string uid = Request.ServerVariables["AUTH_USER"];
// Associate the credentials with the remote object proxy
IDictionary channelProperties =  
                         ChannelServices.GetChannelSinkProperties(proxy);
NetworkCredential credentials;
credentials = new NetworkCredential(uid, pwd);
ObjRef objectReference = RemotingServices.Marshal(proxy);
Uri objectUri = new Uri(objectReference.URI);
CredentialCache credCache = new CredentialCache();
credCache.Add(objectUri, "Basic", credentials);
channelProperties["credentials"] = credCache;
channelProperties["preauthenticate"] = true;

Note   The NetworkCredential constructor shown in the above code is supplied with the user ID and password. To avoid hard coding the domain name, a default domain can be configured at the Web server within IIS when you configure Basic authentication.

Forms authentication

With Forms authentication, the original caller's credentials are available to the Web application in form fields (rather than server variables). In this case, use the following code.

// Retrieve client's credentials from the logon form
string pwd = txtPassword.Text;
string uid = txtUid.Text;
// Associate the credentials with the remote object proxy
IDictionary channelProperties =  
                         ChannelServices.GetChannelSinkProperties(proxy);
NetworkCredential credentials;
credentials = new NetworkCredential(uid, pwd);
ObjRef objectReference = RemotingServices.Marshal(proxy);
Uri objectUri = new Uri(objectReference.URI);
CredentialCache credCache = new CredentialCache();
credCache.Add(objectUri, "Basic", credentials);
channelProperties["credentials"] = credCache;
channelProperties["preauthenticate"] = true;

The following tables show the configuration steps required on the Web server and application server.

Configuring the Web server

Configure IIS  
Step More Information
To use Basic authentication, disable Anonymous access for your Web application's virtual root directory and select Basic authentication

- or -

To use Forms authentication, enable anonymous access
Both Basic and Forms authentication should be used in conjunction with SSL to protect the clear text credentials sent over the network. If you use Basic authentication, SSL should be used for all pages (not just the initial logon page) because Basic credentials are transmitted with every request.

- or -

Similarly, SSL should be used for all pages if you use Forms authentication to protect the clear text credentials on the initial logon and to protect the authentication ticket passed on subsequent requests.
Configure ASP.NET  
Step More Information
If you use Basic authentication, configure your ASP.NET Web application to use Windows authentication

- or -

If you use Forms authentication, configure your ASP.NET Web application to use Forms authentication
Edit Web.config in your Web application's virtual directory.
Set the <authentication> element to:
<authentication mode="Windows" />


- or -

Edit Web.config in your Web application's virtual directory.
Set the <authentication> element to:

<authentication mode="Forms" />
Disable impersonation within the ASP.NET Web application Edit Web.config in your Web application's virtual directory.
Set the <identity> element to:
<identity impersonate="false" />
Note   This is equivalent to having no <identity> element. Impersonation is not required because the user's credentials will be passed explicitly to the remote object through the remote object proxy.
Configure Remoting (Client Side Proxy)  
Step More Information
Configure the remoting proxy to not use default credentials for all calls to the remote object Add the following entry to Web.config:
<channel ref="http" 
         useDefaultCredentials="false" />

You do not want default credentials to be used (because the Web application is configured not to impersonate; this would result in the security context of the ASP.NET process identity being used).

Write code to capture and explicitly set the credentials on the remote object proxy Refer to the code fragments shown earlier.

Configuring the application server

Configure IIS  
Step More Information
Disable Anonymous access for your application's virtual root directory

Enable Basic authentication
Note   Basic authentication at the application server (remote object), allows the remote object to flow the original caller's security context to the database (because the caller's user name and password are available in clear text and can be used to respond to network authentication challenges from the database server). If you don't need to flow the original caller's security context beyond the remote object, consider configuring IIS at the application server to use Windows Integrated authentication because this provides tighter security—credentials are not passed across the network and are not available to the application.
Configure ASP.NET (Remote Object Host)  
Step More Information
Configure ASP.NET to use Windows authentication Edit Web.config in the application's virtual directory.
Set the <authentication> element to:
<authentication mode="Windows" />
Configure ASP.NET for impersonation Edit Web.config in the application's virtual directory.
Set the <identity> element to:
<identity impersonate="true" />
Note   This step is only required if you want to flow the original caller's security context through the remote object and onto the next, downstream subsystem (for example, database). With impersonation enabled here, resource access (local and remote) uses the impersonated original caller's security context. If your requirement is simply to allow per-user authorization checks in the remote object, you do not need to impersonate here.

Trusted Subsystem

The trusted subsystem model provides an alternative (and simpler to implement) approach to flowing the original caller's security context. In this model, a trust boundary exists between the remote object host and Web application. The remote object trusts the Web application to properly authenticate and authorize callers, prior to letting requests proceed to the remote object. No authentication of the original caller occurs within the remote object host. The remote object host authenticates the fixed, trusted identity used by the Web application to communicate with the remote object. In most cases, this is the process identity of the ASP.NET Web application.

The trusted subsystem model is shown in Figure 11.5. This diagram also shows two possible configurations. The first uses the ASP.NET host and the HTTP channel, while the second uses a Windows service host and the TCP channel.

Ff649353.f11sn05(en-us,PandP.10).gif

Figure 11.5. The trusted subsystem model

Flowing the Caller's Identity

If you use the trusted subsystem model, you may still need to flow the original caller's identity (name, not security context), for example, for auditing purposes at the database.

You can flow the identity at the application level by using method and stored procedure parameters and trusted query parameters (as shown in the following example) can be used to retrieve user-specific data from the database.

SELECT x,y,z FROM SomeTable WHERE UserName = "Bob"
  

Choosing a Host

The trusted subsystem model means that the remote object host does not authenticate the original callers. However, it must still authenticate (and authorize) its immediate client (the ASP.NET Web application in this scenario), to prevent unauthorized applications issuing requests to the remote object.

If you host within ASP.NET and use the HTTP channel, you can use Windows Integrated authentication to authenticate the ASP.NET Web application process identity.

If you host within a Windows service, you can use the TCP channel which offers superior performance but no authentication capabilities. In this scenario, you can use IPSec between the Web server and application server. An IPSec policy can be established that only allows the Web server to communicate with the application server.

Note   In .Net 2.0 the TCP channels have inbuilt support for authentication (identification / impersonation) and authorization.

Configuration Steps

The following tables show the configuration steps required on the Web server and application server.

Configuring the Web server

Configure IIS  
Step More Information
Configure IIS authentication The Web application can use any form of authentication to authenticate the original callers.
Configure ASP.NET  
Step More Information
Configure authentication and make sure impersonation is disabled Edit Web.config in your Web application's virtual directory.
Set the <authentication> element to "Windows", "Forms" or "Passport."
<authentication mode="Windows|Forms|Passport" />

Set the <identity> element to:

<identity impersonate="false" />

(OR remove the <identity> element)

Reset the password of the ASPNET account used to run ASP.NET OR create a least privileged domain account to run ASP.NET and specify account details on the <processModel> element within Web.config For more information about how to access network resources (including remote objects) from ASP.NET and about choosing and configuring a process account for ASP.NET, see Accessing Network Resources and Process Identity for ASP.NET in Chapter 8, "ASP.NET Security."
Configure Remoting (Client Side Proxy  
Step More Information
Configure the remoting proxy to use default credentials for all calls to the remote object Add the following entry to Web.config:
<channel ref="http" 
         useDefaultCredentials="true" />

Because the Web application is not impersonating, using default credentials results in the use of the ASP.NET process identity for all calls to the remote object.

Configuring the application server

The following steps apply if you are using an ASP.NET host.

Configure IIS  
Step More Information
Disable Anonymous access for your application's virtual root directory

Enable Windows Integrated authentication




Configure ASP.NET (Remote Object Host)  
Step More Information
Configure ASP.NET to use Windows authentication Edit Web.config in the application's virtual directory.
et the <authentication> element to:
<authentication mode="Windows" />
Disable impersonation Edit Web.config in the application's virtual directory.
Set the <identity> element to:
<identity impersonate="false" />

Using a Windows service host

If you are using a Windows service host process, you must create a Windows account to run the service. This security context provided by this account will be used by the remote object for all local and remote resource access.

To access a remote Microsoft SQL Server™ database (using Windows authentication), you can use a least privileged domain account, or use a least privileged local account and then create a duplicated account (with the same user name and password) on the database server.

Secure Communication

Secure communication is related to guaranteeing the integrity and confidentiality of messages as they flow across the network. You can use a platform-based approach to secure communication and use SSL or IPSec, or you can use a message-level approach and develop a custom encryption sink to encrypt the entire message, or selected parts of a message.

Platform Level Options

The two platform-level options to consider for securing the data passed between a client and remote component are:

  • SSL
  • IPSec

If you host remote objects in ASP.NET, you can use SSL to secure the communication channel between client and server. This requires a server authentication certificate on the computer that hosts the remote object.

If you host remote objects in a Windows service, you can use IPSec between the client and host (server) computers, or develop a custom encryption sink.

Message-Level options

Due to the extensible nature of the .NET Remoting architecture, you can develop your own custom sinks and plug them into the processing pipeline. To provide secure communication, you can develop a custom sink that encrypts and decrypts the message data sent to and from the remote object.

The advantage of this approach is that it allows you to selectively encrypt parts of a message. This is in contrast to the platform-level approaches that encrypt all the data sent between client and server.****

Note   In .NET Framework 2.0, both HTTP channel and TCP channel support SSPI encryption, which can be used for secure communication.

More information

For more information about SSL and IPSec, see Chapter 4, Secure Communication.

Choosing a Host Process

Objects that are to be accessed remotely must run in a host executable. The host listens for incoming requests and dispatches calls to objects. The type of host selected influences the message transport mechanism called a channel. The type of channel that you select influences the authentication, authorization, secure communication, and performance characteristics of your solution.

The HTTP channel provides better security options, but the TCP channel provides superior performance.

You have the following main options for hosting remote objects:

  • Host in ASP.NET
  • Host in a Windows Service
  • Host in a Console Application

Recommendation

To take advantage of the security infrastructure provided by ASP.NET and IIS, it is recommended from a security standpoint to host remote objects in ASP.NET. This requires clients to communicate with the remote objects over the HTTP channel. ASP.NET and IIS authentication, authorization, and secure communication features are available to remote objects that are hosted in ASP.NET.

If performance (and not security) is the primary concern, consider hosting remote objects in Windows services.

Hosting in ASP.NET

When you host a remote object in ASP.NET:

  • The object is accessed using the HTTP protocol.
  • It has an endpoint that is accessible by a URL.
  • It exists in an application domain inside the ASP.NET worker process.
  • It inherits the security features offered by IIS and ASP.NET.

Advantages

If you host remote objects in IIS, you benefit from the following advantages:

  • Authentication, authorization, and secure communication features provided by IIS and ASP.NET are immediately available.
  • You can use the auditing features of IIS.
  • The ASP.NET worker process is always running.
  • You have a high degree of control over the hosting executable through the <processModel> element in Machine.config. You can control thread management, fault tolerance, memory management, and so on.
  • You can create a Web services façade layer in front of the remote object.

Disadvantages

If you use ASP.NET to host remote objects, you should be aware of the following disadvantages:

  • It requires the use of the HTTP channel which is slower than the TCP channel.
  • User profiles are not loaded by ASP.NET. Various encryption techniques (including DPAPI) may require user profiles.
  • If the object is being accessed from code running in an ASP.NET Web application, you may have to use Basic authentication.

Hosting in a Windows Service

When you host a remote object in a Windows service, the remote object lives in an application domain contained within the service process. You cannot use the HTTP channel and must use the TCP channel. The TCP channel supports the following security features:

  • Authentication Features

    You must provide a custom authentication solution. Options include:

    • Using the underlying authentication services of the SSPI. You can create a channel sink that uses the Windows SSPI credential and context management APIs to authenticate the caller and optionally impersonate the caller. The channel-sink sits on top of the TCP channel. The SSPI in conjunction with the TCP channel allows the client and server to exchange authentication information. After authentication the client and server can send messages ensuring confidentiality and integrity.
    • Using an underlying transport that supports authentication, for example, named pipes. The named pipe channel uses named pipes as the transport mechanism. This provides authentication of the caller and also introduces Windows ACL-based security on the pipe and also impersonation of the caller.

    Note   The named pipe channel is provided as a built-in channel known as IpcChannel in .NET Framework 2.0.

  • Authorization Features

    Authorization is possible only if you implement a custom authentication solution.

    • If you are able to impersonate the user (for example, by using an underlying named pipe transport), you can use WindowsPrincipal.IsInRole.
    • If you are able to create an IPrincipal object to represent the authenticated client, you can use .NET roles (through principal permission demands and explicit role checking using IPrincipal.IsInRole)
  • Secure Communication Features

    You have two options:

    • Use IPSec to secure the transport of data between the client and server.
    • Create a custom channel sink that performs asymmetric encryption. This option is discussed later in this chapter.

Advantages

If you host remote objects in Windows services, you benefit from the following advantages:

  • High degree of activation control over the host process
  • Inherits the benefits of Windows service architecture
  • No need to introduce IIS on your application's middle tier
  • User profiles are automatically loaded
  • Performance is good, as clients communicate over the TCP channel using binary encoded data

Disadvantages

If you use a Windows service to host remote objects, you should be aware of the following disadvantages:

  • You must provide custom authentication and authorization solutions.
  • You must provide secure communication solutions.
  • You must provide auditing solutions.

Hosting in a Console Application

When you host a remote object in a console application, the remote object lives in an application domain contained within the console application process. You cannot use the HTTP channel and must use the TCP channel.

This approach is not recommended for production solutions.

Advantages

There are very few advantages to this approach, although it does mean that IIS is not required on the middle tier. However, this approach is only recommended for development and testing and not for production environments.

Disadvantages

If you host remote objects in a custom executable, you should be aware of the following disadvantages:

  • The host must be manually started and runs under the interactive logon session (which is not recommended).
  • There is no fault tolerance.
  • You must provide custom authentication and authorization.
  • There is no auditing capability.

Remoting vs. Web Services

.NET offers many different techniques to allow clients to communicate with remote objects including the use of Web services.

If you need interoperability between heterogeneous systems, a Web services approach that uses open standards such as SOAP, XML, and HTTP is the right choice. On the other hand, if you are creating server to server intranet-based solutions, remoting offers the following features:

  • Rich object fidelity because any .NET type (including custom types created using Microsoft C#® development tool and Microsoft Visual Basic® .NET development system) can be remoted.

    This includes classes, class hierarchies, interfaces, fields, properties, methods and delegates, datasets, hash tables, and so on.

  • Objects may be marshaled by value and by reference.

  • Object lifetime management is lease-based.

  • High performance, particularly with the TCP channel and binary formatter.

  • It allows you to construct load balanced middle tiers, using network load balancing.

Table 11.2. The major differences between remoting and Web services

Remoting Web Services
State full or stateless, lease-based object lifetime management All method calls are stateless
No need for IIS
(Although hosting in IIS/ASP.NET is recommended for security)
Must have IIS installed on the server
All managed types are supported Limited data types are supported. For more information about the types supported by ASP.NET Web services, see the .NET Framework Developer's Guide on MSDN.
Objects can be passed by reference or by value Objects cannot be passed
Contains an extensible architecture not limited to HTTP or TCP transports Limited to XML over HTTP
Can plug custom processing sinks into the message processing pipeline No ability to modify messages
SOAP implementation is limited and can only use RPC encoding SOAP implementation can use RPC or document encoding and can fully interoperate with other Web service platforms.

For more information, see the "Message Formatting and Encoding" section of the Distributed Application Communication article on MSDN.

Tightly coupled Loosely coupled

Summary

.NET Remoting does not provide its own security model. However, by hosting remote objects in ASP.NET and by using the HTTP channel for communication, remote objects can benefit from the underlying security services provided by IIS and ASP.NET. In comparison, the TCP channel and a custom host executable offers improved performance, but this combination provides no built-in security.

  • If you want to authenticate the client, use the HTTP channel, host in ASP.NET, and disable Anonymous access in IIS.

  • Use the TCP channel for better performance and if you don't care about authenticating the client.

  • Use IPSec to secure the communication channel between client and server if you use the TCP channel. Use SSL to secure the HTTP channel.

  • If you need to make trusted calls to a remote resource, host the component in Windows service and not a console application.

  • IPrincipal objects are not passed across .NET Remoting boundaries. You could consider implementing your own IPrincipal class that can be serialized. If you do so, be aware that it would be relatively easy for a rogue client to spoof an IPrincipal object and send it to your remote object. Also, be careful of IlogicalThreadAffinitive if you implement your own IPrincipal class for remoting.

  • Never expose remote objects to the Internet. Use Web services for this scenario.

    .NET Remoting should be used on the intranet only. Objects should be accessed from Web applications internally. Even if an object is hosted in ASP.NET, don't expose them to Internet clients, as clients would need to be .NET clients.

patterns & practices Developer Center

Retired Content

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

© Microsoft Corporation. All rights reserved.