后端进阶之路——浅谈Spring Security用户、角色、权限和访问规则(三)

前言

在这里插入图片描述
「作者主页」:雪碧有白泡泡
「个人网站」:雪碧的个人网站
「推荐专栏」

java一站式服务
前端炫酷代码分享
uniapp-从构建到提升
从0到英雄,vue成神之路
解决算法,一个专栏就够了
架构咱们从0说
★ 数据流通的精妙之道★

★后端进阶之路★

请添加图片描述

在这里插入图片描述

文章目录

  • 前言
  • 引言
  • 1. 定义用户
    • 使用内存方式定义用户
    • 使用数据库方式定义用户
  • 2. 定义角色
    • 创建角色并将其与用户关联
    • 解释如何使用角色来组织和控制权限
  • 3. 定义权限
  • 4. 访问规则
      • 使用Ant风格的路径匹配规则
      • 使用表达式语言进行更复杂的访问规则定义
  • 小结

引言

继上篇后端进阶之路——深入理解Spring Security配置(二)
在这里插入图片描述

1. 定义用户

使用内存方式定义用户

在内存中定义用户是一种简单的方法,适用于开发和测试环境。我们可以在Spring Security的配置类中使用InMemoryUserDetailsManager来定义用户。下面是一个示例:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.inMemoryAuthentication().withUser("user").password("{noop}password") // 使用 "{noop}" 前缀表示密码不加密.roles("USER");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().formLogin();}
}

上述示例中,使用withUser方法定义了一个用户名为"user",密码为"password",角色为"USER"的用户。注意,密码的前缀"{noop}"表示密码不加密,这只适用于开发和测试环境。

使用数据库方式定义用户

在实际生产环境中,通常会将用户信息存储在数据库中。使用数据库方式定义用户需要进行以下步骤:

  1. 创建数据库表格来存储用户信息,例如表格名为"users",包含列"username"、“password"和"role”。
  2. 配置Spring Security以连接到数据库,并使用数据库中的用户信息进行认证和授权。

下面是一个使用数据库方式定义用户的示例:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate DataSource dataSource;@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.jdbcAuthentication().dataSource(dataSource).usersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username=?").authoritiesByUsernameQuery("SELECT username, role FROM users WHERE username=?");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().anyRequest().authenticated().and().formLogin();}
}

上述示例中,通过dataSource注入了数据源,然后使用jdbcAuthentication配置了基于数据库的认证和授权。.usersByUsernameQuery()方法指定了查询用户名、密码和启用状态的SQL语句,.authoritiesByUsernameQuery()方法指定了查询用户名和角色的SQL语句。

2. 定义角色

在Spring Security中,可以使用角色来组织和控制权限。角色是一组权限的集合,可以通过将角色与用户关联来授予用户相应的权限。

以下是在Spring Security中定义角色并将其与用户关联的示例代码:

创建角色并将其与用户关联

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate DataSource dataSource;@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.jdbcAuthentication().dataSource(dataSource).usersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username=?").authoritiesByUsernameQuery("SELECT username, role FROM users WHERE username=?");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN") // 需要"ADMIN"角色才能访问"/admin/**"路径.anyRequest().authenticated().and().formLogin();}
}

在上述示例中,.antMatchers("/admin/**").hasRole("ADMIN")指定了只有拥有"ADMIN"角色的用户才能访问"/admin/**"路径。这样,我们可以根据不同的角色来限制用户对某些资源的访问权限。

解释如何使用角色来组织和控制权限

在Spring Security中,可以使用角色来定义访问控制规则,并使用这些规则来保护应用程序的不同部分。通过为用户分配不同的角色,可以实现对不同用户的权限控制。

以下是一个使用角色进行权限控制的示例代码:

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate DataSource dataSource;@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.jdbcAuthentication().dataSource(dataSource).usersByUsernameQuery("SELECT username, password, enabled FROM users WHERE username=?").authoritiesByUsernameQuery("SELECT username, role FROM users WHERE username=?");}@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN") // 需要"ADMIN"角色才能访问"/admin/**"路径.antMatchers("/user/**").hasRole("USER") // 需要"USER"角色才能访问"/user/**"路径.anyRequest().authenticated().and().formLogin();}
}

上述示例中,使用.antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasRole("USER")定义了不同路径需要不同角色的访问权限。只有拥有相应角色的用户才能访问对应的路径。

3. 定义权限

权限是指在系统中对特定资源或操作进行访问控制的能力。它是用于确保只有经过授权的用户或角色才能执行某些敏感操作或访问某些受限资源的机制。权限的定义和管理对于确保系统的安全性和保护重要数据非常重要。

在Spring Security中,我们可以使用@PreAuthorize@PostAuthorize@Secured等注解来定义权限。这些注解可以放置在方法上,用于限制只有具有特定权限的用户才能调用该方法。

下面是一个示例,演示了如何在Spring Security中定义权限:

首先,确保你已经添加了Spring Security的依赖到你的项目中。

<!-- pom.xml -->
<dependencies>...<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>...
</dependencies>

接下来,创建一个自定义的权限验证类。

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;@Component
public class MyAuthorization {@PreAuthorize("hasRole('ROLE_ADMIN')")public void adminOnly() {// 只有具有ROLE_ADMIN角色的用户才能调用此方法}@PreAuthorize("hasAuthority('WRITE_PERMISSION')")public void writeAccess() {// 只有具有WRITE_PERMISSION权限的用户才能调用此方法}}

在上述代码中,MyAuthorization类包含了两个方法:adminOnly()writeAccess()。这两个方法都使用了@PreAuthorize注解来定义权限。

hasRole('ROLE_ADMIN')表示只有具有ROLE_ADMIN角色的用户才能调用adminOnly()方法。

hasAuthority('WRITE_PERMISSION')表示只有具有WRITE_PERMISSION权限的用户才能调用writeAccess()方法。

然后,在你的业务逻辑中,可以通过依赖注入的方式使用MyAuthorization类,并调用相应的方法。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;@Service
public class MyService {private final MyAuthorization myAuthorization;@Autowiredpublic MyService(MyAuthorization myAuthorization) {this.myAuthorization = myAuthorization;}public void doSomething() {myAuthorization.adminOnly(); // 调用需要admin权限的方法myAuthorization.writeAccess(); // 调用需要writeAccess权限的方法}}

在上述代码中,MyService类依赖注入了MyAuthorization类,并在doSomething()方法中调用了其中的两个方法。

4. 访问规则

当使用Spring Security进行访问控制时,可以通过Ant风格的路径匹配规则和表达式语言来定义更复杂的访问规则。下面是一些示例代码片段,用于说明如何使用这些规则:

使用Ant风格的路径匹配规则

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/admin/**").hasRole("ADMIN").antMatchers("/user/**").hasAnyRole("USER", "ADMIN").anyRequest().authenticated().and().formLogin().and().httpBasic();}
}

在上述代码中,我们使用authorizeRequests()方法来配置路径的访问规则。.antMatchers()方法用于指定要匹配的路径模式,并使用hasRole()hasAnyRole()方法指定需要具有的角色。在这个例子中,如果请求的路径以"/admin/"开头,则用户需要具有"ADMIN"角色。

使用表达式语言进行更复杂的访问规则定义

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().expressionHandler(expressionHandler()).antMatchers("/admin/**").access("hasRole('ADMIN') or hasIpAddress('127.0.0.1')").anyRequest().authenticated().and().formLogin().and().httpBasic();}@Beanpublic DefaultWebSecurityExpressionHandler expressionHandler() {DefaultWebSecurityExpressionHandler expressionHandler = new DefaultWebSecurityExpressionHandler();expressionHandler.setRoleHierarchy(roleHierarchy());return expressionHandler;}@Beanpublic RoleHierarchy roleHierarchy() {RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");return roleHierarchy;}
}

在上述代码中,我们使用.access()方法来定义更复杂的访问规则。这里我们使用表达式语言,可以通过hasRole()hasIpAddress()等方法来判断用户是否有权限访问路径。在这个例子中,如果请求的路径以"/admin/“开头,并且用户具有"ADMIN"角色或者IP地址为"127.0.0.1”,则允许访问。

另外,我们还使用DefaultWebSecurityExpressionHandlerRoleHierarchyImpl来配置角色层次关系。在这个例子中,"ROLE_ADMIN"角色被认为是"ROLE_USER"角色的父角色,因此具有"ROLE_ADMIN"角色的用户也将被授予"ROLE_USER"角色的权限。

小结

通过定义用户、角色、权限和访问规则
可以在SpringSecurity中实现灵活的访问控制和权限管理。可以使用内存方式或数据库方式定义用户,设置用户名、密码和角色等信息。角色可以用来组织和控制权限,可以将一组权限赋予特定角色,并将角色分配给用户。权限是指用户可以执行的特定操作或访问的资源,可以细化到每个功能或数据级别。可以使用Ant风格的路径匹配规则或表达式语言编写更复杂的访问规则,以限制用户对特定路径或功能的访问权限。
通过定义这些元素,可以确保系统的安全性和可靠性。

在这里插入图片描述

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

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

相关文章

代码随想录算法训练营day48

文章目录 Day48 打家劫舍题目思路代码 打家劫舍II题目思路代码 打家劫舍 III题目思路代码递归去偷动态规划法&#xff08;状态标记递归&#xff09; Day48 打家劫舍 198. 打家劫舍 - 力扣&#xff08;LeetCode&#xff09; 题目 你是一个专业的小偷&#xff0c;计划偷窃沿街…

两数相加 II

给你两个 非空 链表来代表两个非负整数。数字最高位位于链表开始位置。它们的每个节点只存储一位数字。将这两数相加会返回一个新的链表。 你可以假设除了数字 0 之外&#xff0c;这两个数字都不会以零开头。 示例1&#xff1a; 输入&#xff1a;l1 [7,2,4,3], l2 [5,6,4] 输…

什么是 webpack?

Webpack 介绍 什么是 webpack&#xff1f; :::tip 官方描述 webpack 是一个用于现代 JavaScript 应用程序的静态模块打包工具。当 webpack 处理应用程序时&#xff0c;它会在内部从一个或多个入口点构建一个 依赖图(dependency graph)&#xff0c;然后将你项目中所需的每一个…

【SCSS】网格布局中的动画

效果 index.html <!DOCTYPE html> <html><head><title> Document </title><link type"text/css" rel"styleSheet" href"index.css" /></head><body><div class"container">&l…

C 语言高级2-多维数组,结构体,递归操作

1. 多维数组 1.1 一维数组 元素类型角度&#xff1a;数组是相同类型的变量的有序集合内存角度&#xff1a;连续的一大片内存空间 在讨论多维数组之前&#xff0c;我们还需要学习很多关于一维数组的知识。首先让我们学习一个概念。 1.1.1 数组名 考虑下面这些声明&#xff1…

react中使用redux-persist做持久化储存

某天下午折腾着玩的 – 笔记 安装相关依赖 npm install reduxjs/toolkit redux-persist redux react-redux// store.jsx import { configureStore, getDefaultMiddleware } from "reduxjs/toolkit"; import { persistStore, persistReducer } from "redux-per…

无涯教程-Lua - 调试语句

Lua提供了一个调试库&#xff0c;该库提供了所有原始函数供无涯教程创建自己的调试器。即使没有内置的Lua调试器&#xff0c;也有许多针对Lua的调试器&#xff0c;这些调试器由各种开发人员创建&#xff0c;其中许多开源。 下表列出了Lua调试库中可用的函数及其用法。 Sr.No.…

Apache RocketMQ 命令注入

漏洞简介 RocketMQ 5.1.0及以下版本&#xff0c;在一定条件下&#xff0c;存在远程命令执行风险。RocketMQ的NameServer、Broker、Controller等多个组件外网泄露&#xff0c;缺乏权限验证&#xff0c;攻击者可以利用该漏洞利用更新配置功能以RocketMQ运行的系统用户身份执行命令…

论文阅读- Uncovering Coordinated Networks on Social Media:Methods and Case Studies

链接&#xff1a;https://arxiv.org/pdf/2001.05658.pdf 目录 摘要&#xff1a; 引言 Methods Case Study 1: Account Handle Sharing Coordination Detection 分析 Case Study 2: Image Coordination Coordination Detection Analysis Case Study 3: Hashtag Sequen…

k8s手动发布镜像的方法

kubectl edit deploy编辑对应的文件&#xff0c;并:wq!保存即可

2023年第四届“华数杯”数学建模思路 - 案例:FPTree-频繁模式树算法

## 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模式树算法&#xff0c;他与Apriori算法一样也是用来挖掘频繁项集的&#xff0c…

互联网摸鱼日报(2023-08-03)

互联网摸鱼日报(2023-08-03) 36氪新闻 飞行汽车风口来了&#xff0c;什么时候我能坐上&#xff1f; 小红书的本地生活&#xff0c;还在玩票期 并行科技8月8日北交所上会&#xff0c;主营业务为超算云服务和算力运营服务 群玉山咨询马晓波&#xff1a;新消费品牌如何通过赛道…

21.Netty源码之编码器

highlight: arduino-light Netty如何实现自定义通信协议 在学习完如何设计协议之后&#xff0c;我们又该如何在 Netty 中实现自定义的通信协议呢&#xff1f;其实 Netty 作为一个非常优秀的网络通信框架&#xff0c;已经为我们提供了非常丰富的编解码抽象基类&#xff0c;帮助我…

sklearn 转换器和预估器

刚学习sklearn时&#xff0c;没分清转换器的fit&#xff08;&#xff09;和模型训练的fit&#xff08;&#xff09;&#xff0c;还以为是一个&#xff0c;结果学完了回过头来&#xff0c;才发现这些差异。再此记录一下。 一、 sklearn 转换器和预估器 转换器&#xff08;Trans…

Java--学生管理系统

本案例基于Java语言中的ArrayList集合来储存数据&#xff0c;并建立两个类——学生类和用户类存储在集合中&#xff0c;通过用户交互&#xff0c;搭建简单的学生管理系统。 1、学生类 学生类利用set函数进行获取学生单个信息&#xff0c;show函数负责获取全部信息。 package …

LCD驱动芯片VK1024B兼容HT系列驱动芯片,体积更小

产品型号&#xff1a;VK1024B 产品&#xff1a;VINKA/永嘉微电 封装形式&#xff1a;SOP16 产品年份&#xff1a;新年份 工程服务&#xff0c;技术支持&#xff0c;用芯服务 VK1024概述&#xff1a; VK1024B 是 24 点、 内存映象和多功能的 LCD 驱动&#xff0c; VK1024B …

Nginx实现反向代理和负载均衡

Nginx安装 本文章主要介绍下&#xff0c;如何使用Nginx来实现反向代理和负载均衡&#xff0c;Nginx安装和基础知识&#xff0c;可参考我的这篇文章 Nginx安装。 Nginx实现反向代理 实现反向代理需要准备两台Nginx服务器。一台Nginx服务器A&#xff0c;ip为 192.168.206.140&…

MySQL主从复制入门指南:基础概念和配置步骤

文章目录 前言一、问题分析二、Mysql主从复制1. 介绍2. 配置3. 测试 三、读写分离案例1. 背景2. shardingDBC介绍3. 入门案例4. 功能测试 总结 前言 为了巩固所学的知识&#xff0c;作者尝试着开始发布一些学习笔记类的博客&#xff0c;方便日后回顾。当然&#xff0c;如果能帮…

基于freertos的温湿度蓝牙系统

前言&#xff1a;本项目主要是基于freertos的小项目&#xff0c;目的是为了巩固近期学习的知识&#xff0c;功能较简单&#xff0c;可自行扩充。 一、项目基本架构 项目基本功能&#xff1a;通过STM32单片机的freertos操作系统&#xff0c;将温湿度数据显示在oled屏幕上&#…

节流函数(执行最后一次)

节流函数的主要目的是限制一个函数在一定时间内只能执行一次。以下是一个使用JavaScript编写的基本节流函数&#xff1a; function throttle(func, delay) {let lastCall 0;return function() {const now new Date().getTime();if (now - lastCall < delay) {return;}las…