Thursday, February 18, 2010

UnauthorizedActionResult for ASP.Net MVC

Here is the simple class which represents action result for not authorized access:

   1: public class UnauthorizedActionResult : ActionResult
   2: {
   3:     public override void ExecuteResult(ControllerContext context)
   4:     {
   5:         context.HttpContext.Response.StatusCode =
   6:               (Int32)HttpStatusCode.Unauthorized;
   7:         context.HttpContext.Response.ContentType = "text/html";
   8:         using (var sw = new StreamWriter(context.HttpContext.Response.OutputStream, Encoding.UTF8))
   9:         {
  10:             using (var tw = new HtmlTextWriter(sw))
  11:             {
  12:                 tw.RenderBeginTag(HtmlTextWriterTag.Html);
  13:                 tw.RenderBeginTag(HtmlTextWriterTag.Head);
  14:                 
  15:                 tw.RenderBeginTag(HtmlTextWriterTag.Title);
  16:                 tw.Write(UnauthorizedActionResources.Titlte);
  17:                 tw.RenderEndTag();
  18:  
  19:                 tw.RenderEndTag();
  20:  
  21:                 tw.RenderBeginTag(HtmlTextWriterTag.Body);
  22:                 tw.Write(UnauthorizedActionResources.Text);
  23:                 tw.RenderEndTag();
  24:  
  25:                 tw.RenderEndTag();
  26:             }
  27:         }
  28:     }
  29: }

It can be used like this in your controller:

   1: public class AdminController : Controller
   2: {
   3:     private IUserSession userSession;
   4:  
   5:     public AdminController(IUserSession userSession)
   6:     {
   7:         this.userSession = userSession;
   8:     }
   9:  
  10:     [HttpGet]
  11:     public ActionResult Panel()
  12:     {
  13:         var user = this.userSession.GetCurrentUser();
  14:         if (user == null || !user.IsAdmin)
  15:         {
  16:             return new UnauthorizedActionResult();
  17:         }
  18:         return View("Panel");
  19:     }
  20: }

If this action result is returned ASP.Net MVC will redirect user on the view which corresponds to loginUrl attribute of forms tag in your web.config.

Also notice that if you will use another http response code (e.g. 403 Forbidden) IE will not show your custom error message if it has size less than 512 bytes – it will show its own “friendly error message”: http://stackoverflow.com/questions/1492444/ie-7-not-showing-my-custom-401-page/1492472.

3 comments:

  1. hm... why build Unauthorized output instead of render template?

    ReplyDelete
  2. hello mogadanez,
    by render template you mean render predefined view like "http401.aspx"? Just if we set Response.StatusCode = Unauthorized, then mvc will automatically redirect user to login page (specified in web.config) - more or less standard behavior.
    BTW - in the behaviour above there is no necessary to fill out response body tw.Write(..) with 401 status code as it will not be shown. It only has sense when you use another http status code (e.g. 403)

    PS. Glad to see you back :)

    ReplyDelete
  3. Found that there is standard HttpUnauthorizedResult in System.Web.Mvc 2

    ReplyDelete