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

    一、基本的数据库表设计

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

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

MVC中权限管理的更多相关文章

  1. 朴素的标题:MVC中权限管理实践

    基于MVC的web项目最好的权限控制方式我认为是对Action的控制,实现思路记录于此,权限管理分成两个部分授权.认证. 一.授权 1.读取当前项目中的所有需要控制的Action /// <su ...

  2. MVC之权限管理-网站开发之路

    一.前言 刚到公司没多长时间就开始接触MVC到现在不能说懂了,只能说到达会用这个层次吧,感觉MVC用来写Web还是很强大的,层次清晰. 今天我来写写关于权限管理这一块,自我感觉网站的权限主要分为菜单权 ...

  3. asp.net mvc的权限管理设计

    现在集中展示用户-角色-权限管理的功能,因此,所有数据表一律简化处理.   1 后台管理效果 (1)角色管理 (2)权限管理   2 数据库设计(MSSQL) (1)用户表dbo.Users 项 类型 ...

  4. MVC中权限的知识点及具体实现代码

    一:知识点部分 权限是做网页经常要涉及到的一个知识点,在使用MVC做权限设计时需要先了解以下知识: MVC中Url的执行是按照Controller->Action->View页面,但是我们 ...

  5. ASP.NET MVC中权限控制的简单实现

    1.重写AuthorizeAttribute类,用自己的权限控制逻辑重写AuthorizeCore方法 public class MyAuthorizeAttribute : AuthorizeAtt ...

  6. Linux中权限管理之文件属性权限

    chattr [+-=][选项] 文件或目录名 + 增加权限 - 删除权限 = 等于某权限 选项: i 文件设置i属性,不允许对文件进行删除.改名.添加.修改数据,相当于把整个文件锁起来了 目录设置i ...

  7. Linux中权限管理之文件特殊权限

    SetUID 1.只有在可执行的二进制程序上设定SUID权限才是有意义的 2.命令执行者要对该程序拥有执行权限 3.命令执行者在执行该程序时获得该程序文件属主的身份 4.SetUID权限只在该程序执行 ...

  8. Linux中权限管理之ACL权限

    1.简介: a.作用: 是为了防止权限不够用的情况,一般的权限有所有者.所属组.其他人这三种,当这三种满足不了我们的需求的时候就可以使用ACL权限 b.故事背景: 一个老师,给一个班的学员上课,他在l ...

  9. linux中权限管理命令(chmod/chown/chgrp/unmask)

    目录 chmod chown chgrp umask chmod 解释 命令名称:chmod 命令英文原意:change the permissions mode of a file 命令所在路径:/ ...

随机推荐

  1. 提取LSA密码lsadump

    提取LSA密码lsadump   LSA是Windows系统本地安全认证的模块.它会存储用户登录其他系统和服务用户名和密码,如VPN网络连接.ADSL网络连接.FTP服务.Web服务.通过搜集这些信息 ...

  2. python操作日期和时间的方法

    不管何时何地,只要我们编程时遇到了跟时间有关的问题,都要想到 datetime 和 time 标准库模块,今天我们就用它内部的方法,详解python操作日期和时间的方法.1.将字符串的时间转换为时间戳 ...

  3. [超级懒人最简单法]iPhone 6 plus 适配切图方法分享(转载文章)

    网络上已经有很多适配教程,可是看了半天总是半懂不懂..最后还是要综合多个教程再动动脑子动动手,最好有程序大哥帮你试一下(这得有多大的福气) 如果有跟我一样情况的: 1.       有人说用sketc ...

  4. marquee-:模拟弹幕

              marquee:基本已被弃用!!1 可以模拟弹幕效果           1.方向:direction             up  right   left  down     ...

  5. js中的数据类型

    JS中的数据类型: ——数字  (number)NaN ——字符串(string) ——布尔  (boolean)——函数  (function)     也是对象的一种 ——对象  (object) ...

  6. asp.net在线预览txt文件(简单实现)

    最近在做文件的在线预览,发现txt文件没有一个较好的方法去实现,想了想可能是比较简单就直接在后台输出了 txt文件

  7. 中國區的代理協議的韓國遊戲廠商PatiGames

    “與阿裏巴巴簽署旗下游戲「突突三國」在中國區的代理協議的韓國遊戲廠商PatiGames決定與阿裏巴巴終止合作.”相信這條前不久報導的新聞,很多人並不陌生,但這背後其實並不像表面那樣簡單.早在今年4月P ...

  8. jQuery系列:五个模块总结

    Query插件,以备并希望在前端方面有所长进.请批评指正. 一,类型判断全解 JQuery判断类型扩展方法:$.type() /*type: function( obj ) { if ( obj == ...

  9. Rails--n+1查询

    listings = Listing.includes(:property).where(id: ids)

  10. 一起来做webgame,《Javascript蜘蛛纸牌》

    不得不说,做游戏是会上瘾的,这次带来的是win系统上的经典游戏<蜘蛛纸牌>,不能完美,但求一玩 移牌 0 次 Javascript game_蜘蛛纸牌 正在努力加载... // " ...