C# asp.net MVC4 权限设计

2023-10-31 16:08

本文主要是介绍C# asp.net MVC4 权限设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

因为是转载文章 在此标明出处,以前有文章是转的没标明的请谅解,因为有些已经无法找到出处,或者与其它原因。

如有冒犯请联系本人,或删除,或标明出处。

因为好的文章,以前只想收藏,但连接有时候会失效,所以现在碰到好的直接转到自己这里。

原文 出处http://www.cnblogs.com/xiaoqi/archive/2010/01/07/1641570.html

几点说明:

 

    1、该权限系统是个网站用的,用户简单,因此不涉及到部门这些信息

    2、基于将角色与controller、action相关联来判断用户是否有权

    3、通过重载AuthorizeAttribute实现

 

数据库设计:

  • image 

  •  

表说明

 

ControllerAction 

  1.     Name是controller的名称
  2.     IsController是指是否是controller,如果为false,表示存的是action,那么controllerName字段就派上用场了
  3.     IsAllowedNoneRoles是指是否允许没有权限的人访问
  4.     IsAllowedAllRoles是指是否允许有角色的人访问

IsAllowedNoneRoles,IsAllowedAllRoles实现了允许所有人访问以及允许所有注册用户访问:),并且我们约定,IsAllowedNoneRoles具有最高的优先级,其次是IsAllowedAllRoles,然后才是ControllerActionRole中定义的规则

 

 

ControllerActionRole

 IsAllowed表示该action或者controller是否允许访问,加入表中有两条记录

角色 Name ControllName IsAllowed IsController
   A Admin Home false false
   A Home Null true true

     这里约定分两个层次来判断权限:

          第一条记录:表示A角色不能访问 Home/admin

          第二条记录:表示A角色可以访问Controller下的所有方法

     到底能不能访问呢?其实,我们以action为准,如果定义了action,我们直接从action的约定来判断,因此这里判断A不能访问Home/admin

 

 其他几张表一看就明白,不再多说

 

判断是否有权限的设定

 

    1、获取controller,action,以及存放在session中的用户信息

复制代码
   
1 public class UserAuthorizeAttribute : AuthorizeAttribute
2 {
3
4 public override void OnAuthorization(AuthorizationContext filterContext)
5 {
6 var user = filterContext.HttpContext.Session["CurrentUser"] as User;
7 var controller = filterContext.RouteData.Values["controller"].ToString();
8 var action = filterContext.RouteData.Values["action"].ToString();
9 var isAllowed = this.IsAllowed(user, controller, action);
10
11 if (!isAllowed)
12 {
13 filterContext.RequestContext.HttpContext.Response.Write("无权访问");
14 filterContext.RequestContext.HttpContext.Response.End();
15 }
16
17 }
18
19 ……
20
21 }
22  
复制代码

 

    2、检索数据库ControllerAction表中有没有Name为第一步中controller 的记录,如果没有,我们约定这个controller是不需要进行权限控制的,如果有的话,进入第三步

 

   3、前面提到了,我们约定对权限的控制分为两个层次,controller和action层次,如果同时定义了,以action为准。因此,我们需要判断是否在数据库中有action的记录,如果有,进入4,无,进入5

复制代码
   
1 bool IsAllowed(User user, string controllerName, string actionName)
2 {
3 var service = ServiceLoader.LoadService<ToySpirit.IToySpiritService.IControllerActionService>();
4
5 // 获取对应的controller
6   var controller = service.GetSingleByExpression(c => c.Name == controllerName && c.IsController);
7 if (controller != null)
8 {
9 // 获取对应的action
10   var controllerAction = service.GetSingleByFunc(c => c.Name == actionName && c.IsController == false && c.ControllerName == controllerName);
11
12 return controllerAction == null ? this.isAllowed(user, controller) : this.isAllowed(user, controllerAction);
13 }
14
15 // 没有定义controller的权限,表示无需权限控制
16   return true;
17 }
18
19  
复制代码

 

4、如果有action的记录,那么我们首先判断controllerAction 拒绝哪些角色访问,如果用户有角色在这里面,很遗憾,就不能访问了;然后判断controllerAction 允许哪些角色访问,如果用户的角色在这里面,就可以访问了

注:这里很有可能用户有多个角色,比如A,B,C,如果A不能访问controllerAction,那么很遗憾,用户不能访问,尽管角色B,C可能可以访问该controllerAction

5、没有action的记录,自然就检查controller对应的controllerAction 了

 

复制代码
    
4、5判断的代码是一样的,如下:

private bool isAllowed(User user, ControllerAction controllerAction)
{
// 允许没有角色的:也就是说允许所有人,包括没有登录的用户
if (controllerAction.IsAllowedNoneRoles)
{
return true;
}

// 允许所有角色:只要有角色,就可以访问
if (controllerAction.IsAllowedAllRoles)
{
return user.Roles.Count > 0;
}

if (user == null || user.Roles.Count == 0)
{
return false;
}

// 选出action对应的角色
var roles = controllerAction.ControllerActionRoles.Select(ca => ca.Role).ToList();
if (roles.Count == 0)
{
// 角色数量为0,也就是说没有定义访问规则,默认允许访问
return true;
}

var userHavedRolesids
= user.Roles.Select(r => r.ID).ToList();

// 查找禁止的角色
var notAllowedRoles = controllerAction.ControllerActionRoles.FindAll(r => r.IsAllowed == false).Select(ca => ca.Role).ToList();
if (notAllowedRoles.Count > 0)
{
foreach (Role role in notAllowedRoles)
{
// 用户的角色在禁止访问列表中,不允许访问
if (userHavedRolesids.Contains(role.ID))
{
return false;
}
}
}

// 查找允许访问的角色列表
var allowRoles = controllerAction.ControllerActionRoles.FindAll(r => r.IsAllowed).Select(ca => ca.Role).ToList();
if (allowRoles.Count > 0)
{
foreach (Role role in allowRoles)
{
// 用户的角色在访问的角色列表
if (userHavedRolesids.Contains(role.ID))
{
return true;
}
}
}

return false;
}

复制代码

 

 

 

使用方法:

 

建立一个basecontroller,使用我们定义好的UserAuthorize,然后所有的controller继承basecontroller就可以了

复制代码
   
1 /// <summary>
2 /// 控制基类
3 /// </summary>
4   [UserAuthorize]
5 public abstract class BaseController : Controller
6 {}
7
8 public class HomeController : BaseController{}
9  
复制代码

 

 

演示:

 

在controlleraction中添加几条数据:

image

根据我们的规则,我们可以知道,未登录的用户可以访问Home/Public,其他几个页面则不能访问

我们看对应的Action:

复制代码
   
1 public void ViewPage()
2 {
3 Response.Write("View");
4 }
5 public void Public()
6 {
7 Response.Write("Public");
8 }
9 public void Delete()
10 {
11 Response.Write("Delete");
12 }
复制代码

 

访问Home/Public,如果有权限,那么显示“Public“,否则显示”无权访问”

未登录用户访问Home/Public,结果符合我们的约定;-)

image

未登录用户访问Home/ViewPage,按约定应该显示错误信息

image


这篇关于C# asp.net MVC4 权限设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/316522

相关文章

使用C#代码在PDF文档中添加、删除和替换图片

《使用C#代码在PDF文档中添加、删除和替换图片》在当今数字化文档处理场景中,动态操作PDF文档中的图像已成为企业级应用开发的核心需求之一,本文将介绍如何在.NET平台使用C#代码在PDF文档中添加、... 目录引言用C#添加图片到PDF文档用C#删除PDF文档中的图片用C#替换PDF文档中的图片引言在当

详解C#如何提取PDF文档中的图片

《详解C#如何提取PDF文档中的图片》提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使用,下面我们就来看看如何使用C#通过代码从PDF文档中提取图片吧... 当 PDF 文件中包含有价值的图片,如艺术画作、设计素材、报告图表等,提取图片可以将这些图像资源进行单独保存,方便后续在不同的项目中使

C#使用SQLite进行大数据量高效处理的代码示例

《C#使用SQLite进行大数据量高效处理的代码示例》在软件开发中,高效处理大数据量是一个常见且具有挑战性的任务,SQLite因其零配置、嵌入式、跨平台的特性,成为许多开发者的首选数据库,本文将深入探... 目录前言准备工作数据实体核心技术批量插入:从乌龟到猎豹的蜕变分页查询:加载百万数据异步处理:拒绝界面

C#数据结构之字符串(string)详解

《C#数据结构之字符串(string)详解》:本文主要介绍C#数据结构之字符串(string),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录转义字符序列字符串的创建字符串的声明null字符串与空字符串重复单字符字符串的构造字符串的属性和常用方法属性常用方法总结摘

C#如何动态创建Label,及动态label事件

《C#如何动态创建Label,及动态label事件》:本文主要介绍C#如何动态创建Label,及动态label事件,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#如何动态创建Label,及动态label事件第一点:switch中的生成我们的label事件接着,

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

C#基础之委托详解(Delegate)

《C#基础之委托详解(Delegate)》:本文主要介绍C#基础之委托(Delegate),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 委托定义2. 委托实例化3. 多播委托(Multicast Delegates)4. 委托的用途事件处理回调函数LINQ

在C#中调用Python代码的两种实现方式

《在C#中调用Python代码的两种实现方式》:本文主要介绍在C#中调用Python代码的两种实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#调用python代码的方式1. 使用 Python.NET2. 使用外部进程调用 Python 脚本总结C#调

C#中的 StreamReader/StreamWriter 使用示例详解

《C#中的StreamReader/StreamWriter使用示例详解》在C#开发中,StreamReader和StreamWriter是处理文本文件的核心类,属于System.IO命名空间,本... 目录前言一、什么是 StreamReader 和 StreamWriter?1. 定义2. 特点3. 用

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth