Nov 17, 2009

MVC Custom authorization (part 2)

MVC Forms Authentication and Authorization (membership and custom implementation) part 2

In my
previous article i discussed how to do custom forms authentication with MVC and in short reviewed the membership authentication that comes out-of-the-box. Refer to part 1 for details.

Today i will focus mostly on the authorization. I will reuse the database model exposed in part 1 and i will demonstrate how to build a custom authorize attribute which will server our needs for giving more granular restriction to protect our action methods.

Let's get back to part 1 and to reconsider the way we have implemented authentication process. Does it worth all the bunch of code we developed only for the sake of authenticating the user. Considering that MVC supports this out-of-the-box with membership, I would say – it is up to you to decide. For me – not, period. Still it mostly depends on if you are starting your development from the scratch, or you are faced with integration with developed code.

After we configured and secured our MVC application, we can protect our controllers and our action methods by specifying users and roles who can access the methods. To implement this, we can use either IAuthorizaiton attribute, or its implementation in MVC – Authorize attribute.
The Authorize attribute provides two parameters that can be both used and applied in the same time
• Users - comma separated list of users that are granted with access. Username could be Domain\Username too.
• Roles – comma separated list of roles that a granted with access. It could be Domain\Group from Active Directory.
• No specified parameters – user should be authenticated but he/she can access controller and action methods regardless of his username and role given

If I apply the Authorize attribute to an action method or controller and the user is not authenticated, he will be redirected to the login page on trying to execute the method. The same will happen if the user doesn’t meet values mentioned in Roles and Users parameters if they are specified for the given Authorize attribute.

But, what if we want from now on to build our authorization based on these granular access rights that our database is designed for? In this case our approach overdo the membership, just because it is custom, flexible and extensible the way everybody wants it.

Authorization is pretty much what user can do. One side of this, we can say is what user sees. Let’s make our sample a bit more complicated.
In table Modules we have 3 records – “Administration”, “Importing”, “Invoice”. And we have function rights – “Access”, “Manage Users”, “Manage Invoices”, “Generate Reports” in Functions table. In ModulesFunctions we bind our functions rights to appropriate modules.

Let’s make authenticated users to see only modules which they have been granted access to.

For the sake of the demo I have created user kbochevski who has “Access rights” to “Administration” and “Import module”. I use custom authentication model built in part 1. Also this user has all the other rights that are related to the mentioned modules. All this is configured and hardcoded in “AccessToModuleFunctions” table in database.
Let’s keep the modules and functions records as enums in our code (They are nomenclatures and they are pretty much read only, so this is a good practice. If you choose this approach don’t forget to sync them up with your database changes). Important thing is to put the attribute Flags of our Functions enumeration, since we want its values to be properly treated when doing bit operations against its elements. But we will get back on this later…(Check how our custom attribute has been applied in the given example later)

We will fetch our module access from the database and will store this information in cookie, which we’ll be checked in aspx and based on its value only the appropriate modules will be displayed.

In master page of our application we will iterate through cookie values and will display only elements that we should do.

Since the only way to transport data from server side to client side (aspx) is via ViewDate (and of course TempData), it should be initiated before passing content to the view render engine. That is why the most reasonable solution is to create a base controller class that will do this for us. All controller classes MUST inherit it.

Now, at this particular step we are ready to check what we have done.

You can see, our user sees only the menus (modules) which he has access to. But I would say – don’t rely on this mechanism for restricting access rights. Another user can easily see the url and paste in address bar, and he will be able to see the content he is not supposed to.

The other side (real one) of authorization, literally pertains to what are the restrictions forced to the authenticated users. And this restriction is forced programatically.This pretty much guarantees that nobody will access things that he is not supposed to.

In our case we need analog to the Authorize attribute that comes with MVC out-of-the-box. There are two possible solutions :
1) to implement IAuthorizationAttribute
2) to inherit its implementation class in MVC AuthorizeAttribute

Authorize attribute guarantees us that only authenticated users will be able to execute certain controller methods marked with this attribute.

This approach will work. But is it what we really needed? No. We are pretty much restricted with enumerating Roles and Users. And that is.We need a mechanism which to validate users’ rights based on they access to modules with a specific functions access – manage users, do invoicing….
That is why we do need a custom attribute that should do pretty much the same as Authorize attribute.

In this class we should override the OnAuthorization attribute method. In its implementation we need to do next things:

• check if user is authenticated
• check against database if he has the set rights in database that correspond to the rights set in attirbute on calling
• better once you get the rights save them in session, rather than requesting the database every time

Here is how our attribute applies to action methods:

Let’s see if this works…

Yes it is. I can access my action method which renders desired view.

Now let’s restrain the access. Just modify the database and revoke the access right to this function.

And here is the result:

User obviously doesn't have access right. We can do it more complicated and redirect to specific page, but for the sake of the demo this is quite enough.

You can refer my new article for designing MVC.NET 3 applications, which contains the custom attribute authorization in its code sample here.

To download the source code of the example i built refer:
source code

Well, we reviewed how to do authentication and authorization in MVC, we reviewed what comes with MVC out of the box.
You can mix both approaches whenever you need it.

Read full article!

Nov 16, 2009

MVC Forms Authentication and Authorization (part 1)

MVC Forms Authentication and Authorization (membership and custom implementation)

Today, I want to start my blogging experience with discussion of authentication and authorization in MVC Framework. We will review membership mechanism that comes out-of-the-box with MVC but also we are going to focus on custom implemented forms authentication and access rights management. Nowadays most of the web sites and enterprise intranet applications allow user to store private information and to perform specific, members-only actions.

Since this is a large topic of discussion, I will separate this article in two parts. The first give a short introduction and explanation of membership in MVC and how to do custom forms authentication with MVC. The latter will introduce how to do custom authorization with MVC, and I will mention also what MVC has out-of-the-box for the authorization.

First of all (I know most of the readers are well informed about this) we have to make difference between authentication and authorization process.
  • Authentication is the mechanism with which every user is recognized by the system. It technically answers the question – Who are you?
  • Authorization is completely separate mechanism which indeed is tightly coupled to the authentication. The authorization is about determining the level of access and the very specific things that authenticated user can do, once he is been verified. The authorization process can be described with the question – What can you do, after I already know who you are?

Part 1 Authentication

The MVC framework comes with a native support of forms authentication using membership. When creating a new ASP.NET MVC application, you can notice a default AccountController and associated views that expose classic ASP.NET membership in the ASP.NET MVC framework. In addition Visual Studio provides a tool which makes easier the management of the roles and the users.

Still few things should be done before start exploring the membership mechanism and .NET Membership namespace. You should create the MS SQL database used by membership providers prior to start integrating with MVC.

Since membership is presented in .NET Framework 2.0 and there are lots of articles describing how to do step by step, I will just mention the base steps. For any additional info, just google and you will find out plenty of articles on this topic.
You can refer to

  • Run C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727>aspnet_regsql.exe
  • If we don’t give a name to the database it creates default name aspnetdb
  • Go to web config of your MVC application and set the connections string

  • MVC has this connection string and it comes with the project template.
    • Build your application
    • Open Web Site Administration Too: Project-> ASP.NET Configuration and manage your roles and users

    If you give another name to the database, different than “aspnetdb”, go to your web.config and change the connection string.

    MVC project comes with membership integration and membership authentication implemented. You can see the AccountController and views in Views\Account folder. There are forms for registering, changing password, logging on, etc. You can enhance whatever you like as long as you can do your code behind job with membership provider.

    Membership mechanism that comes with MVC out-of-the-box is good, but sometimes you most likely will need to omit usage of roles, or you will need more granular rights that you should grant to authenticated users, or you will be forced by the circumstances to use custom authentication that is already implemented (at least to DB design level). In some cases you can still use membership by creating new roles via Web Site Administration tool and assigning new users to these specific roles (or just create new users). Yes, this can spare you the development of amend forms for users and roles management, but long term it is pretty restricted solution. Doing this, you will easily end up with controller’s attributes containing dozen of roles or users, which should serve bunch of custom specific access rights.
    If you face a situation in which you should do your authorization based on groups (roles) that envelops more granular rights, your solution definitely requires custom authorization attributes. Fortunately MVC framework relies on a highly extensible and pluggable architecture. Just because this modular architecture we can easily create AuthorizeAttribute. I will talk more about this in my second article.

    Let’s do things step by step.
    First we need to create our little sample database with few tables that should serve accounts and the access rights to these accounts.

    Here is a brief description of the tables:
    • Users – contains the users that will have access to application
    • Roles – contains the roles, a user can participate in one or zero roles
    • Functions – contains the granular rights that every user may have for particular module
    • Module – contains the modules list
    • ModulesFunctions – contains the association between module and functions. It pretty much describes what are the things (functions) that can be done in every module
    • AccessToModuleFunctions – contains association between user and roles and the access that they have with specific rights for specific module.

    Now we can develop the custom forms cookie based authentication. Below are the major steps that we need to complete:

    1) Create Authentication controller and authentication view. If you want to have separated and dedicated view for logging only, it should be outside of the context of the master pages. In this case make sure that you deselect the “Select master page” checkbox. If you don’t this, your logging page will be displayed in the context of its master, and you will most likely end up with hiding some menus and controls if your user is not been authenticated yet. That is why the simplest solution is to create one brand new page which you will be your logging page.

    2) Now we need to modify our web.config file and our global.asax file to say that our new web form is first one that user should see.

    If you run your application you will see it works.

    3) Well, at this point we are pretty much ready to start with “real” development and making our application read users from the database and authenticate them.
    We are about to create a new class library application which will be our database layer based on Linq to Entities. Just add new item to the project – ADO.NET Entity Data Model. Make the connection to database and fetch all the tables you will need.

    Add your class library as reference project to your MVC project. One thing that worths statiting – add a connection string in your web config of the MVC application in order to be able to instantiate the context without providing connection string.

    I will mention few major consideraitons that I think are important when you make custom authenticaiton:
    • Never store user’s credentials in plain text. You can develop some class that does encryption of password. In my example I use RNGCryptoServiceProvider and FormsAuthentication classes.
    • Create some session management for tracking expiration of your credential. This is especially important if you have validation for not allowing user to log in if he is marked as currently logged in, if you keep history of visits in your site, etc…Possible solutions might be – storing credentials in cache and invalidating them (plus SQL job for cleaning your database if something screws up), storing sessions in database, inproc, state service, etc.
    • Create your own class for storing user’s data rather than fetching it every time you need it from database. You can do this in global.asax.

    In order to store your credentials in the context, you should create a class that implements IPrinciple interface.

    Beside developing code in global.asax, in your login controller method you should pass the credentials in order to be authenticated. After you validate that user extists in your database, you can pass his credentials using FormsAutneticaitonTicket class.

    I will skip the rest of the boring stuff related to how to use Linq and how to write methods. Technically you can create an action method in your AuthenticateController which will get the input and do the validation of the passed credentials. I will attach the source code of this example after I publish the second article devoted to custom authorization in MVC.

    At this step you can successfully login in your MVC web project via forms authenticaiton. In my next article I will continue the topic and I am going to demonstrate how to implement custom authorizaiton. I will aslo review in short the authorizaiton that comes with MVC out-of-the-box.

Read full article!