当前位置: 首页 > news >正文

c# .net core项目角色授权机制

前言

角色授权机制是确保应用程序安全性的重要组成部分,它允许开发者根据用户的角色来限制对应用程序中不同资源的访问。

基本概念:

角色授权基于用户角色的访问控制,即根据用户所属的角色来决定其能够访问的资源或执行的操作。在.NET Core中,这通常与身份认证(Authentication)一起使用,以确保只有经过验证的用户才能被授权访问特定资源。

案例

在上一篇blog 中,我们完成了对.net Core项目添加了JWT签名的生成与校验,这里,我们基于上一篇blog中演示的代码中进行改进,在jwt中添加Role信息。

c# .net core项目中使用JWT进行权限校验icon-default.png?t=N7T8http://t.csdnimg.cn/XjqqX

 角色枚举

首先,我们新建一个枚举AuthorizeRoleName,用于表示不同的角色 。

public enum AuthorizeRoleName
{Administrator,  Editor,  Viewer  
}

 用户信息增加角色

然后在UserRes中添加一个新的属性RoleName,用于填写用户角色。

public class UserRes
{/// <summary>/// 用户名/// </summary>[Required]public string Name { get; set; }/// <summary>/// 密码/// </summary>[Required]public string Password { get; set; }/// <summary>/// 用户角色/// </summary>[Required]public AuthorizeRoleName RoleName { get; set; }
}

再在生成token的时候往claims中加入 

new Claim("RoleName",user.RoleName.ToString()),

这样,我们调用GetToken接口时就可以设置角色,并存储到token中。

 

我们来进行测试一下,将接口获取到的token放到在线解析工具JSON Web Tokens - jwt.io中解析一下,可以看到已经有RoleeName的信息了。

增加AdminAuthorizeAttribute类

  • 用途:这是一个自定义的属性(Attribute),继承自TypeFilterAttribute。它允许开发者通过在其上指定AuthorizeRoleName枚举值,来标记哪些类或方法需要特定的角色授权。
  • 构造函数:接收一个AuthorizeRoleName枚举类型的参数role,该参数用于指定允许访问的角色。在构造函数中,它调用了基类TypeFilterAttribute的构造函数,并传入了AdminAuthorizeFilter类型的实例,同时将role作为参数传递给AdminAuthorizeFilter
  • 特性:通过AttributeUsage特性指定了这个自定义属性可以应用于类(Class)或方法(Method),并且允许多次应用(AllowMultiple = true),还可以被子类继承(Inherited = true)。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = true)]
public class AdminAuthorizeAttribute : TypeFilterAttribute
{public AuthorizeRoleName Role { get; }public AdminAuthorizeAttribute(AuthorizeRoleName role) : base(typeof(AdminAuthorizeFilter)){Role = role;Arguments = new object[] { role };}
}

:base(typeof(AdminAuthorizeFilter)): 这是构造函数的初始化器(Constructor Initializer),它调用了基类TypeFilterAttribute的构造函数,并传递了一个参数typeof(AdminAuthorizeFilter)。typeof(AdminAuthorizeFilter)是一个Type对象,它表示AdminAuthorizeFilter类的类型信息。这里,它告诉TypeFilterAttribute,当这个自定义属性被应用时,应该使用AdminAuthorizeFilter类作为过滤器。

增加AdminAuthorizeFilter类 

  • 接口实现:实现了IAuthorizationFilter接口,这意味着它将在MVC或Razor Pages的授权流程中被调用。
  • 构造函数:接收一个AuthorizeRoleName枚举类型的参数role,这个参数是通过AdminAuthorizeAttribute传递过来的,用于指定允许访问的角色。
  • OnAuthorization方法:这是授权逻辑的核心。首先,它检查用户是否已认证(即是否已经登录)。如果用户未认证,则返回一个ChallengeResult,这通常会导致用户被重定向到登录页面。如果用户已认证,则通过调用GetCurrentUserRole方法获取用户的角色,并与允许的角色进行比较。如果用户角色不匹配,则返回一个ForbidResult,这通常表示用户没有权限访问该资源,并返回403 Forbidden状态码。
  • GetCurrentUserRole方法:这是一个辅助方法,用于从HttpContext中提取用户的角色信息。它查找用户声明(Claims)中类型为"RoleName"的声明,并将其值尝试转换为AuthorizeRoleName枚举类型。如果转换成功,则返回该枚举值;如果失败或找不到角色声明,则抛出异常。
public class AdminAuthorizeFilter : IAuthorizationFilter
{private readonly AuthorizeRoleName _role;public AdminAuthorizeFilter(AuthorizeRoleName role){_role = role;}public void OnAuthorization(AuthorizationFilterContext context){// 检查用户是否已认证  if (!context.HttpContext.User.Identity.IsAuthenticated){context.Result = new ChallengeResult();return;}// 检查用户是否属于指定的角色通,常涉及到检查用户的Claims或其他安全令牌中的信息  // 我们有一个方法GetCurrentUserRole()来获取当前用户的角色  var userRole = GetCurrentUserRole(context.HttpContext); if (userRole != _role){context.Result = new ForbidResult(); // 或者返回403 Forbidden,取决于你的需求  }}// private AuthorizeRoleName GetCurrentUserRole(HttpContext context){var user = context.User;var roleClaim = user.Claims.FirstOrDefault(c => c.Type == "RoleName");if (roleClaim != null){// 将 Claim 的 Value 转换为 AuthorizeRoleName 枚举  // 这里需要实现一个转换逻辑,因为 Claim 的 Value 是字符串   if (Enum.TryParse<AuthorizeRoleName>(roleClaim.Value, true, out var role)){return role;}throw new InvalidOperationException("无法确定用户的角色!");}throw new InvalidOperationException("角色信息为空!");}
}

调整获取用户信息接口

在之前的GetUser接口上增加属性标签

[AdminAuthorize(AuthorizeRoleName.Administrator)]

表示只有role为 Administrator 的角色才能访问此接口。

 测试一下!

当GetToken时设置Role为0,即(Administrator )时,获得的token去访问GetUser时是可以的。

设置为其他时,则断点会进入这里,接口返回403

项目代码

该项目的案例源代码我已经上传至gitee,需要的可自取

AuthenticationAndAuthorization: .net Core Web Api的Token生成,JWT签名,验证与授权 (gitee.com)icon-default.png?t=N7T8https://gitee.com/libihao520/authentication-and-authorization

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • WordPress网站被入侵,劫持收录事件分析
  • RocketMQ 的消息跟踪机制
  • 【C语言】结构体内存布局解析——字节对齐
  • C# 工厂方法模式
  • 嵌入式linux相机 图像处理模块
  • 【学习方法】高效学习因素 ① ( 开始学习 | 高效学习因素五大因素 | 高效学习公式 - 学习效果 = 时间 x 注意力 x 精力 x 目标 x 策略 )
  • 解析Java中1000个常用类:HashSet类,你学会了吗?
  • 【保姆级系列:锐捷模拟器的下载安装使用全套教程】
  • Pr2024苹果(mac)版剪辑软件安装下载(附下载链接)
  • 计算机毕业设计Hadoop+Hive专利分析可视化 面向专利的大数据管理系统 专利爬虫 专利数据分析 大数据毕业设计 Spark
  • 基于切片法计算点云体积 双向最近点三维点排序
  • (计算机网络)物理层
  • 利用Dockerfile文件执行docker build自动构建镜像
  • 【java】单行注释(//)与多选注释(/* */)
  • 【iOS】APP仿写——天气预报
  • 【翻译】babel对TC39装饰器草案的实现
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • chrome扩展demo1-小时钟
  • Fabric架构演变之路
  • HashMap剖析之内部结构
  • javascript面向对象之创建对象
  • JavaWeb(学习笔记二)
  • JS题目及答案整理
  • js中forEach回调同异步问题
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • Redis字符串类型内部编码剖析
  • Vue2.0 实现互斥
  • vue2.0项目引入element-ui
  • Vue全家桶实现一个Web App
  • 服务器从安装到部署全过程(二)
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 面试总结JavaScript篇
  • 目录与文件属性:编写ls
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 用 vue 组件自定义 v-model, 实现一个 Tab 组件。
  • Oracle Portal 11g Diagnostics using Remote Diagnostic Agent (RDA) [ID 1059805.
  • ​经​纬​恒​润​二​面​​三​七​互​娱​一​面​​元​象​二​面​
  • # Python csv、xlsx、json、二进制(MP3) 文件读写基本使用
  • # 利刃出鞘_Tomcat 核心原理解析(二)
  • #[Composer学习笔记]Part1:安装composer并通过composer创建一个项目
  • #include
  • #NOIP 2014# day.1 T2 联合权值
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (01)ORB-SLAM2源码无死角解析-(66) BA优化(g2o)→闭环线程:Optimizer::GlobalBundleAdjustemnt→全局优化
  • (13)DroneCAN 适配器节点(一)
  • (2024,Vision-LSTM,ViL,xLSTM,ViT,ViM,双向扫描)xLSTM 作为通用视觉骨干
  • (八)c52学习之旅-中断实验
  • (搬运以学习)flask 上下文的实现
  • (回溯) LeetCode 77. 组合
  • (回溯) LeetCode 78. 子集
  • (强烈推荐)移动端音视频从零到上手(下)
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (十六)一篇文章学会Java的常用API
  • (一)WLAN定义和基本架构转
  • (原創) X61用戶,小心你的上蓋!! (NB) (ThinkPad) (X61)