寫該權限類主要目地
為了讓權限配置更加的靈活,可以根據SQL、json、或者XML的方式來動態進行頁面的訪問控制,以及沒有權限的相關跳轉。
使用步驟
1、要建一個全局過濾器
//受權過濾器 public class AuthorizeFilter : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { } }
2、Gobal里注冊 GlobalFilters.Filters.Add(new AuthorizeFilter());該過該全局過濾器
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); GlobalConfiguration.Configure(WebApiConfig.Register); GlobalFilters.Filters.Add(new AuthorizeFilter()); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); }
3、在過濾器中調用 SystemAuthorizeService.Start實現
(1)使用對象進行權限驗證
public override void OnAuthorization(AuthorizationContext filterContext) { List<SystemAuthorizeModel> smList = new List<SystemAuthorizeModel>() { //用戶1,2,3可以訪問 area為admin 所有權限 new SystemAuthorizeModel() { SystemAuthorizeType= SystemAuthorizeType.Area, AreaName="admin" , UserKeyArray=new dynamic[] { 1,2,3 /*用戶授權數組*/} }, //用戶8,7可以訪問 area為admin 控制器為:center 所有權限 new SystemAuthorizeModel() { SystemAuthorizeType= SystemAuthorizeType.Controller, AreaName="admin" , ControllerName="center", UserKeyArray=new dynamic[] { 8,7 /*用戶授權數組*/} }, //用戶1可以訪問為 area為:null 控制器為:home 操作為:about 的請求 new SystemAuthorizeModel() { SystemAuthorizeType= SystemAuthorizeType.Action, ControllerName="home" , ActionName="about" , UserKeyArray=new dynamic[] { 1 } }, //給用戶100和110所有頁面權限 new SystemAuthorizeModel() { SystemAuthorizeType= SystemAuthorizeType.All, UserKeyArray=new dynamic[] { 100,110 } } }; SystemAuthorizeErrorRedirect sr = new SystemAuthorizeErrorRedirect(); sr.DefaultUrl = "/user/login";//沒有權限都跳轉到DefaultUrl //sr.ItemList=xx 設置更詳細的跳轉 SystemAuthorizeService.Start(filterContext, smList, sr, () => { //獲取用戶ID return 1; //用戶ID為1,作為DEMO寫死 ,當然了可以是SESSION也可以是COOKIES等 這兒就不解釋了 }); }
(2)使用JSON轉成對象進行驗證
[
{
"SystemAuthorizeType": 1,
"AreaName": "admin",
"ControllerName": "center",
"ActionName": null,
"UserKeyArray": [
1,
2,
3
]
},
{
"SystemAuthorizeType": 1,
"AreaName": "admin",
"ControllerName": "center",
"ActionName": null,
"UserKeyArray": [
8,
7
]
},
{
"SystemAuthorizeType": 3,
"AreaName": null,
"ControllerName": "home",
"ActionName": "about",
"UserKeyArray": [
1
]
},
{
"SystemAuthorizeType": 0,
"AreaName": null,
"ControllerName": null,
"ActionName": null,
"UserKeyArray": [
100,
110
]
}
]
SystemAuthorizeService代碼:
using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace Idea.Models.Filters { /// <summary> /// 系統授權服務 /// 作者:sunkaixuan /// 時間:2015-10-25 /// </summary> public class SystemAuthorizeService { /// <summary> /// 啟動系統授權 /// </summary> /// <param name="filterContext"></param> /// <param name="SystemAuthorizeList">所有驗證項</param> /// <param name="errorRediect">沒有權限跳轉地址</param> /// <param name="GetCurrentUserId">獲取當前用戶ID</param> public static void Start(AuthorizationContext filterContext, List<SystemAuthorizeModel> systemAuthorizeList, SystemAuthorizeErrorRedirect errorRediect, Func<object> GetCurrentUserKey) { if (errorRediect == null) { throw new ArgumentNullException("SystemAuthorizeService.Start.errorRediect"); } if (systemAuthorizeList == null) { throw new ArgumentNullException("SystemAuthorizeService.Start.systemAuthorizeList"); } //全部小寫 foreach (var it in systemAuthorizeList) { it.ControllerName = it.ControllerName.ToLower(); it.ActionName = it.ActionName.ToLower(); it.AreaName = it.AreaName.ToLower(); } //聲名變量 var context = filterContext.HttpContext; var request = context.Request; var response = context.Response; string actionName = filterContext.ActionDescriptor.ActionName.ToLower(); string controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.ToLower(); string areaName = null; bool isArea = filterContext.RouteData.DataTokens["area"] != null; //變量賦值 if (isArea) areaName = filterContext.RouteData.DataTokens["area"].ToString().ToLower(); //函數方法 #region 函數方法 Action<string, string, string> Redirect = (action, controller, area) => { filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = controller, action = action, area = area })); }; Action<string> RedirectUrl = url => { filterContext.Result = new RedirectResult(url); }; #endregion Func<SystemAuthorizeErrorRedirectItemList, bool> redirectActionExpression = it => it.SystemAuthorizeType == SystemAuthorizeType.Action && it.Area == areaName && it.Controller == controllerName && it.Action == actionName; Func<SystemAuthorizeErrorRedirectItemList, bool> redirectControllerExpression = it => it.SystemAuthorizeType == SystemAuthorizeType.Action && it.Area == areaName && it.Controller == controllerName; Func<SystemAuthorizeErrorRedirectItemList, bool> redirectAreaExpression = it => it.SystemAuthorizeType == SystemAuthorizeType.Action && it.Area == areaName; Func<SystemAuthorizeModel, bool> actionExpression = it => it.SystemAuthorizeType == SystemAuthorizeType.Action && it.AreaName == areaName && it.ControllerName == controllerName && it.ActionName == actionName; Func<SystemAuthorizeModel, bool> controllerExpression = it => it.SystemAuthorizeType == SystemAuthorizeType.Controller && it.AreaName == areaName && it.ControllerName == controllerName; Func<SystemAuthorizeModel, bool> areaExpression = it => it.SystemAuthorizeType == SystemAuthorizeType.Area && it.AreaName == areaName; dynamic userId = GetCurrentUserKey(); //所有權限 bool isAllByUuserKey = IsAllByUserKey(systemAuthorizeList, userId); bool isAreaByUserKey = IsAreaByUserKey(systemAuthorizeList, areaName, userId); bool isControllerByUserKey = IsControllerByUserKey(systemAuthorizeList, areaName, controllerName, userId); bool isActionByUserKey = IsActionByUserKey(systemAuthorizeList, areaName, controllerName, actionName, userId); //有權限 var hasPower = (isAllByUuserKey || isActionByUserKey || isControllerByUserKey || isAreaByUserKey); //需要驗證 var mustValidate = systemAuthorizeList.Any(actionExpression) || systemAuthorizeList.Any(controllerExpression) || systemAuthorizeList.Any(areaExpression); if (!hasPower && mustValidate) { ErrorRediect(errorRediect, RedirectUrl, redirectActionExpression, redirectControllerExpression, redirectAreaExpression); } } private static void ErrorRediect(SystemAuthorizeErrorRedirect errorRediect, Action<string> RedirectUrl, Func<SystemAuthorizeErrorRedirectItemList, bool> actionExpression, Func<SystemAuthorizeErrorRedirectItemList, bool> controllerExpression, Func<SystemAuthorizeErrorRedirectItemList, bool> areaExpression) { if (errorRediect.ItemList == null) {//返回默認錯誤地址 RedirectUrl(errorRediect.DefaultUrl); } else if (errorRediect.ItemList.Any(actionExpression)) { var red = errorRediect.ItemList.Single(actionExpression); RedirectUrl(red.ErrorUrl); } else if (errorRediect.ItemList.Any(controllerExpression)) { var red = errorRediect.ItemList.Single(controllerExpression); RedirectUrl(red.ErrorUrl); } else if (errorRediect.ItemList.Any(areaExpression)) { var red = errorRediect.ItemList.Single(areaExpression); RedirectUrl(red.ErrorUrl); } else if (errorRediect.ItemList.Any(it => it.SystemAuthorizeType == SystemAuthorizeType.All)) { var red = errorRediect.ItemList.Single(it => it.SystemAuthorizeType == SystemAuthorizeType.All); RedirectUrl(red.ErrorUrl); } else { RedirectUrl(errorRediect.DefaultUrl); } } private static bool IsAllByUserKey(List<SystemAuthorizeModel> systemAuthorizeList, object userKey) { var hasAll = systemAuthorizeList.Any(it => it.SystemAuthorizeType == SystemAuthorizeType.All); if (hasAll) { if (systemAuthorizeList.Any(it => it.UserKeyArray != null && it.UserKeyArray.Contains(userKey))) { return true; } } return false; } private static bool IsAreaByUserKey(List<SystemAuthorizeModel> systemAuthorizeList, string area, object userKey) { if (systemAuthorizeList.Any(it => it.AreaName == area && it.SystemAuthorizeType == SystemAuthorizeType.Area)) //是否存在驗證級別為Area的驗證 { var isContains = systemAuthorizeList.Any(it => it.AreaName == area && it.SystemAuthorizeType == SystemAuthorizeType.Area && it.UserKeyArray.Contains(userKey)); return isContains; } return false; } private static bool IsControllerByUserKey(List<SystemAuthorizeModel> systemAuthorizeList, string area, string controller, object userKey) { if (systemAuthorizeList.Any(it => it.AreaName == area && it.ControllerName == controller && it.SystemAuthorizeType == SystemAuthorizeType.Controller)) //是否存在驗證級別為Controller的驗證 { var isContains = systemAuthorizeList.Any(it => it.AreaName == area && it.ControllerName == controller && it.SystemAuthorizeType == SystemAuthorizeType.Controller && it.UserKeyArray.Contains(userKey)); return isContains; } return false; } private static bool IsActionByUserKey(List<SystemAuthorizeModel> systemAuthorizeList, string area, string controller, string action, dynamic userKey) { if (systemAuthorizeList.Any(it => it.AreaName == area && it.ControllerName == controller && it.ActionName == action && it.SystemAuthorizeType == SystemAuthorizeType.Action)) //是否存在驗證級別為action的驗證 { return systemAuthorizeList.Any(it => it.AreaName == area && it.ControllerName == controller && it.ActionName == action && it.SystemAuthorizeType == SystemAuthorizeType.Action && it.UserKeyArray.ToString().Contains(userKey.ToString())); } return false; } } /// <summary> /// 用戶訪問需要授權的項 /// </summary> public class SystemAuthorizeModel { /// <summary> /// 驗證類型 /// </summary> public SystemAuthorizeType SystemAuthorizeType { get; set; } /// <summary> /// 用戶擁有權限訪問的Area /// </summary> public string AreaName { get; set; } /// <summary> /// 用戶擁有權限訪問的Controller /// </summary> public string ControllerName { get; set; } /// <summary> /// 用戶擁有權限訪問的Actioin /// </summary> public string ActionName { get; set; } /// <summary> /// 用戶ID /// </summary> public dynamic[] UserKeyArray { get; set; } } /// <summary> /// 如果沒有權限返回地址 /// </summary> public class SystemAuthorizeErrorRedirect { /// <summary> /// 默認值 /// </summary> public string DefaultUrl { get; set; } public List<SystemAuthorizeErrorRedirectItemList> ItemList { get; set; } } public class SystemAuthorizeErrorRedirectItemList { /// <summary> /// 驗證類型 /// </summary> public SystemAuthorizeType SystemAuthorizeType { get; set; } public string Controller { get; set; } public string Action { get; set; } public string Area { get; set; } public string ErrorUrl { get; set; } } /// <summary> /// 驗證類型 /// </summary> public enum SystemAuthorizeType { /// <summary> /// 所有權限 /// </summary> All = 0, /// <summary> ///驗證Area /// </summary> Area = 1, /// <summary> /// 驗證Area和Controller /// </summary> Controller = 2, /// <summary> /// 驗證Area和Controller和Action /// </summary> Action = 3, /// <summary> /// 沒有權限 /// </summary> No = 4 } }