Securing ASP.Net Applications

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
Rating: 4 stars4 stars4 stars4 stars4 stars / 10
December 14, 2005
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

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.

Impersonation, Delegation and Roles: Understanding the Terminology

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.

Authentication Modes: Validating Claims

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:

<configuration>
   <system.web>
      <authentication mode = "Forms">
         <forms name="TestCookie" loginUrl="LoginForm.aspx" />
      </authentication>
   </system.web>
</configuration>

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.

Forms Authentication in the Real World

I will start with the login form. It uses a code behind page to do the processing. So the first thing we need to do is set the code behind page.

<%@ Page Language="C#" % Src=”Login.cs”%>

Once that is done, the page is designed as a normal page. The username text field is named as txtUser and the password field is txtPassword.

In the Login.cs begin by declaring the namespace:

namespace Auth
{
          :
          :
}
next do the required imports:
namespace Auth
{
  using System;
  using System.Collections;
  using System.ComponentModel;
  using System.Web;
  using System.Web.SessionState;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using System.Web.UI.HtmlControls;
         
:
          :
}

Next, start defining the class:

namespace Auth
{
  using System;
  using System.Collections;
  using System.ComponentModel;
  using System.Web;
  using System.Web.SessionState;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using System.Web.UI.HtmlControls;
       public class CodeBehind : System.Web.UI.Page
            {
    :
                :
            }
}

And in the button click event, do the checking:

namespace Auth
{
  using System;
  using System.Collections;
  using System.ComponentModel;
  using System.Web;
  using System.Web.SessionState;
  using System.Web.UI;
  using System.Web.UI.WebControls;
  using System.Web.UI.HtmlControls;
       public class CodeBehind : System.Web.UI.Page
          {
               public System.Web.UI.WebControls.Label Message;
                 public System.Web.UI.HtmlControls.HtmlTable tblSignIn;
               public System.Web.UI.WebControls.TextBox txtLogin;
               public System.Web.UI.WebControls.TextBox txtPassword;
               public System.Web.UI.WebControls.Button btnSignIn;//the web            //controls
               protected void btnSignIn_Click(Object obj, EventArgs e)
    {
      if(Page.IsValid)
      {
         // check username/password against a database table
         SQLConnection conn = new
         SQLConnection("server=localhost;uid=sa;pwd=;database=CodeBehind");
         // get row back based on username/password
         string strSQL = "Select * From Users Where UserId='" +
                         txtUser.Text + "' And Password = '" +
                         txtPassword.Text + "'";
         SQLDataSetCommand dsc = new SQLDataSetCommand(strSQL, conn);
         // populate a dataset with the SQL results
         DataSet ds = new DataSet();
         dsc.FillDataSet(ds, "Users" );
         // check to see if the dataset contains no rows (if it is EOF (i.e.
         //    contains no rows), then the user is invalid)
         if( ds.Tables["Users"].Rows.Count == 0 )
         {
           Message.Text = "Invalid User Name and Password. Try Again.";
         } else    {
           FormsAuthentication.RedirectFromLoginPage(txtUser.Text,
                                                   false);
         }
       }
    }
           }
}

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:

FormsAuthentication.RedirectFromLoginPage(txtUserName.Text, false);

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:

<configuration>
   <system.web>
      <authentication mode = "Forms">
         <forms name="TestCookie" loginUrl="LoginForm.aspx" />
      </authentication>
   </system.web>
</configuration>

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.

blog comments powered by Disqus
ASP.NET ARTICLES

- Implementing ASP.NET 4.0 Page.MetaDescriptio...
- ASP.Net Development Tips
- Intro to Sessions in ASP.Net
- Google Maps API Introduction in ASP.NET usin...
- Creating an ASP.NET 3.5 Gridview Image Galle...
- Encrypt QueryString in ASP.NET 3.5 using VB....
- ASP.NET 3.5 Drop Down List Controls
- Connect to Access Database with ASP.Net
- Secure Audio Streaming with ASP.Net and Flash
- Dynamic Sitemap and Navigation in ASP.Net
- Implement Gzip and Deflate Compression in AS...
- Run ASP.Net in Ubuntu with Apache
- ASP.Net Mono Website Contact Forms
- ASP.Net URL Rewriting Methods
- Murach`s ASP.NET 4 Web Programming with C# 2...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
 
 
 

ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 3 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials