[MVC]自定授權過濾器屬性

[MVC]自定授權過濾器屬性

如果有自己的權控系統,不使用Asp.NET內建的,這時就要來寫授權過濾器屬性,然後設定到Controller上,這樣Controller上所有的Action都會驗証!

以下繼承自System.Web.Mvc.AuthorizeAttribute,然後加一個屬性AppFunctionId做為該Controller的功能代號,再來就是覆寫OnAuthorization及AuthorizeCore來填入我們系統的驗証Logic。

public class AppAuthorizeAttribute : AuthorizeAttribute
{
    /// <summary>
    /// 功能代號
    /// </summary>
    public string AppFunctionId
    {
        get;
        set;
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }
        //檢查是否有權限
        if (string.IsNullOrEmpty(AppFunctionId))
        {
            //如果功能代號是空值,代號就給控制項名稱
            AppFunctionId = filterContext.RouteData.Values["controller"] as string;
        }
        if (AuthorizeCore(filterContext.HttpContext))
        {
            //驗証通過... your custom code ...
        }
        else //if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            // 驗証失敗, redirect to login page
            filterContext.Result = new HttpUnauthorizedResult();
            //redirect to login page
        }
    }
    
    /// <summary>
    /// 覆寫AuthorizeAttribute類別的AuthorizeCore方法
    /// </summary>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool result = false;
        if ( httpContext.User.Identity.IsAuthenticated)
        { 
            //已登入,所以先檢查是否有Session沒有的話,就從cookie中取出來
            if (CheckLoginInfo(httpContext))
            {
                result = true; //檢查是否有權限使用該功能 CheckAuthorization(AppFunctionId));
            }
        }
        return result;
    }

    /// <summary>
    /// 檢查Session是否還在,依據cookie取出使用者資訊,並取出該使用者的資料
    /// </summary>
    private bool CheckLoginInfo(HttpContextBase httpContext)
    {
        bool result = false;
        if ( string.IsNullOrEmpty(Session["usrid"]))
        {
            //沒有使用者資訊
            //session不在,所以check cookie是否在
            string cookieName = FormsAuthentication.FormsCookieName;
            HttpCookie authCookie = httpContext.Request.Cookies[cookieName];
            FormsAuthenticationTicket authTicket = null;
            authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            string usrid = authTicket.Name;
            if (string.IsNullOrEmpty(usrid) == false)
            {
                //自動登入系統
                FormsService.SignIn(usrid, true);
                Session["usrid"] = usrid;
                result = true;
            }
        }
        else { result = true; }
        return result;
    }
}

所以再定義一個要參與驗証的FunControllerBase,然設設定要驗証,這樣繼承它下來的Controller都會驗証到哦!

/// <summary>
/// 要參與驗証的Controller
/// </summary>
[AppAuthorizeAttribute()]
public class FunControllerBase : Controller
{

}