MVC中權限管理

      權限管理,通常指根據系統設置的安全規則或者安全策略,用戶能夠訪問並且只能訪問本身被受權的資源,很少很多。權限管理幾乎出如今任何系統裏面,只要有用戶和密碼的系統。權限管理仍是比較複雜的,有的固定到某個模塊,某個操做,甚至是某個按鈕,總之想要作好一個權限管理,真的很不容易,一直在探索當中,全當拋磚引玉;看到網上好多關於權限管理的文章,之前也寫過簡單的文章,今天樓主我也要總結整理一下本身的實現方法,畢竟一千個讀者就有一千個哈姆雷特,說說本身的詳細實現、基本設計和基本思想但願幫到入門的新人們。sql

    1、基本的數據庫表設計數據庫

      基本的表設計如圖,用戶表、角色表、模塊表、權限表和用戶角色關係表、角色模塊權限關係表,某個用戶的角色(管理員、用戶等),而後再去判斷對應角色的模塊(新聞、文章等)權限(增、刪、改、查)。安全

      建立基本權限操做的SQL腳本:cookie

CREATE TABLE [dbo].[Module](
	[ID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
	[ModuleKey] [nvarchar](100) NOT NULL,
	[ModuleName] [nvarchar](100) NOT NULL,
)

CREATE TABLE [dbo].[Permission](
	[ID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
	[PermissionKey] [nvarchar](100) NOT NULL,
	[PermissionName] [nvarchar](100) NOT NULL,
)

CREATE TABLE [dbo].[Role](
	[ID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
	[RoleName] [nvarchar](100) NOT NULL,
)

CREATE TABLE [dbo].[RoleModulePermission](
	[ID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
	[RoleID] [int] NOT NULL,
	[ModuleID] [int] NOT NULL,
	[PermissionID] [int] NOT NULL,
)

CREATE TABLE [dbo].[User](
	[ID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
	[AccountNum] [nvarchar](100) NOT NULL,
	[Pwd] [nvarchar](100) NOT NULL,
	[Status] [int] NOT NULL,
	[LastLoginTime] [datetime] NOT NULL,
	[Remark] [nvarchar](100) NULL,
)

CREATE TABLE [dbo].[UserRole](
	[ID] [int] IDENTITY(1,1) PRIMARY KEY NOT NULL,
	[UserID] [int] NOT NULL,
	[RoleID] [int] NOT NULL,
)

  2、代碼中具體的實現ide

      這是一個基類,全部的Controller都繼承BaseController,[UserAuthorizeFilter(Order = 999)],每個Action過濾器都有一個 Order 屬性,用來決定Action過濾器在該範圍內的執行順序。Order屬性必需是0(默認值)或者更大的整數值。省略Order屬性則會給該過濾器的Order值爲 -1, 代表爲指明順序。任何一個在同一範圍的Action過濾器Order設爲 -1 的都將按不肯定的順序執行,單在此以前過濾器有一個特定的順序。登陸的時候是存儲的加密的Cookie,會有一個私鑰(本身定義)。加密

    [UserAuthorizeFilter(Order = 999)]
    public class BaseController : Controller
    {
        public int LoginID { get; set; }
        public string LoginName { get; set; }
        /// <summary>
        /// 是否登陸的標誌
        /// </summary>
        /// <returns></returns>
        public bool IsLogin()
        {
            if (NCookieUtil.GetCookie("GkqCMSCookie") != null)
            {
                string cookie_ver = NCookieUtil.GetCookie("GkqCMSCookie");
                string[] cookieArray = cookie_ver.Split('&');
                int loginId = cookieArray[1].ToInt();
                string token = cookieArray[0].ObjectToString();
                Admin_User user = AdminPermissionRepository.Get(loginId);
                if (user != null)
                {
                    string tokenKey = string.Format("{0}{1}{2}{3}", user.ID.ObjectToString(), user.AccountNum.ObjectToString(), user.Pwd.ObjectToString(), CommonHelper.SecretSalt);
                    if (token == tokenKey)
                    {
                        LoginID = user.ID;
                        LoginName = user.AccountNum;
                        return true;
                    }
                    return false;
                }
                return false;
            }
            else
            {
                return false;
            }
        }
    }

  Filter裏面判斷用戶是否登陸cb.IsLogin(),若是登錄驗證經過還要驗證是否對某個某個Controller對應的Action有操做權限。若是未登陸或者發成錯誤底層會捕獲,跳轉到登錄頁面或者是錯誤頁。spa

 public class UserAuthorizeFilter : System.Web.Mvc.AuthorizeAttribute
    {
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            BaseController cb = filterContext.Controller as BaseController;
            if (!cb.IsLogin())
            {
                SetHttpContext(filterContext, GkmBBS.DataCenter.GlobalEnumHelper.EnumJsonResult.NotLogin, "未登陸");
            }
            else
            {
                bool IsAuthorization = filterContext.Controller.TempData["IsAuthorization"].ToBoolean(true);
                if (IsAuthorization)
                {
                    string controller = filterContext.RouteData.Values["controller"].ObjectToString();
                    string action = filterContext.RouteData.Values["action"].ObjectToString();
                    if (!AdminPermissionRepository.IsPowerPage(cb.LoginID,controller, action))
                    {
                        SetHttpContext(filterContext, GkmBBS.DataCenter.GlobalEnumHelper.EnumJsonResult.NoAccess, "您沒有權限執行此操做");
                    }
                }
            }
        }

        private void SetHttpContext(AuthorizationContext filterContext, GkmBBS.DataCenter.GlobalEnumHelper.EnumJsonResult result, string msg)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                var data = new { Result = (int)result, Msg = msg };
                filterContext.Result = new JsonpResult() { Data = data, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
            }
            else
            {
                if (result == GkmBBS.DataCenter.GlobalEnumHelper.EnumJsonResult.NotLogin)
                {
                    filterContext.Result = new RedirectResult(string.Format("/Login/Index?ReturnUrl={0}", filterContext.HttpContext.Request.Url.OriginalString));
                }
                else
                {
                    filterContext.Controller.ViewData["ErrorMessage"] = msg;
                    filterContext.Result = new ViewResult() { ViewName = "Error", ViewData = filterContext.Controller.ViewData };
                }
            }
        }
    }

  用戶的ID判斷角色,而後把角色去查是否有這個權限,若是有進入,對應的controller 和action,若是沒有則沒權限。具體實現方法以下:設計

    public static bool IsPowerPage(int loginID, string Moudle, string operate)
        {
            try
            {
                string sql = string.Format(@"SELECT COUNT(1)
FROM (
           SELECT c.modulekey,
                  d.permissionkey
           FROM   (
                      SELECT *
                      FROM   Admin_userrole
                      WHERE  userid = {0}
                  ) a
                  LEFT JOIN Admin_RoleModulePermission b
                       ON  a.roleId = b.roleId
                  LEFT 
           JOIN Admin_Module c
                       ON  b.moduleId = c.Id
                  LEFT JOIN Admin_Permission d
                       ON  b.PermissionId = d.Id
       ) e
WHERE  e.moduleKey = '{1}'
       AND e.PermissionKey = '{2}'", loginID, Moudle, operate);
                return NSqlHelper.ExecuteScalar(NWebConfig.ReadConnectionString(DBCon.SYS_DBCONNSTRING), CommandType.Text, sql, null).ToInt() > 0;
            }
            catch (Exception ex)
            {
                log.Error("AdminPermissionRepository-IsPowerPage", ex);
                return false;
            }
        }

       用戶登陸成功寫入Cookie,而後瀏覽每一個模塊判斷登陸和具體某個模塊的權限, 這算是一個最基本簡單權限管理,適合新手入門用,大牛們覺的不合適的地方,或者更好的方法多多指導!         3d

相關文章
相關標籤/搜索