MVC中权限管理

      权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源,不多不少。权限管理几乎出现在任何系统里面,只要有用户和密码的系统。权限管理还是比较复杂的,有的固定到某个模块,某个操作,甚至是某个按钮,总之想要做好一个权限管理,真的很不容易,一直在探索当中,全当抛砖引玉;看到网上好多关于权限管理的文章,以前也写过简单的文章,今天楼主我也要总结整理一下自己的实现方法,毕竟一千个读者就有一千个哈姆雷特,说说自己的详细实现、基本设计和基本思想希望帮到入门的新人们。

    一、基本的数据库表设计

      基本的表设计如图,用户表、角色表、模块表、权限表和用户角色关系表、角色模块权限关系表,某个用户的角色(管理员、用户等),然后再去判断对应角色的模块(新闻、文章等)权限(增、删、改、查)。

      创建基本权限操作的SQL脚本:

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,
)

  二、代码中具体的实现

      这是一个基类,所有的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有操作权限。如果未登录或者发成错误底层会捕获,跳转到登陆页面或者是错误页。

 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,然后浏览每个模块判断登录和具体某个模块的权限, 这算是一个最基本简单权限管理,适合新手入门用,大牛们觉的不合适的地方,或者更好的方法多多指导!         

转载于:https://www.cnblogs.com/viaiu/p/5799269.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
功能介绍: 本系统通过对MVC4 Simplemembership默认数据库进行扩展实现了后台管理用户,角色和权限。通过角色的权限配置实现对前台Controller和Action的权限管理。 使用方法: 第一步:修改Web.config文件。 这个文件只需要TYStudioUsersConnectionString的用户名和密码,修改为你本地具有创建数据库权限的用户名和密码。修改完成运行程序会系统会自动创建扩展后的Membership数据库。 第二步:建立系统管理员角色和用户。 考虑到手动添加系统管理员角色和用户比较麻烦,初始的程序都是可以匿名访问的,这时候你需要运行系统添加一个系统管理员角色,并添加一个用户赋给系统管理员权限。再添加完系统管理员角色和用户之后你需要修改一下Controllers下面的各个Controller,注释掉[AllowAnonymous]并把//[Authorize(Roles = "系统管理员")]注释打开。编译重新运行程序,这时后台管理系统只能允许系统管理员角色的用户登陆了。 第三步:测试产品模块(ProductController) Controller下有一个ProductController是用来测试我们的权限管理是否成功的起作用了,同时也是对前台Controller和Action进行全线控制的方法。这里使用[TYStudioAuthorize("查询产品")]方式对Action进行访问控制。所有关于Membership的类都在Models/Membership文件夹下面。将来你需要把这些class移植到你的公共project去,这样就可以使用MVC4 Simplemembership对你的前台进行权限控制了。 注意: 开发环境为Visual Studio 2012
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值