Spring Security 中的RBAC角色和权限

news/2024/5/5 13:56:31/文章来源:https://blog.csdn.net/allway2/article/details/126971435

在这篇文章中,我们将看看使用 Spring boot的R ole B ased A ccess Control ( RBAC )。

了解 RBAC

在 RBAC 模型中存在三个关键实体。他们是,

  1. 用户或主题 ——执行操作的系统参与者。它可以代表一个自然人、一个自动帐户,甚至是另一个应用程序。
  2. 角色 ——由职位、部门或职能层次结构定义的权限级别。
  3. 特权——执行操作的批准或许可

话虽如此,以下是这些实体如何相互映射的说明。

基本上,用户可以执行操作。要执行操作,他们需要具有一定的权限或特权。这就是为什么将权限分配给角色而将角色分配给用户的原因。让我们看看如何实现这些。

RBAC 实体

让我们创建上述对象以表示为数据库实体。

用户实体

@Data
@Entity
public class UserAccount {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;@Column(unique = true)private String username;private String password;private boolean active;@OneToMany(mappedBy = "user")private List<UserToRole> userToRoles;
}

用户角色实体

@Data
@Entity
public class UserRole {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;private String roleName;@OneToMany(mappedBy = "role")private List<UserRoleToPrivilege> userRoleToPrivileges;
}

UserPrivileges 实体

@Data
@Entity
public class UserPrivilege {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;private String privilegeName;
}

UserRoleToPrivilege 实体

@Data
@Entity
public class UserRoleToPrivilege {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;@ManyToOneprivate UserRole role;@ManyToOneprivate UserPrivilege privilege;
}

UserToRole 实体

@Data
@Entity
public class UserToRole {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;@ManyToOneprivate UserAccount user;@ManyToOneprivate UserRole role;
}

填充数据库条目

有了上述实体,让我们用适当的角色和权限填充数据库。对于这个测试,我使用 data.sql 文件直接输入了条目。

insert into user_account(id, username, password, active) values (1, 'user1', '{noop}user1', 1);
insert into user_account(id, username, password, active) values (2, 'user2', '{noop}user2', 1);
insert into user_account(id, username, password, active) values (3, 'admin', '{noop}admin', 1);
insert into user_role(id, role_name) values (1, 'USER');
insert into user_role(id, role_name) values (2, 'ADMIN');
insert into user_to_role(id, user_id, role_id) values (1, 1, 1);
insert into user_to_role(id, user_id, role_id) values (2, 2, 1);
insert into user_to_role(id, user_id, role_id) values (3, 3, 2);
insert into user_privilege(id, privilege_name) values (1, 'canReadUser');
insert into user_privilege(id, privilege_name) values (2, 'canReadAdmin');
insert into user_role_to_privilege(id, role_id, privilege_id) values (1, 1, 1);
insert into user_role_to_privilege(id, role_id, privilege_id) values (2, 2, 1);
insert into user_role_to_privilege(id, role_id, privilege_id) values (3, 2, 2);

请注意,我使用的是  NoOpPasswordEncoder ,因为密码前面带有 {noop}.

Spring Security userDetailsS​​ervice

在我们之前的帖子中,我们总是使用一个角色来调用 USER 系统中的所有用户。但是,我们需要进行更改以从数据库中选择这些角色和权限。这是一个如何做到这一点的粗略示例。

@Component
public class DatabaseUserDetailsService implements UserDetailsService {private finalUserAccountRepository userAccountRepository;public DatabaseUserDetailsService(UserAccountRepository userAccountRepository) {this.userAccountRepository = userAccountRepository;}@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {UserAccount userAccount = userAccountRepository.findByUsername(username);if (userAccount == null) {throw new UsernameNotFoundException("User with username [" + username + "] not found in the system");}Set<GrantedAuthority> authorities = new HashSet<>();for (UserToRole userToRole : userAccount.getUserToRoles()) {authorities.add(new SimpleGrantedAuthority("ROLE_" + userToRole.getRole().getRoleName()));for (UserRoleToPrivilege userRoleToPrivilege : userToRole.getRole().getUserRoleToPrivileges()) {authorities.add(new SimpleGrantedAuthority(userRoleToPrivilege.getPrivilege().getPrivilegeName()));}}return new CustomUserDetails(userAccount.getUsername(), userAccount.getPassword(), userAccount.isActive(), authorities);}
}

这里要注意的一件有趣的事情是,我们添加了角色和权限作为权限。但是,所有角色都以 ROLE_. 这种特定的方式是由于安全表达式的喜欢 hasRole 和 hasAuthority 工作方式。

这样,开发人员可以使用表达式为 url 映射设置角色级别和权限级别设置,您将在下面看到。

保护 API 端点

使用 WebSecurityConfigurerAdapter,您可以自定义谁可以访问哪个 URL。看看这个配置片段。

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/user").access("hasAuthority('canReadUser')").antMatchers("/admin").access("hasAuthority('canReadAdmin')").anyRequest().authenticated().and().httpBasic().and().formLogin();}
}

在这里, admin 用户可以同时访问 /user 和 /admin 因为 ADMIN 角色同时拥有 canReadUser 和 canReadAdmin 权限。但是, user1 或者 user2 无法访问 /admin ,因为他们会得到 403 Forbidden 响应。

有了以上所有内容,让我们测试结果。

$ curl -i -u "user1:user1" http://localhost:8080/user
HTTP/1.1 200
Set-Cookie: JSESSIONID=9BEC44655277BBDF6832817AFF4CAAA1; Path=/; HttpOnly
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: text/plain;charset=UTF-8
Content-Length: 11
Date: Tue, 29 Dec 2020 15:16:57 GMTHello user!
$ curl -i -u "user1:user1" http://localhost:8080/admin
HTTP/1.1 403
Set-Cookie: JSESSIONID=0910F6115CB28A9DF914D22052396448; Path=/; HttpOnly
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Type: application/json
Transfer-Encoding: chunked
Date: Tue, 29 Dec 2020 15:17:28 GMT{"timestamp" : "2020-12-29T15:17:28.537+00:00","status" : 403,"error" : "Forbidden","message" : "","path" : "/admin"
}

如您所见,当 user1 尝试访问 /admin 端点时,他们会收到 403 - Forbidden 消息。

这是供您学习本教程的GitHub 存储库。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_11461.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

专业思维导图软件 Mindjet MindManager 2021下载

Mindjet MindManager 2021 是一款专业的思维导图软件&#xff0c;美国Mindjet公司开发&#xff0c;一款视觉工作管理的思维导图软件&#xff0c;界面友好功能强大&#xff0c;头脑风暴、会议管理及项目管理工具帮您轻松创建思维导图&#xff0c;有序组织思维、资源和项目进程。…

win10+cuda+cudnn+anconda+pytorch+pycharm全家桶安装

1、下载安装cuda&#xff1a; 网址&#xff1a;CUDA Toolkit 11.7 Update 1 Downloads | NVIDIA Developer 网址下方可以找到以前版本 安装完后&#xff0c;可以在命令行窗口输入nvcc --version查看cuda版本是否正确 显卡驱动版本与cuda版本对应关系&#xff1a; 2、安装cud…

操作系统实验四 进程间通信

★观前提示&#xff1a;本篇内容为操作系统实验内容&#xff0c;代码等内容经测试没有问题&#xff0c;但是可能会不符合每个人实验的要求&#xff0c;因此以下内容建议仅做思路参考。 目录一、实验目的二、实验内容三、具体实现四、实验总结一、实验目的 多道程序设计中&…

【前端面试】-- 必知必会的promise题

Promise 想必大家都十分熟悉&#xff0c;想想就那么几个 api&#xff0c;可是你真的了解 Promise 吗&#xff1f; 请迎接测试: 以下 promise 均指代 Promise 实例&#xff0c;环境是 Node.js 题目一&#xff1a; const promise new Promise((resolve, reject) > {conso…

ES8JC-ASEMI快恢复二极管ES8JC

编辑:ll ES8JC-ASEMI快恢复二极管ES8JC 型号:ES8JC 品牌:ASEMI 封装:SMC 特性:快恢复二极管 正向电流:8A 反向耐压:600V 恢复时间:35ns 引脚数量:2 芯片个数:1 芯片尺寸:84MIL 浪涌电流:125A 漏电流:<5ua 工作温度:-40℃~150℃ 包装方式:30/管;3000/箱 备受…

华为云各Region网络延迟实测

一、测试综述 测试内容&#xff1a; 序号 评测内容 测试日期 1 华为云各大区公网接入网络延迟 2022-09-20 2 华为云各大区之间网络延迟&#xff08;通过公网&#xff09; 2022-09-20 3 华为云各大区之间网络延迟&#xff08;通过云连接&#xff09; 2022-09-20 测…

【Linux】聊聊删文件的那些破事

聊聊删文件的那些破事前言正文rm命令find命令perl方式10w文件删除对比50w文件删除对比100w文件删除对比结语前言 在操作系统的日常运维中&#xff0c;我们经常会做文件的创建、删除、修改操作&#xff0c;尤其是删除&#xff0c;无论是定期清理日志文件&#xff0c;还是做完一…

传统光流方法汇总

又搬运了一个3d视觉相关的~~ 还是先道歉 就是学习用 还是公交上回家看那种 ~~ 这次分享传统光流方法汇总及其在深度学习中的应用&#xff01;&#xff08;基于相位/能量/匹配/变分&#xff09; 回望传统光流估计方法 近年来&#xff0c;随着深度学习技术的快速发展&#xff…

嵌入式分享合集63

一、PCB为什么一定要做阻抗 在具有电阻、电感和电容的电路里&#xff0c;对交流电所起的阻碍作用叫做阻抗。阻抗常用Z表示&#xff0c;是一个复数&#xff0c;实部称为电阻&#xff0c;虚部称为电抗。 其中电容在电路中对交流电所起的阻碍作用称为容抗&#xff0c;电感在电路…

Pr:多机位编辑

很多时候一个机位满足不了影视创作的需求。比如拍摄人物动作&#xff0c;如果能使远景、近景、特写等一些镜头相互衔接&#xff0c;将会使得角色显得更加丰富饱满。不同的景别传达着不同的信息&#xff0c;更容易交待环境和表达角色的情绪。早期人们在拍摄的同时完成多机位切换…

应用层 HTTP 代理服务器转发消息时的相关头部 请求头 X-Forwarded-For

在http消息传递过程当中会经过很多正向代理服务器和反向代理服务器&#xff0c;这些代理服务器在转发消息的时候会涉及到http的头部&#xff0c;下面将会介绍这些头部&#xff0c;包括由于存在这些代理服务器所以客户端和源服务器之前有许多的tcp连接&#xff0c;有一些http头部…

Flutter快学快用15 服务通信:Flutter 中常见的网络协议

上一课时之前&#xff0c;我们的接口都是在代码中模拟假数据&#xff0c;并没有从服务端获取数据&#xff0c;但是在实际开发中&#xff0c;必须与服务端进行交互。本课时主要介绍在 Flutter 中常见的网络传输协议序列化方式&#xff0c;并对其中比较常用的协议进行简单实践&am…

大数据培训技术phoenix表操作

phoenix表操作 1 显示所有表 &#xff01;table 或 &#xff01;tables 2 创建表 CREATE TABLE IF NOT EXISTS us_population ( State CHAR(2) NOT NULL, City VARCHAR NOT NULL, Population BIGINT CONSTRAINT my_pk PRIMARY KEY (state, city)); 如下显示&#xff1a; 在p…

超级基础篇_疑惑实验

1、多态&#xff1a; 多态是什么&#xff1f; 多态是同一个行为具有多个不同表现形式或形态的能力。 多态就是同一个接口&#xff0c;使用不同的实例而执行不同操作多态的优点 1.消除类型之间的耦合关系 2. 可替换性 3. 可扩充性 …

树的应用 —— 二叉树:二叉树的性质

树的应用 —— 二叉树 二叉树&#xff08;Binary Tree&#xff09;是n &#xff08;n ≥0&#xff09;个节点构成的集合&#xff0c;或为空树&#xff08;n 0&#xff09;&#xff0c;或为非空树。 对于非空树T &#xff0c;要满足&#xff1a; ①有且仅有一个被称为根的节点…

FFmpeg入门详解之20:视频编码原理简介

视频为何需要压缩&#xff1f; 原因&#xff1a;未经压缩的数字视频的数据量巨大 ● 存储困难 ○ 一G只能存储几秒钟的未压缩数字视频。 ● 传输困难 ○ 1兆的带宽传输一秒的数字电视视频需要大约4分钟。 主要压缩了什么东西&#xff1f; 原始视频压缩的目的是去除冗余信息&a…

结构体的理解

结构体前言结构体&#xff1f;定义变量如何赋初值&#xff1f;结构体的访问结构体的嵌套使用注意事项结构体的大小内存对齐默认对齐数的修改为什么存在内存对齐&#xff1f;结构体传参位段什么是位段&#xff1f;位段的内存分配深入剖析位段“存”数据位段的“取”位段的跨平台…

Idea工具中,使用Mapper对象有红线

背景&#xff1a; IDEA开发工具&#xff0c;springboot mybatis项目 &#xff08;这个是不需要改的&#xff0c;也不算是问题&#xff0c;因为项目并不会报错&#xff0c;只是作者好奇找了下问题&#xff0c;并记录一下&#xff09; 问题描述 mapper对象在service层有红线&a…

8 位卷王!总结 1135 页 Java 核心面试手册,硬钢 BATJ 一线大厂面试官

又到了金九银十求职季&#xff01; HR 开始拼业绩&#xff0c;招聘网站也开始释放出大量岗位&#xff0c;转行跳槽、毕业求职的人都开始行动起来&#xff01; 此时&#xff0c;对于大多数程序员来说&#xff0c;最大的目标就是&#xff1a;进大厂&#xff01; 大厂为什么这么…

ArcGIS Map Sdk for unity使用

本文主要讨论离线模式。 目录 1.底图tpk文件制作 2.3D图层slpk文件制作 3.导入使用 1.底图tpk文件制作 软件&#xff1a;91卫图助手 Arcgis Pro 操作步骤&#xff1a; 打开91卫图助手&#xff0c;更换底图为高德影像/腾讯影像。(百度影像的地理投影格式有自身加密&#xff…