Security is vital, especially for applications that are used over the Internet. For anything that requires a user to log in, you must be able to ascertain that the user is who he says he is, and is permitted to access the areas he is trying to access. This article explains how to deal with security and authentication issues in ASP.Net applications.
Contributed by A.P.Rajshekhar Rating: / 10 December 14, 2005
Security is the key that not only keeps sensitive data and information locked away from prying eyes, but also enables access to the data discreetly. When the topic of discussion is security, web applications happen to take the spotlight. This truth is evident from the fact that both J2EE and .Net has security features as their core functionality, not as a peripheral function, which was the case until about five to six years ago.
Microsoft, understanding the worries surrounding the security of web applications, has come out with a security model that includes both the existing window’s ACL model and the new Code Access Security (CAS) model. While the CAS model is more used with the stand alone applications, the ACL model, along with the declarative approach, is more suitable for web-based applications. In other words, the approach for ASP.Net is declarative security.
In this article, we will discuss how to put this aspect of ASP.Net to work so that security can be provided without delving into code too much. But before going into the details, it is imperative to understand the terms that recur most in the ASP.Net security model. Hence the first section introduces these terms. Then authentication modes and their configuration will be detailed in the second section. In the last section, I will pull it all together for an example that will explain how code and the declarative approach work together in securing an ASP.Net application.
The basis of ASP.Net security is the philosophy of selectively restricting access to certain sections of the web application. To do this, we depend on certain processes which are:
1. Authentication
2. Authorization
3. Impersonation
4. Delegation
Let's look at these one by one.
1. Authentication:
Whenever a user logs onto the website, it is necessary to verify the credentials provided by him or her. The process of verifying the credentials is known as authentication. It can be as simple as checking the username/password combination against the database -- relational or flat-file based -- or as complex as providing digital certificates.
2. Authorization:
Though the user may be authentic, whether he or she has permission to access different sections of the website/application needs to be verified. The process through which the privileges of a user are checked is known as authorization.
3. Impersonation:
It is sometimes possible that, even though a user doesn’t have certain privileges on the system (other than the system in current domain), ASP.Net can let them assume the role of a user having limited privileges on that system, thus providing limited access to the user.
4. Delegation:
Delegation is the process by which the web server (running the application) is able to access remote resources when impersonation is being done. In other words, delegation is a powerful form of impersonation.
Each of these processes depends in turn on some objects that represent the authentic user, the resource for which authentication or authorization is being performed, and so on. In the terminology of security they are:
1. Principal
2. Identity
3. Credentials
These are normal words associated with security. But when they are discussed in conjunction with ASP.Net, they take the form of interfaces that can be used to gain information regarding the user. Using these, one can programmatically access declaratively configured security parameters. Let's have an overview of these terms:
1. Principal:
Principal relates to the user whose session is currently active. In other words, it relates to an authenticated user. The corresponding interface is IPrincipal. This interface is defined as follows:
public interface IPrincipal
{
bool IsInRole( string role );
IIdentity Identity {get;}
}
The .Net framework provides a number of concrete implementations of the IPrincipal interface. The main thing to keep in mind in the interface is that there is a getter that returns IIdentity. In essence, IPrincipal is implemented to store the roles of the user currently logged on.
2. Identity:
Identity provides additional authentication details. The details include name and authentication type of the user. The interface corresponding to identity is IIdentity, which is as follows:
public interface IIdentity
{
string authenticationType {get;}
bool IsAuthenticated {get;}
string Name {get;}
}
The concrete implementations provide the required type on the basis of authentication being done.
3. Role:
The term role reflects the privileges a user has. These privileges could be resource based or service based. These roles revolve around the IPrincipal object. As the IPrincipal object represents an authenticated user, it is logical that the roles are associated with an object of IPrincipal.
Now that the terminologies have been introduced, let's move to the important aspect of security -- authentication.
As mentioned in the previous section, authentication is the process by which it can be verified whether a user is what he or she claims to be. The process is based on the credentials supplied by the user. The credentials are verified by authenticating authority. The authority can come from Windows NT/2000/XP security or store of names, passwords, and rights, maintained in a flat-file format such as a configuration file (web.config), XML file or a relational database such as SQL Server.
The core of authentication in ASP.Net is in code modules called authenticationproviders. The authenticating systems, or authentication providers as they are known, must be enabled in the configuration files of the application – either the machine.config or web.config. The entry in the configuration files to enable authentication would be as follows:
<configuration>
<system.web>
<authentication mode=auth_type/>
</system.web>
</configuration>
The crux of the configuration is the element <authentication>. Just by changing the mode of the mode attribute of the <authentication> element, the mode of authentication can be changed. It is as simple as that. The real game is understanding the different modes and when to use them. So let's begin by learning about the different modes. There are four modes provided by ASP.Net, which are:
1. None
2. Forms
3. Windows
4. Digest
5. Passport
All these modes refer to the way the authentication takes place.
1. None:
To provide anonymous access, use this mode. This is the default mode. When the mode is None, the user’s credentials are never verified. That is to say no information about the user is gathered and passed on to the IIS server. To configure the application to anonymous mode, use the following code:
<configuration>
<system.web>
<authentication mode="None" />
</system.web>
</configuration>
2. Forms:
In this mode, a login form is used to gather the information from a user when an unauthenticated request comes. The information is then sent to the IIS server via POST. The application contains code that uses the gathered information to verify it against stored user information. The storage can be in the form of relational tables, XML files or the web.config file itself. To set the mode to form use the following code:
The extra tag <form> is required to provide the cookie to be placed for authentication and the login form for gathering required info. I will cover more about this in the next section, where I will create a login form and use it for forms-based authentication.
3. Windows:
Also known as Basic Authentication, it is the least secure type of authentication. When a request arrives for a secured resource, a standard Windows dialog box is displayed, asking for username and password. Then the credentials are matched against the user accounts that are stored either on the local machine (where the server is running) or on the domain server/controller. If the comparison is successful, the user is accepted as authentic. The reason for the insecurity of this mode is that the credentials are passed to the server without encryption. To overcome this, SSL can be used, but performance loss would be the side effect. To use basic authentication change the mode as follows:
<configuration>
<system.web>
<authentication mode="Windows" />
</system.web>
</configuration>
4. Digest:
Digest is same as Windows authentication, but the gathered credentials are encrypted before being passed on to the server. Though the encryption is not as strong as that of SSL, it is stronger than Windows authentication. The encryption mechanism is based on hashing. Before the credentials are passed on to the server, they are hashed to a value on the basis of a string. The server knows the string’s value and thus is able to decrypt the value. To use digest authentication change the mode thus:
<configuration>
<system.web>
<authentication mode="Windows" />
</system.web>
</configuration>
There are no apparent changes to the configuration. To bring the encryption into effect, changes must be made to the user account. The user’s name and password have to be set to reversible encryption. This can be done using the user account tab of the management console for Active Directory users.
5. Passport:
Passport provides single point authentication service to all those who have registered with the Passport service, which is a commercial service provided by Microsoft. It is based on an authentication ticket. Whenever a request is made without the ticket as a part of the query string, the client is redirected to the Passport logon Service. The parameters are encrypted. The user credentials are gathered using a login form and then passed on to the authenticating server. If the credentials are verified, the request is redirected to the originating server. To use the passport service, Passport SDK must be installed on the server. To use it, change the mode to Passport as shown below:
<configuration>
<system.web>
<authentication mode="Passport" />
</system.web>
</configuration>
Now that the modes have been introduced, let's look at a real world example that shows how to use forms authentication.
The user name and password is checked against the database. First the SQL statement is created by the following line:
string strSQL = "Select * From Users Where UserId='" + txtUser.Text + "' And Password = '" + txtPassword.Text + "'";
Then pass it to the database, and execute the query. This is all normal procdure. What is different is the else part, especially the following statement:
If the user is authentic, then he or she is redirected to the next page with the user’s name.The next step is to configure the web.comfig file. That is done by adding the following code:
The name for the cookie is specified by the name attribute. This cookie is used to keep track of the authenticated user. The loginUrl specifies the login form to be shown. That’s all. This brings us to the end of this section.
Parting Thoughts
Securing any ASP.Net application is less code centric and more conceptual. But don’t be fooled by the ease in terms of the code. Keep the following in mind when using the ASP.Net declarative approach for security:
1. Configure the IIS server for maximum security. None of the above mentioned modes would work correctly if the server has been not configured correctly.
2. Don’t provide anonymous access. If at all necessary, keep it to the bare minimum.
3. Last but not least, always keep a backup plan in your code itself. If for some unforeseen reasons, the ASP.Net based authentication fails, you can authenticate by your own methods.
This brings us to the end of this tutorial. In this I have discussed authentication modes. But this is just first step in the journey of securing the web applications. The next step involves authorization. This will be discussed some time in the future. Till next time.