2016年5月21日 星期六

[ASP.NET] Customize Authorize attribute

 ASP.NET   Windows Authentication   Identity   Authorize Attribute


Introduction


In ASP.NET MVC, we can confirm the permission of the current logon user by add the [Authorize] attribute. For example,

[Authorize(Roles ="Admin")]
public ActionResult Index(int? page)
{ … }

However, we will never want to maintain the Authorize attributes for every Action or Controller since the role name might changes or there might be other roles allowed for the Action.

We will override the Authorize attribute to make it more flexible by query the role of the user and then verify the permission of the role.


Implement



Implemnt a new attribute which inherits AuthorizeAttribute


[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class SetPermissionsAttribute : AuthorizeAttribute
{
        /// <summary>
        /// Controller name
        /// </summary>
        public string Controller { get; set; }
        /// <summary>
        /// Action name
        /// </summary>
        public string Action { get; set; }

        /// <summary>
        /// Authorize
        /// </summary>
        /// <param name="httpContext">HttpContextBase</param>
        /// <returns>Is authorized</returns>
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            bool isAuthorized = false;
            //Verify the user thru database
            //Step1. Get user id
            //Step2. Get the user’s roles
            //Step3. Check if the user’s roles have permissions on the Controller and Action
isAuthorized =
            return isAuthorized;
        }

        /// <summary>
        /// 攔截未授權的Request
        /// </summary>
        /// <param name="filterContext"></param>
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            // Returns HTTP 401 by default - see HttpUnauthorizedResult.cs.
            filterContext.Result = new RedirectToRouteResult(
            new RouteValueDictionary {
                { "action", "Index" },
                { "controller", "Home" },
                { "area", ""}
                //{ "parameterName", "YourParameterValue" }
            });
        }
    }

l   Override AuthorizeCore(HttpContextBase httpContext) to verify the user with the Controller name and Action name.

l   Override HandleUnauthorizedRequest(AuthorizationContext filterContext) to redirect the request or something else.

Usage

[SetPermissions(Controller="Hello", Action ="Index")]
public ActionResult Index(int? page)
{ … }



Redirect for Unauthorized requests

Furthermore, it’s better to add the following 401 redirect settings in WebConfig.

<system.web>
      <error statusCode="401" redirect="~/error401.html" />
    </customErrors>
</system.web>



Or capture the 401 request on Global.asax

protected void Application_EndRequest(object sender, System.EventArgs e)
{
     if (Response.StatusCode == 401)
     {
         String redirectUri = "~/Error401.html";
         Response.Redirect(redirectUri);
     }
}


Reference




沒有留言:

張貼留言