ASP.NET MVC 5: Custom AuthorizeAttribute for custom authentication
In a previous post I wrote about how you can should protect your web app from human errors by enforcing authentication by default.
In this, lets check how to write your very own custom AuthorizeAttribute
!
Since adding the AuthorizeAttribute to every action involves global filters, we can use that to add our own custom authentication, by inheriting AuthorizeAttributeand overriding the AuthorizeCore
and HandleUnauthorizeRequest
methods.
We ‘ll start by adding a new .cs file (I also add a folder Attributes for all custom attributes) with the following code (read the comments for explanation):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MyNewProject.Attributes {
[AttributeUsageAttribute( AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true )]
public class MyAuthorizeAttribute : AuthorizeAttribute {
//Custom named parameters for annotation
public string ResourceKey { get; set; }
public string OperationKey { get; set; }
//Called when access is denied
protected override void HandleUnauthorizedRequest( AuthorizationContext filterContext ) {
//User isn't logged in
if ( !filterContext.HttpContext.User.Identity.IsAuthenticated ) {
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary( new { controller = "Account", action = "Login" } )
);
}
//User is logged in but has no access
else {
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary( new { controller = "Account", action = "NotAuthorized" } )
);
}
}
//Core authentication, called before each action
protected override bool AuthorizeCore( HttpContextBase httpContext ) {
var b = myMembership.Instance.Member().IsLoggedIn;
//Is user logged in?
if ( b )
//If user is logged in and we need a custom check:
if ( ResourceKey != null && OperationKey != null )
return ecMembership.Instance.Member().ActivePermissions.Where( x => x.operation == OperationKey && x.resource == ResourceKey ).Count() > 0;
//Returns true or false, meaning allow or deny. False will call HandleUnauthorizedRequest above
return b;
}
}
}
And then you can just use it from your controller like this:
//No Annotation, user must be logged in
public ActionResult DoSomething( [DataSourceRequest]DataSourceRequest request )
//Custom authentication request
[myAuthorizeAttribute(ResourceKey="SomeResource",OperationKey="SomeAction")]
public ActionResult DoSomething( [DataSourceRequest]DataSourceRequest request )
//No Authentication at all
[AllowAnonymous]
public ActionResult DoSomething( [DataSourceRequest]DataSourceRequest request )
* You should also read “ASP.NET MVC 5: “Authorization” by default for your web app” to understand the commend //No Annotation, user must be logged in
!