[转载]asp.net MVC 权限设计(续) – jqpeng的技术记事本 – 博客园.
asp.net MVC 权限设计一文中没有demo放出来,应大家的要求,这里补充上文并放出demo。
几点说明:
1、基于将角色与controller、action相关联来判断用户是否有权
2、通过自定义AuthorizeAttribute实现
3、demo 仅供参考,一些规则可以根据实际情况重新定义
简明需求
1、可以对每个action实现权限控制,并且可以在数据库动态配置
2、权限分为允许所有人访问、允许注册用户访问、允许\禁止特定角色人访问
数据库设计
在demo里不使用数据库,这里给出表对应的类
004 |
public class ControllerAction |
019 |
/// IsController是指是否是controller,如果为false, |
020 |
/// 表示是action,那么controllerName字段就派上用场了 |
022 |
public bool IsController |
030 |
/// 如果IsController为false,该项不能为空 |
032 |
public string ControllName |
041 |
public bool IsAllowedNoneRoles |
050 |
public bool IsAllowedAllRoles |
060 |
public class ControllerActionRole |
069 |
/// 对应的ControllerAction编号 |
071 |
public int ControllerActioId |
087 |
/// IsAllowed表示包含RoleId的用户是否有权限访问ControllerActioId |
089 |
public bool IsAllowed |
113 |
public string Description |
141 |
public class UserRole |
核心流程
我们见一个Database类来模拟数据库
07 |
public static List<user> Users; |
08 |
public static List<role> Roles; |
09 |
public static List<userrole> UserRoles; |
10 |
public static List<controlleraction> ControllerActions; |
11 |
public static List<controlleractionrole> ControllerActionRoles; |
16 |
Users = new List<user>() |
18 |
new User(){Id=1,Name= "Admin" }, |
19 |
new User(){Id=2,Name = "User" }, |
20 |
new User(){Id=3,Name= "Guest" } |
23 |
Roles = new List<role>() |
25 |
new Role() {Id=1,Name= "Administrator" }, |
26 |
new Role() {Id=2,Name= "User" } |
29 |
UserRoles = new List<userrole>() |
31 |
new UserRole(){Id=1,RoleId=1,UserId=1}, |
32 |
new UserRole(){Id=2,RoleId=2,UserId=2} |
35 |
ControllerActions = new List<controlleraction>() |
37 |
new ControllerAction(){Id=1,Name= "Index" ,IsController= true ,IsAllowedNoneRoles= true ,IsAllowedAllRoles= true }, |
39 |
new ControllerAction(){Id=2,ControllName= "Home" ,Name= "Admin" ,IsController= false ,IsAllowedNoneRoles= false ,IsAllowedAllRoles = false }, |
41 |
new ControllerAction(){Id=3,ControllName= "Home" ,Name= "User" ,IsController= false ,IsAllowedNoneRoles= false ,IsAllowedAllRoles = true }, |
43 |
new ControllerAction(){Id=4,ControllName= "Home" ,Name= "UserOnly" ,IsController= false ,IsAllowedNoneRoles= false ,IsAllowedAllRoles = false }, |
47 |
ControllerActionRoles = new List<controlleractionrole>() { |
48 |
new ControllerActionRole(){ Id=1,ControllerActioId = 2,RoleId = 1,IsAllowed = true }, |
49 |
new ControllerActionRole(){ Id=2,ControllerActioId = 4,RoleId = 2,IsAllowed = true } |
54 |
</controlleractionrole></controlleraction></userrole></role></user></controlleractionrole></controlleraction></userrole></role></user></summary> |
来看我们的主要代码
/// 自定义AuthorizeAttribute |
public class UserAuthorizeAttribute : AuthorizeAttribute |
public override void OnAuthorization(AuthorizationContext filterContext) |
var user = filterContext.HttpContext.Session[ "CurrentUser" ] as User; |
user = Database.Users.Find(u => u.Name == "Guest" ); |
var controller = filterContext.RouteData.Values[ "controller" ].ToString(); |
var action = filterContext.RouteData.Values[ "action" ].ToString(); |
var isAllowed = this .IsAllowed(user, controller, action); |
filterContext.RequestContext.HttpContext.Response.Write( "无权访问" ); |
filterContext.RequestContext.HttpContext.Response.End(); |
/// <span name="user"> </span>用户 |
/// <span name="controller"> </span>控制器 |
/// <span name="action"> </span>action |
/// <returns>是否允许访问</returns> |
public bool IsAllowed(User user, string controller, string action) |
var controllerAction = Database.ControllerActions.Find(ca => ca.IsController == false && ca.Name == action && ca.ControllName == controller); |
if (controllerAction == null ) |
controllerAction = Database.ControllerActions.Find(ca => ca.IsController && ca.Name == controller); |
if (controllerAction == null ) |
if (controllerAction.IsAllowedNoneRoles) |
if (controllerAction.IsAllowedAllRoles) |
var roles = Database.UserRoles.FindAll(ur => ur.UserId == user.Id); |
var actionRoles = Database.ControllerActionRoles.FindAll(ca => ca.ControllerActioId == controllerAction.Id).ToList(); |
if (actionRoles.Count == 0) |
var userHavedRolesids = Database.UserRoles.FindAll(ur => ur.UserId == user.Id).Select(ca => ca.RoleId).ToList(); |
var notAllowedRoles = actionRoles.FindAll(r => !r.IsAllowed).Select(ca => ca.RoleId).ToList(); |
if (notAllowedRoles.Count > 0) |
foreach ( int roleId in notAllowedRoles) |
if (userHavedRolesids.Contains(roleId)) |
var allowRoles = actionRoles.FindAll(r => r.IsAllowed).Select(ca => ca.RoleId).ToList(); |
if (allowRoles.Count > 0) |
foreach ( int roleId in allowRoles) |
if (userHavedRolesids.Contains(roleId)) |
测试
public class HomeController : Controller |
public ActionResult Index() |
ViewData[ "Message" ] = "欢迎使用 ASP.NET MVC!" ; |
public ActionResult Admin() |
ViewData[ "Message" ] = "只有管理员才能访问!" ; |
public ActionResult User() |
ViewData[ "Message" ] = "只要是注册用户就能访问!" ; |
public ActionResult UserOnly() |
ViewData[ "Message" ] = "只能是User才能能访问!" ; |
public ActionResult Login( string user) |
Session[ "CurrentUser" ] = Database.Users.Find(u => u.Name == user); |
if (Session[ "CurrentUser" ] != null ) |
ViewData[ "Message" ] = "你已登录为" + user; |
public ActionResult About() |
1、登录为Admin
访问Admin
访问User
访问UserOnly
2、登录为User
访问Admin
访问User
访问UserOnly
demo下载 MVCRole.rar