Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Authorization Security Model in Web Applications Using .NET Attributes

4.00/5 (5 votes)
26 Jul 2008CPOL5 min read 1   242  
This article talks about the authorization security model in Web applications using .NET attributes.

Introduction

Security in web applications is something necessary nowadays; especially because everyday attacks are in increase. But in this article, we are not going to discuss the authentication of a web application, we are going to discuss a simple and powerful way for authorization instead.

Background

In the Web Application Security Model, there are two essential terms in use: Authentication and Authorization; it's very necessary to differentiate between the two.

Authorization is the mechanism in which systems securely identify users to know who the user really is and if the user is whom he is claiming he is.

Authentication is the mechanism in which systems determine what level of access an authenticated user should have to secured resources in the system. And this includes: accessing resources and performing operations.

This article focuses on authorization. As there are a lot of ways for authorization (we are not going to discuss them in this article), we are going to discuss one of them in this article, which is using .NET Attributes.

Using the code

A .NET attribute is a class that can be used on the header of another class, method, delegate, property, etc ... and it should be inheriting from the class System.Attribute. We will create our own attribute as follows:

C#
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

/// <summary />
/// Summary description for PrivilegedObjectAttribute
/// </summary />
[AttributeUsage(AttributeTargets.Class | 
         AttributeTargets.Method, AllowMultiple = false)]
public class PrivilegedObjectAttribute : System.Attribute
{
    private string m_PrivilegeCode;

    public string PrivilegeCode
    {
        get { return m_PrivilegeCode; }
        set { m_PrivilegeCode = value; }
    }

    public PrivilegedObjectAttribute(string privilegeCode)
    {
        m_PrivilegeCode = privilegeCode;
    }
}

This attribute class will be used with classes and methods. Surely, you can identify more of these if you want, but for the purposes of this sample, we will have just these two.

The AllowMultiple property indicates whether we can use more than one attribute on each class or method, we will be using only one privilege for each class or method.

Note that we have a simple privilege object which will only have the privilege code attribute as a string, which we will use.

Next, we will use the BasePage class for pages and BaseUserControl for User Controls. BasePage inherits from the System.Web.UI.Page class, and each page in the application we want to apply the privileges to should inherit from the BasePage class. This is for code reuse and so that the same code will handle the authorization of all pages.

The most important thing in the BasePage is the OnInit method; we will override this method to include our authorization code, and the BasePage will look something like this:

C#
public class BasePage : Page
{
    protected override void OnInit(EventArgs e)
    {
        base.OnInit(e);

        //Get User ID
        int userID = SecurityHelper.UserID;

        //Get Current Page Privilege
        string pagePrivilegeCode = SecurityHelper.GetPrivilegeCode(this);

        //If the page doesnt have a privilege code you can either make it 
        ///accessilbe by default (which we will use here) or not accessible
        if (!string.IsNullOrEmpty(pagePrivilegeCode))
        {

            //Does the Current User Has the privilege
            bool authorized = 
              SecurityHelper.UserHasThePrivilege(userID, pagePrivilegeCode);

            //Raise Authorization Decision
            SecurityHelper.RaiseAuthorizationDescision(this, authorized);
        }
    }
}

Now, once a user needs authorization, when asking for a page in the application, he will enter the base page of that page first, and there he will be asked for authorization information. This is done in the OnInit life cycle of the page.

Now to apply a privilege on a certain page, for example, the HumanResources.aspx page, the code-behind of the page will look something like this:

C#
[PrivilegedObject ("PRV_HUMANRESOURCES")]
public partial class HumanResources : BasePage
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }
}

Note the usage of the PrivilegedObject attribute. It takes a string as a parameter, which will indicate the privilege of the page. Of course, you can use an enum instead of a string, for example. And, note that each page has its own privilege and only one privilege. Authenticated users should have these privileges stored in the database, for example, so when adding a new page with a new privilege, you have to add that privilege to the database as well so that admin users can map that privilege to normal users.

To summarize, the Authorization mechanism by .NET happens as follows:

  • Get the authenticated User ID (to get his privileges later)
  • Get the current page privilege
  • Return a value of whether the current user has the privilege
  • Raise the authorization decision, which is taken by specifying the authorization object (a page) and the authorization result (authorized or not)

The RaiseAuthorizationDecision method either makes the current page accessible or not. If the user is not authorized, then you can redirect the user to the AccessDenied page:

C#
public static void RaiseAuthorizationDescision(object authorizationObject, bool authorized)
{
    if (!authorized)//Not Authorized
    {
        if (authorizationObject is Page)
        {
            Page currentPage = authorizationObject as Page;

            //Do Something like redirect the user to the AccessDenied Page
            currentPage.Response.Redirect("AccessDenied.aspx?BackUrl=" + 
            currentPage.Server.UrlEncode(currentPage.Request.UrlReferrer.PathAndQuery));
        }
        else if (authorizationObject is UserControl)
        {
            UserControl currentControl = authorizationObject as UserControl;

            //Do Something like redirect the user to a security information 
            //page which will explain why he is not accessable

            //...
            //...
        }
    }
}

In the AccessDenied page, there will be a link to redirect the user back to the page he was in before his authorization was declined:

C#
public partial class AccessDenied : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }

    protected void btnBackUrl_Click(object sender, EventArgs e)
    {
        string backUrl=this.Request.QueryString ["BackUrl"];
        this.Response.Redirect(backUrl);
    }
}

The same concept almost applies for User Controls. The main difference is the action taken when the user is not authorized. You probably want to make the User Control invisible for the user on that page, or do whatever you think is appropriate for your application.

Points of interest

There are a few points you should take care of when implementing this model of authorization:

  • Non-privileged pages: if you add a page that inherits from the BasePage class but you did not apply the PrivilegedObject attribute to it, then you have two options: either make that page accessible by default or non-accessable by default, for me, I think I will treat it to be accessable by default
  • Static pages and dynamic Pages: in this example, we talked so far about static pages, or static page functions in which the page only does a specific operation, or view, or something like that, instead of dynamic pages in which the contents of a page will vary dynamically depending on some kind of business logic - in this case, the privileged page will control all the operations in the page, so you have to figure out some way to control it depending on your business in that page, or use User Controls to grant dynamic privileges.

Summary

This authorization model is just one of a lot of other authorization models that exist or that you could think of, but I think there is some kind of simplicity and clarity in using this model. Definitely, you could add and enhance this model to suit your business. I have used this model and I have simplified this foe the purposes of this article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)