In this article

Design and Implementation Guidelines for Web Clients

07/28/2010

27 minutes to read

In this article

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

November 2003

Applies to: Microsoft .NET Framework ASP.NET

Contents

In This Appendix

Securing the Presentation Layer

Performing Operational Management

Summary

In This Appendix

This appendix describes security and operational issues relating to the presentation layer. It includes the following sections:

Securing the Presentation Layer

Performing Operational Management

Security is a necessary consideration in most industrial-strength solutions to preserve the integrity and privacy of data as it passes over the network, and also to protect resources and business intelligence at the host.

Operational management is also a vital issue to make sure that applications are deployed correctly and run effectively.

The presentation layer provides specific threats and risks to the security of your application. You must take care to secure it against these threats. Consider the following guidelines when thinking about presentation layer security:

Rely on proven and tested security solutions based on industry-proven algorithms instead of creating custom solutions.

Assume all external systems that your application accesses are insecure.

Apply the principle of least privilege to the users of the system and hide functionality from those who do not have authorization to use a particular feature.

If your application supports multiple user interfaces and client types, make sure you enforce a suitable security baseline across all interface and client types.

Aim to stop unauthorized actions in the presentation layer before any process penetrates deeper into the application.

The following sections describe presentation-layer specific issues relating to the following aspects of application security:

Achieving Secure Communications

Performing Authentication

Performing Authorization

Using Code Access Security

Implementing Security Across Tiers

Auditing

Applying the guidance in these sections may help you to design and implement secure presentation layer solutions.

Achieving Secure Communications

Exchanging data over exposed networks, such as the Internet, introduces risks to the security of your communications. If your application processes sensitive data—such as credit card details or medical records—you must implement mechanisms to make sure of the secrecy and integrity of the data as it travels between application components.

Whether your presentation layer supports Web- or Windows-based clients, there are a number of widely used secure communications solutions available to you. These solutions are typically implemented by the underlying software or hardware infrastructure where your application runs. This means your application transparently gains the benefits of secure communications without the requirement to implement secure communications mechanisms at the application level. The most common secure communications solutions are shown in Table A.1:

Despite the availability and widely acknowledged success of these solutions, your application may demand different or additional levels of secure communications. Some examples include:

Using message authentication codes to ensure data integrity

Using digital signatures to ensure data integrity and support non-repudiation

Using data encryption to provide end-to-end privacy of application data

You typically have to implement these features in your application, and the presentation layer is a common place to implement them. The .NET Framework provides cryptographic classes that support symmetric and asymmetric encryption, hashing, digital certificates, and key exchange. These cryptographic solutions are common to Windows and Web programming. Your selection of a cryptographic solution depends on the specific requirements of your application.

Performing Authentication

The purpose of authentication is to securely establish the identity of a person who wants to use your application. Authorization and auditing require authentication. The most common authentication technique on the Windows platform is the use of user names and passwords (using built-in Windows authentication or a mechanism such as Microsoft .NET Passport.) However, other mechanisms, such as smart cards, biometrics, and digital certificates, are gaining in popularity as they become more accessible and easier to implement. This is especially true in applications that require higher levels of security.

The techniques you use for authentication vary, depending primarily on whether you are creating a Windows-based or Web application. In both instances, there are operating system-provided mechanisms that are transparent to your application. Of course, you can implement a custom application-level authentication mechanism; however, implementing a secure and reliable authentication scheme is not trivial. Where possible, use the mechanism the operating system provides.

For .NET Framework applications, the result of authentication is an identity object and a principal object associated with each thread that the runtime can use to make authorization decisions.

Identityobject–An identity object implements the IIdentity interface and provides run-time information about the owner of the currently executing thread.

The IsAuthenticated property in the IIdentity object indicates whether the user has been authenticated, and the AuthenticatedType property returns the authentication type as a string (for example, "Basic" or "NTLM"). There is also a Name property (this provides the name of the current user); if the user hasn't been authenticated, this is an empty string (""). You can use these details to decide whether the current user can access a particular resource or execute a particular piece of code.

The .NET Framework defines a GenericIdentity class that you can use for most custom logon scenarios and a more specialized WindowsIdentity class that you can use if you want your application to use Windows authentication.

Principalobject–A principal object implements the IPrincipal interface and stores the roles associated with the current user. The IPrincipal object can then be used to authorize or reject access to particular resources.

The IPrincipal interface has an Identity property; this returns an IIdentity object that identifies the current user. The IPrincipal interface also has an IsInRole method; this enables you to perform role-based checks to grant or deny access to a particular resource (or piece of code) depending on whether the current user is in a certain role. Principals allow fine-grained authorization checks at a very detailed programmatic level.

The .NET Framework defines GenericPrincipal and WindowsPrincipal classes to use with the GenericIdentity and WindowsIdentity classes described earlier.

IIS supports a variety of authentication mechanisms. Use the following guidelines to help you decide when to use these mechanisms:

Anonymous authentication–Anonymous authentication is effectively synonymous with "no IIS authentication." Under Anonymous authentication, the IIS server creates a guest account to represent all anonymous users. By default, the anonymous account has the name IUSR_COMPUTERNAME, where COMPUTERNAME is the NetBIOS name of the computer at install time.

Anonymous authentication is appropriate if you want to allow unfettered access to resources, and it offers the best performance because the authentication overheads are minimal. Another scenario where Anonymous authentication is appropriate is if you want to perform your own custom authentication.

If you enable Anonymous authentication, IIS always attempts to authenticate the user with Anonymous authentication first, even if you enable additional authentication methods. You can change the account that is used for Anonymous authentication in IIS Manager. You can also change the security settings for the IUSR_computername account in Windows by using the Group Policy Manager snap-in of the Microsoft Management Console (MMC); when you change the IUSR_computername account, the changes affect every anonymous HTTP request that a Web server services.

Basic authentication–Basic authentication is part of the HTTP specification; therefore it is supported by most browsers. Basic authentication requires the user to supply credentials—a user name and password—so that IIS can prove the user's identity. If a user's credentials are rejected, Internet Explorer displays an authentication dialog box to re-enter the user's credentials. Internet Explorer allows the user three connection attempts before failing the connection and reporting an error to the user.

The user's credentials are submitted in unencrypted format; a network snooper can easily intercept the packets and steal these details. Therefore, use Basic authentication only in conjunction with SSL/TSL to ensure secure communication between the client and the IIS server. For more information, see "Achieving Secure Communications" earlier in this chapter.

Digest authentication–Digest authentication was first introduced in IIS 5.0 as an enhancement to Basic authentication. The user's credentials are hashed before they are transmitted to the IIS server instead of being transmitted in clear text. To enable Digest authentication, the user and the IIS server must be part of the same domain, and the user must have a Windows user account stored in Active Directory on the domain controller. Additionally, the domain controller and the IIS server must be running Windows 2000 or later.

Integrated Windows authentication–Integrated Windows authentication relies on an encrypted exchange of information between the client and the IIS server to confirm the identity of the user. Unlike Basic authentication, Integrated Windows authentication does not initially prompt for a user name and password; the current Windows user information on the client computer is used for Integrated Windows authentication.

Integrated Windows authentication is either provided by Kerberos or NTLM (Windows NT LAN Manager) Challenge/Response, depending on the client and server configuration: Kerberos is used if the domain controller is running Windows 2000 or later and Active Directory Services is installed; NTLM authentication is used in all other cases.

Certificate authentication–Certificate authentication relies on the user submitting a client certificate to the IIS server to prove the user's identity. The user obtains this client certificate from a Certification Authority (CA). At the IIS server, you must create a client certificate map to map client certificates to particular Windows user accounts; this enables IIS to test the client's certificate to verify that it corresponds with a recognized and authenticated user. When the user submits his or her certificate, it means IIS does not have to perform Basic, Digest, or Integrated Windows authentication to identify the user.

In addition to the security mechanisms provided by IIS, ASP.NET provides its own security mechanisms as follows:

Both Forms and .NET Passport authentication require significantly more effort to implement than IIS-based authentication; however, they are the only workable solutions if you have an Internet-facing Web application and do not want to establish Windows accounts for every user.

Performing Authorization

Authorization is the process of determining whether a user has permission to access a particular resource or piece of functionality. To perform authorization, you must have an authentication mechanism in place to establish the identity of the user, and that mechanism must determine the identity of the user accurately and reliably.

In .NET Framework applications, authorization is generally based on two pieces of information associated with the active thread:

The Windows access token

The IPrincipal object

The Windows access token represents the capabilities of the active Windows account. In smart client applications, such as Windows Forms applications, this is generally the currently logged on user. In server-based applications, such as ASP.NET, this is generally a special service account configured to run the application; for example, the default account named for ASP.NET is named ASPNET. Windows uses the access token to determine whether the current thread can access resources and functionality secured at the operating system level.

The IPrincipal object is an application-level object that represents the identity and roles of the current user. Application code can use the IPrincipal object to make authorization decisions based on the roles of the active user. Frequently, the IPrincipal represents the same user as the Windows access token; however, applications can change the IPrincipal relatively easily to represent a different user. This is most frequently done in server applications to represent the user connected to the server instead of the account that the server service is running as.

Using Code Access Security

Code access security is a security feature that applies to all .NET Framework managed code to protect computer systems from malicious code and to provide a way to allow mobile code to run safely.

You will have to consider the ramifications of code access security in the following scenarios:

You are designing browser-hosted controls

You are hosting third-party applications

You are hosting assemblies from different vendors on a shared server

You want to prevent certain native functions, such as file write APIs, to be available to certain assemblies

Code access security allows code to be trusted to varying degrees, depending on factors such as where the code comes from and its strong assembly name. Code access security enables you to specify the operations your code can perform and the operations your code cannot perform.

Code access security supports a permission support mechanism where code can explicitly request particular permissions and explicitly refuse others that it knows it never requires. Each permission represents the right for code to access a protected resource such as a file, directory, or registry entry, or the right for it to perform a protected operation such as calling into unmanaged code. Permissions can be demanded by code and the run-time security policy determines which permissions to grant.

The .NET Framework allows administrators to assign a pre-defined set of permissions to an application. For example, applications running on a UNC share (running in the Intranet security zone) receive the LocalIntranet permission set. Applications running on the local computer (running in the MyComputer security zone) receive the FullTrust permission set.

ASP.NET Web applications can be configured by assigning them trust levels. Trust levels are configured using the <trust> element in the configuration file.

Each level determines the application's permissions; an XML security policy file specifies the details of these permissions. Each level maps to a specific file. The default mappings for ASP.NET are:

Full–This trust level has no associated configuration file. Full trust allows applications to use all resources (subject to operating system permissions); this is just like running without code access security (although code access security cannot be switched off for managed code).

High–This trust level maps to web_hightrust.config. This trust level provides permissions that grant applications read/write access to the application directory (subject to operating system permissions) and allows the application to replace the authentication principal object.

Medium–This trust level maps to web_mediumtrust.config. This trust level provides permissions that grant applications read/write access to the application directory (subject to operating system permissions) and allows the application to replace the authentication principal object.

The restrictions listed for the high trust level also apply to the medium trust level. Additionally, file access is restricted to the current application directory, and registry access is not permitted.

Low–This trust level maps to web_lowtrust.config. This trust level allows applications to read from the application directory and provides limited network connectivity. Applications can connect back to their host site, assuming the originUrl attribute of the <trust> element is configured appropriately.

The restrictions listed for the medium trust level also apply to the low trust level. Additionally, the application is not able to connect to SQL Server data sources or call the CodeAccessPermission.Assert method.

Minimal–This trust level maps to web_minimaltrust.config. In this trust level, only the execute permission is available.

You can override these mappings in the <securityPolicy> element of the configuration file, and you can customize and extend each level. You can also create your own levels that define arbitrary permission sets. The default <securityPolicy> mapping set is shown in the following example.

ASP.NET configuration is hierarchical in nature, with configuration files optionally at the computer, application, and sub-application levels. Sub-level configuration files can be used to override settings made at a higher level or can be used to add additional configuration information. While this provides a high degree of flexibility, administrators may sometimes want to enforce the configuration settings and not allow them to be overridden by specific applications.

For example, an administrator of a hosted Web site may want to specify the code access security level and not allow it to be changed by individual applications. This can be achieved using the <location> element coupled with the allowOverride attribute. For example, an administrator of a hosted Web site may want to make sure that no applications are permitted to call into unmanaged code. The following configuration file fragment shows how an administrator can lock down the code access configuration settings for a whole site and restrict applications with the High trust level (this does not allow calls into unmanaged code).

The path attribute may refer to a site or a virtual directory, and it applies to the nominated directory and all sub-directories. In the preceding example, if you set allowOverride to "false," you can prevent any application in the site from overriding the configuration settings specified in the <location> element. Note that the ability to lock configuration settings applies to all settings, not just security settings such as trust levels.

Implementing Security Across Tiers

ASP.NET Web applications typically interact with business objects, .NET Framework remoting objects, or some other back-end application. The Web application typically undertakes the responsibility for authenticating and authorizing the user. There are two ways to pass the results of the authentication and authorization to downstream applications:

Trusted subsystem model

Impersonation/delegation model

The following sections describe these models and provide guidance on when to use each model.

Using the Trusted Subsystem Model

The ASP.NET Web application authenticates and authorizes the user at the first point of contact, and it creates a trusted identity to represent the user. By default, the ASP.NET Web application worker process (aspnet_wp.exe) runs using an account named ASPNET.

Whenever the ASP.NET application communicates with downstream applications, it does so using this security context. The downstream applications trust the ASP.NET application to correctly authenticate and authorize the original user.

There are two key benefits of the trusted subsystem model:

Simplicity–Downstream applications have to authenticate only a single user account (that is, the ASPNET account of the ASP.NET application). Moreover, access control lists (ACLs) can be defined in terms of this single trusted identity instead of defining access rights for every authorized user or role.

Scalability–The ASP.NET application always forwards the same security credentials to downstream applications, regardless of the identity of the user who actually contacted the ASP.NET application. This facilitates connection pooling. Connection pooling is an essential requirement for scalability and it allows multiple clients to reuse resources in an efficient manner, as long as the users have the same security context.

For more information, see "How to Use the Trusted Subsystem Model" in Appendix B in this guide.

Using the Impersonation/Delegation Model

In the impersonation/delegation model, the ASP.NET Web application authenticates and authorizes the user at the first point of contact as before. However, these original credentials are flowed to downstream applications instead of passing the same trusted identity for all users. This enables downstream applications to perform their own authentication and authorization tests using the real security credentials of the original user.

There are two key benefits of the impersonation/delegation model:

Flexibility–Downstream applications can perform their own per-user and per-role security checks, using the user's real security context.

Auditing–Downstream applications, and the resources that they access (such as databases), can keep an accurate audit trail of which users have accessed which resources.

Before you use the impersonation/delegation model, you must be aware of the following issues:

Scalability restrictions–Connection pooling is not possible with impersonation/delegation, because each user's original security context is flowed downstream. Connection pooling works only if the same security context is used to access pooled resources.

Complexity–You must define ACLs for particular users and roles instead of being able to express these ACLs in terms of a single trusted identity.

There are two different ways to use impersonation/delegation model, depending on how you initially authenticate the user in the ASP.NET Web application:

Using Kerberos authentication–Kerberos involves authenticating a user with a Windows NT Domain or Active Directory account. For more information about how to perform impersonation/delegation with Kerberos, see "How to: Use Impersonation/Delegation with Kerberos Authentication and Delegation" in Appendix B in this guide.

Using Basic authentication or Forms authentication–Basic authentication is part of the HTTP 1.0 specification; it transmits the user's name and password to the Web server using Base64 encoding. Forms authentication uses HTTP client-side redirection to redirect unauthenticated users to an HTML login form. For more information about how to perform impersonation/delegation with Basic authentication or Forms authentication, see "How to Use Impersonation/Delegation with Basic or Forms Authentication" in Appendix B in this guide.

Use the appropriate impersonation/delegation model, depending on how you initially authenticate the user in your ASP.NET Web application.

Auditing

Auditing of presentation layer activities is generally limited to a small set of global events including:

Users logging on

Users logging off

Sessions timing out

Password changes

Failed logon attempts

Failed authorizations

Failure and success of business processes

You might also decide to audit the business processes initiated by the user in the presentation layer. Having a high-level view of a user's actions can provide useful diagnostic information. However, it is best not to rely on presentation layer auditing to provide the sole audit trail of user activities. Typically, a presentation layer event triggers a series of events in the business and data access layers. To provide the granularity of information required for security auditing, make sure that each of the lower layers audits its own activities.

Aside from what to audit, the most important decision you must make is where to store audit logs. The most appropriate storage location depends on the architecture of your application.

Server-based applications that support thin Windows-based or Web clients generate all audit events at the server. In this scenario, it is easy to manage a handful of servers that write to their local Windows Event Logs. As the number of servers grows, it is better to switch to a centralized audit log. If all servers reside on a private network, the security risks are minimal, and the administrative and operation benefits of a global security log are significant.

Distributed applications that implement significant portions of their functionality in smart client applications might have to audit some presentation layer events on the clients. In these situations, writing to the local Windows Event Log becomes a problem. You must implement a mechanism to pull or push the events from the remote computers to a central store. Although there are tools available to automate this, the approach becomes unmanageable (or at least inefficient) as the number of clients grows. In this scenario, your application can implement a custom auditing service that your presentation layer logic can write audit records to. The service takes responsibility for delivering the audit logs to a central store. When implementing remote auditing mechanisms, consider the following guidelines:

Sign the audit records with a digital signature or message authentication code before sending to ensure data integrity.

Avoid including sensitive information in audit records; if unavoidable, it is a good idea to encrypt the records before sending them. For more information about using the .NET Framework cryptographic classes, see "Achieving Secure Communications" earlier in this chapter.

Use a reliable transport and delivery mechanism to make sure audit records do not get lost.

Make sure operating system security is in place to stop users from deleting audit records before delivery.

Make sure users cannot change the location to where the audit service stores and delivers records.

Regardless of where you store your audit logs, audit records must be immutable and accessible only to authorized people.

The following sections describe specific aspects of operational management to consider when designing your presentation layer:

Managing Exceptions in the Presentation Layer

Monitoring in the Presentation Layer

Managing Metadata and Configuration Information

Defining the Location of Services

Deploying Applications

These sections provide guidance for planning the operational management of your application.

Managing Exceptions in the Presentation Layer

One important point that relates closely to the presentation layer is the issue of unhandled exceptions. As the name suggests, an unhandled exception is one that your application code does not explicitly handle. This might be because the exception represents an unrecoverable error, or perhaps the programmer did not anticipate and code for that type of exception. Whatever the case, these unhandled exceptions occur until they reach the outer boundary of your application, where they appear to the user as a confusing error. Not only is the presentation of a stack trace not useful for a typical user, but it might also provide attackers with useful information they can use to attack your system in the future. It is a good idea to never allow a user to see the raw details of an uncaught exception.

If you are developing Windows Forms-based applications, it is a good idea to implement a catch-all exception handler. For an example of how to do this, see "How to Define a Catch-All Exception Handler in Windows Forms Applications" in Appendix B in this guide.

Monitoring in the Presentation Layer

Implementing the appropriate levels of monitoring to your application allows you to know when things are running smoothly and when problems are encountered.

The types of monitoring to consider for your presentation layer include:

Health monitoring, to determine:

Whether the application is running

If there are errors or other problems that might cause the application to not perform in an optimal manner

Performance monitoring, to determine:

How long the application takes to process a user request

If there are any bottlenecks needing attention

It is also important that you communicate problems affecting application operation to users clearly, effectively, and in a timely manner. Some options for communicating these problems include Windows Management Instrumentation (WMI), writing to the Event Log, or publishing exceptions to isolated storage. As a minimum, display an informative message if your application is down, and include an estimate for when normal operation will resume. Depending on the nature of your application and user base, it may be appropriate to provide application health and status information directly to the users.

Relies on external services that you have to provide location and authentication details for

The .NET Framework supports a range of storage mechanisms to hold application configuration information. Each mechanism has benefits and disadvantages that make it more suitable in certain situations. The most common mechanisms for storing configuration information are listed in Table A.2.

Table A.2: Common Configuration Information Storage Mechanisms

Option

Notes

XML or INI Files

Using XML files to store configuration information provides an easy and standard way to store and read the information.
Include built-in support for files such as Web.config and Machine.config through IConfigurationSectionHandler.Security is provided by Windows ACLs.

Databases (SQL Server, MSDE)

Configuration information is available to multiple computers and applications.
Provide greatest flexibility in terms of the types of data stored and data security.
Require additional infrastructure and ongoing management.

Active Directory

Within an organization, you may decide to store application metadata in Active Directory so that the metadata available for clients on the domain.
Security is provided by Windows ACLs.

Constructor strings

If you are using Enterprise Services–based components, you can add configuration data to the constructor string for the components.

Windows Registry

Your application should store configuration information in the Windows registry only when absolutely necessary, such as when you must work with earlier versions of applications that use the registry.
Storing configuration information in the Windows registry increases the deployment burden of your application.
Configuration information is available to multiple applications on the same computer.
Security is provided by Windows ACLs.

All these mechanisms provide some form of general-purpose administration tools, allowing you to manage your configuration information and configure its security. However, you frequently have to develop your own application-specific utilities to manage your applications configuration data effectively—especially if the configuration data is complex, or if you have to distribute administrative capabilities between different users. The development of usable, high-quality, administrative tools is important to the long-term success of your application and should not be sidelined as a trivial exercise to be done only if there is time.

Note The Configuration Management Application Block available on MSDN (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/cmab.asp) simplifies the storage and retrieval of configuration information. The block allows you store application configuration information in XML files, the Windows registry, or SQL Server and is extensible so that you can add support for other data stores. Additionally, the block supports features such as encryption and message authentication codes to ensure the confidentiality and integrity of your application configuration data.

Defining the Location of Services

If your presentation layer code uses remote objects and XML Web services, make sure that you do not hard code the locations of these services into your code. Doing so reduces the maintainability of your code. If a service address changes, you have to update, rebuild, test, and distribute your application. It is a good idea for service location and authentication information to be stored securely with your other application configuration information. For information about application configuration, see the previous section of this chapter.

Deploying Applications

Deployment is rarely an application-specific decision in medium- to large-sized organizations that have standard application deployment policies and mechanisms owned by operations departments. None of the major application deployment mechanisms require you to implement specific features in your application; however, you can use the following guidelines to simplify application deployment:

If security considerations allow, implement browser-based user interfaces where possible to avoid the requirement to distribute client software to a high number of computers.

Summary

This appendix has described how to secure the presentation layer in ASP.NET Web applications by applying built-in support provided by the IIS, ASP.NET, and the .NET Framework for authentication, authorization, and secure communications. It also described how to perform operational management tasks to enable applications to run smoothly and securely day-to-day.

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.