Dec 7, 2009

MVC Exception management

ASP.NET MVC exception handling, custom error pages and logging

I will continue our walk through the MVC’s world and today we will review how to manage our exceptions in MVC application.
Nobody wants to see the famous “yellow screen” of death page, when working in his application. It is getting bothering whilst working to get an ugly exception screen and either to refresh your current page or to use “back” navigation button of your browser. In addition I would like to note that nowadays just doing exception is not enough. Critical problems that occur in our code should be traced and persisted, because this information might be crucial and it is stateless if we decide to do nothing with it.

In classic ASP.NET you could manage your exceptions on page level, central lever through global.asax, or you can even do it via http module.

Well ASP MVC, can handle easily exceptions too. And it is very powerful. We will review how to use and explore what the framework gives and in addition will create our own Exception attribute and we will use log.net (which is pretty popular) for logging our exceptions in text file.

HandleError attribute in MVC can be applied to both controllers and action methods.
Let’s see what this attribute gives us.

I will add a method in my Home controller that will cause and exception and will handle this by various ways.

In Master page I will refer my method by adding next line of code:
<%= Html.ActionLink("Cause exception", "DoSomething", "Home") %>

If you take a look of controllers that are created with MVC template (HomeController.cs, AccountController.cs), you will see that they come for us with [HandleError] attribute applied to their definition.
In order to make HandleError attribute working for you (locally), go to the web.config and change the settings related to custom errors:


Now we need to provoke an exception, just to check what this HandleError attribute does for us.
In the sample action method I will cause DevideByZero exception.

public ActionResult DoSomething()
{
var j = 0;
var i = 5 / j;
return View("Index");
}

Screenshot below demonstrates very clear what the result is.



What we see, is actually the Error.aspx page placed in Views\Shared. When you provide only the HandleError attribute to your class (or to your action method), then when an unhandled exception occurs MVC will look for a corresponding View named "Error" first in the Controller's View folder. In our case we don’t have such one, so MVC ends up searching of view with this name in Shared folder.

If we turn of the custom error attribute by setting mode=”Off” we will see the “yellow page”.


HandleError attribute allows even more. It provides functionality to handle specific exception types and to visualize dedicated pages that can serve your action methods.

By adding a new view called “Test.aspx” in Views\Shared and declaring HandleError for our DoSomething action method, we supply dedicated page for displaying on exception in the controller method.



Important thing to note is that if we want both controller and action methods to be served by HandleError attribute, we should set Order = 0 to attribute of the controller. Otherwise it takes over and overrides the HandleError of action methods if no Order is set for their HandleError attributes.
The Order property of the HandleErrorAttribute attribute helps determine which HandleErrorAttribute filter is used to handle an exception. You can set the Order property to an integer value that specifies a priority from -1 (highest priority) to any positive integer value. The greater the integer value is, the lower the priority of the filter is.
Bear in mind that filters with the same order number are applied in an undetermined order.

In addition we can specify what exception type to handle the HandleError attribute.
[HandleError(View="Test", ExceptionType=typeof(DivideByZeroException))]

If another type of exception occurs, then exception will be handled by HandleError attribute of the controller (if such been set).

If you want one action method to be served by different pages on exception, or one page to server different exception types for an action method you should apply as many HandleError attributes as you want.



Another approach for handling your exceptions on controller level is by overriding the virtual method OnExcetion.

protected virtual void OnException(ExceptionContext filterContext); defined in System.Web.Mvc.Controller class.

If overriden, this method is called whenever exception occurs in an action method in the controller. It doesn’t rely on your HandleError attribute and execution of OnException method will take over. So, this could be one centralized place for handling your controllers exceptions.



This approach is much more straightful and powerful. It gives you one central place, where you can manage all unhandled exceptions and decide what to do with this information – email it, log it, store it, serve it to the user in friendly message, etc..

Since HandleError attribute just outputs a view and doesn’t let you run any code, it this not the ultimate solution for the exception management. It is still good from the perspective of the end user, who works with your application. But, do you really think this is the right way to do? How are you going to investigate a problem that occurred a day ago on your client’s production environment? Only by the memories of the users who faced the issue? Honestly I wouldn’t rely on this.

That is why using OnException method in my opinion, is the right way for exception management in ASP.NET MVC. You can implement a logic that perfectly fits your custom needs for tracking all unhandled issues.

We reviewed how we can do exception management, but we didn’t cover one very common scenario. What If I want to have a set of certain action attributes which should be treated in different manner on exception? Well, obviously I can do this in mine overriden OnException by inspecting the route data. But, If I have many action methods I may end up with a very big switch statement (for example). And I can go a bit futher, what if I expect to have very very specific exceptions that I don’t want at all to treat in the same place with all others? What if I want to render a custom action result if specific unhandled exception occurs in mine action method?

In this case, we should go for creating custom exception attribute and to apply it to the methods we need.
Just for the sake of the demo, let’s create custom attribute for logging exceptions with log4net.

After we download and refer log4net.dll in our project we need slight modifications in order to make it work and log for us.



Configure log4net in Global.asax :


In order to create a custom exception attribute we need to inherit FilterAttribute and to implement IExceptionFilter interface.
Exception filters run after all other action filters and result filter have been executed. This approach allows us to replace the action method's action result with a custom ActionResult, to redirect user to an error action method that can serve user friendly result or just to do logging as we do.



The last thing that left is to use the CustomExcetionAttribute.


If OnException method is overridden in the controller class, bear in mind that it will be executed prior to our custom exception method.
If we add next statement block, our custom exception attribute will never log a message since it is already been handled in BaseController OnException method.

if (filterContext.ExceptionHandled)
return;

So, be careful when you use such validations.

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

Read full article!

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
Enjoy!!!

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 http://msdn.microsoft.com/en-us/library/ms229862.aspx

  • 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!