01-Spring Security框架的认证和授权测试

Spring Security

介绍

认证功能与业务无关几乎是每个项目都要具备的功能,市面上有很多认证框架如Apache Shiro、CAS、Spring Security

  • Spring Security是Spring家族的一份子且和Spring Cloud集成的很好,所以本项目采用Spring Security作为认证服务的技术框架

Spring Security是一个功能强大且可高度定制的身份验证和访问控制框架,它是一个专注于为Java应用程序提供身份验证和授权的框架

创建认证服务初始工程

第一步: 在项目根目录下创建一个普通的SpringBoot工程xuecheng-plus-auth,这个工程可以连接数据库但不具备认证授权功能

第二步: 执行xcplus_users.sql脚本创建xc_users数据库

第三步: 在nacos服务端中新增auth-service-dev.yaml配置文件

server:servlet:context-path: /authport: 53070
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/xc_users?serverTimezone=UTC&userUnicode=true&useSSL=false&username: rootpassword: 123456

第四步: 创建Controller类编写控制器方法,启动工程尝试访问localhost:53070/auth/user/52可以正常访问到数据

package com.xuecheng.auth.controller;
@Slf4j
@RestController
public class LoginController {@AutowiredXcUserMapper userMapper;@RequestMapping("/login-success")public String loginSuccess() {return "登录成功";}@RequestMapping("/user/{id}")public XcUser getuser(@PathVariable("id") String id) {XcUser xcUser = userMapper.selectById(id);return xcUser;}@RequestMapping("/r/r1")public String r1() {return "访问r1资源";}@RequestMapping("/r/r2")public String r2() {return "访问r2资源";}
}

认证测试

第一步: 在xuecheng-plus-auth服务工程中添加Spring Security框架所需的依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>

第二步: 重启工程访问localhost:53070/auth/r/r1会自动进入/login页面,这个页面是由Spring Security提供的

在这里插入图片描述

第三步: 创建config/WebSecurityConfig配置类继承WebSecurityConfigurerAdapter

  • 该类可以用来配置用户信息(账号和密码以及访问权限),密码存储方式(明文还是加密),安全拦截机制(需要对哪些请求路径进行认证)

第四步: 重启工程访问localhost:53070/auth/user/52可以正常访问, 访问localhost:53070/auth/r/r1会被拦截,跳转到Spring Security提供的登录页面

方法描述
authorizeRequests()配置请求授权规则
antMatchers()指定需要进行访问控制的URL路径的匹配规则
authenticated()指定需要进行身份验证的请求
anyRequest()表示除了需要进行访问控制的URL以外请求
permitAll()表示任何用户都可以访问不需要进行身份验证
formLogin()配置登录页表单认证
successForwardUrl()指定登录成功后的跳转页面
logout()配置退出登录页面
logoutUrl()指定退出登录的URL
package com.xuecheng.auth.config;
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {@Beanpublic UserDetailsService userDetailsService() {// 1. 配置用户信息服务InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();// 2. 创建用户信息这里暂时写死,后面需要从数据库中动态查询, Kyle的权限是p1,Lucy的权限是p2// User是Spring Security提供的工具类manager.createUser(User.withUsername("Kyle").password("123").authorities("p1").build());manager.createUser(User.withUsername("Lucy").password("456").authorities("p2").build());return manager;}@Beanpublic PasswordEncoder passwordEncoder() {// 采用明文的方式return NoOpPasswordEncoder.getInstance();}protected void configure(HttpSecurity http) throws Exception {http.authorizeRequests().antMatchers("/r/**")// 表示"/r/**"开头的请求需要认证.authenticated().anyRequest().permitAll()// 其他请求全部放行.and().formLogin().successForwardUrl("/login-success");// 配置退出登录页面,认证成功后访问/logout可退出登录http.logout().logoutUrl("/logout");}
}

授权测试

用户认证通过后需要去访问系统的资源,但不同的用户对资源的访问权限是不同的

  • Spring Security会判断当前用户是否有该资源的访问权限,如果有权限才可以继续访问没有权限则拒绝访问

在这里插入图片描述

第一步: 在WebSecurityConfig配置类中创建用户时配置用户的权限

@Bean
public UserDetailsService userDetailsService() {// 1. 配置用户信息服务, InMemoryUserDetailsManager是指在内存中配置用户的信息InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();// 2. 创建用户信息这里暂时写死,后面需要从数据库中动态查询, Kyle的权限是p1,Lucy的权限是p2// User是Spring Security提供的工具类manager.createUser(User.withUsername("Kyle").password("123").authorities("p1").build());manager.createUser(User.withUsername("Lucy").password("456").authorities("p2").build());return manager;
}

第二步:在控制器方法上使用@PreAuthorize("hasAnyAuthority('权限')")注解指定用户访问的资源对应所需要的权限,如查询用户信息时所需要的权限

  • 由于要访问资源需要通过URL,所有我们在Controller中定义的每个HTTP的接口就是访问资源的接口,权限控制就是在接口这里配置

第三步: 重启工程,如果登录Kyle账号进行认证,由于其只有p1权限所以无法访问/r/r2会报403错误, 同理Lucy无法访问/r/r1

@RequestMapping("/r/r1")
@PreAuthorize("hasAnyAuthority('p1')")// 访问/r/r1需要p1权限
public String r1() {return "访问r1资源";
}@RequestMapping("/r/r2")
@PreAuthorize("hasAuthority('p2')")// 访问/r/r2需要p2权限
public String r2() {return "访问r2资源";
}

认证的工作原理

过滤链

Spring Security所解决的问题就是对安全访问控制即对所有进入系统的请求进行拦截, 校验每个请求是否能够访问到它所期望的资源

通过Filter或AOP等技术可以实现安全访问控制功能,而Spring Security对Web资源的保护是靠Filter实现的,Spring Security有一个过滤链

在这里插入图片描述

Spring Security框架中真正起作用的是FilterChainProxy中的SecurityFilterChain所包含的各个Filter

在这里插入图片描述

过滤器功能
SecurityContextPresistenceFilter整个拦截过程的入口和出口即第一个和最后一个拦截器
在请求开始时从配置好的SecurityContextRepository中获取SecurityContext给SecurityContextHolder
在请求完成后将SecurityContextRepository持有的SecurityContext再保存到配置好的SecurityContextRepository,同时清除SecurityContextHolder所持有的SecurityContext
UsernamePasswordAuthenticationFilter处理来自表单提交的认证,要求表单必须提供对应的用户名和密码
其内部还有登录成功或失败后进行处理的AuthenticationSuccessHandler和AuthenticationFailureHandler
FilterSecurityInterceptor用于保护web资源的,使用AccessDecisionManager对当前用户进行授权访问
ExceptionTranslationFilter捕获来自 FilterChain所有的异常并进行处理
它只会处理AuthenticationException和AccessDeniedException这两类异常,其它的异常它会继续抛出

执行流程

Spring Security的执行流程如下

  1. 用户提交的用户名、密码被SecurityFilterChain中的UsernamePasswordAuthenticationFilter过滤器获取到并把其封装到Authentication请求对象中
  2. UsernamePasswordAuthenticationFilter过滤器将Authentication请求对象提交至认证管理器AuthenticationManager进行认证
  3. 认证成功后,AuthenticationManager身份管理器会把权限,身份,细节等信息(密码通常移除)填充到刚提交的Authentication请求对象
  4. 通过SecurityContextHolder(安全上下文容器)将填充了用户名,权限,身份,细节等信息的Authentication请求对象保存都安全上下文中

AuthenticationManager是认证相关的核心接口也是发起认证的出发点,它的实现类为ProviderManager

  • Spring Security支持多种认证方式,所以ProviderManager会维护着一个List<AuthenticationProvider>列表
  • AuthenticationProvider接口的实现类完成最终实际认证工作(不同实现类代表不同认证方式),web表单的实现类为DaoAuthenticationProvider
  • DaoAuthenticationProvider的内部又维护着一个UserDetailsService负责获取UserDetails(实体类)
  • 最终AuthenticationProvider将获取到的UserDetails信息填充至Authentication请求对象中

在这里插入图片描述

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

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

相关文章

vue3(六)-基础入门之自定义组件与插槽、ref通信

一、全局组件 html: <div id"app"><mytemplace></mytemplace> </div>javascript: <script>const { createApp } Vueconst app createApp({})app.component(mytemplace, {template: <div><button>返回</button>…

canvas随机绘制100个五角星

canvas实例应用100 专栏提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。 canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重要的帮助。 文章目录 示例…

element-plus修改主题颜色

一、自定义scss文件 在src\css\styles\element目录下新建index.scss 代码如下 forward "element-plus/theme-chalk/src/common/var.scss" with ($colors: ("primary": ("base": #d61b1a,"color": #fff,),) );use "element-plus…

Java - 工厂设计模式

Java - 工厂设计模式 一. 简介二. 例子2.1 定义抽象类2.2 定义子类2.3 创建工厂2.4 测试 三. JDK中使用工厂模式的案例 前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 工厂设计模式…

Day73力扣打卡

打卡记录 统计移除递增子数组的数目 II&#xff08;双指针&#xff09; 链接 class Solution:def incremovableSubarrayCount(self, a: List[int]) -> int:n len(a)i 0while i < n - 1 and a[i] < a[i 1]:i 1if i n - 1: # 每个非空子数组都可以移除return n …

普中STM32-PZ6806L开发板(STM32CubeMX创建项目并点亮LED灯)

简介 搭建一个用于驱动 STM32F103ZET6 GPIO点亮LED灯的任务;电路原理图 LED电路原理图 芯片引脚连接LED驱动引脚原理图 创建一个点亮LED灯的Keil 5项目 创建STM32CubeMX项目 New Project -> 单击 -> 芯片搜索STM32F103ZET6->双击创建 初始化时钟 调试设置 一…

双侧电源系统距离保护MATLAB仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 系统原始数据 双侧电源系统模型如图所示&#xff1a; 仿真模型搭建 将线路AB分成Line1和Line2&#xff0c;将线路BC分成Line3和Line4&#xff0c;用三相电压电流测量模块作为系统母线&#xff0c;根据系统已…

洛谷 P1387 最大正方形 刷题笔记

P1387 最大正方形 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 找出一个 由数字1组成的最大正方形 输出该正方形的边长 &#xff1b; 思路 dp 画图模拟 可以发现 当 当前点a[i][j]1,满足构成正方形的初步条件 而当前点能构成的最大正方形长度 由它的左上角 左边和上边…

新手为什么跟着大型机构交易?fpmarkets总结理由

正所谓方向不对努力白费&#xff0c;这也就是为什么fpmarkets建议新手在刚开始的时候&#xff0c;跟着大型机构进行交易。 这些大型机构包括中央银行、巨额对冲基金、投资和保险公司等等&#xff0c;首先fpmarkets认为这些大型机构的交易量巨大&#xff0c;能够影响市场的走势。…

LeetCode刷题--- N 皇后

个人主页&#xff1a;元清加油_【C】,【C语言】,【数据结构与算法】-CSDN博客 个人专栏 力扣递归算法题 http://t.csdnimg.cn/yUl2I 【C】 http://t.csdnimg.cn/6AbpV 数据结构与算法 ​​​​​​http://t.csdnimg.cn/hKh2l 前言&#xff1a;这个专栏主要讲述递归…

ARCGIS PRO SDK 要素空间关系

一、要素与要素查询&#xff0c;返回的是bool值 1、 Touches 判断几何要素是否接触 Touches 如果 geometry1 与 geometry2 接触&#xff0c;则返回 true&#xff0c;否则 false。 touches GeometryEngine.Instance.Touches(Geometry1, Geometry2) 2、…

传感器原理与应用复习--电感式传感器

文章目录 上一篇自感式电感传感器差动变压器式传感器电涡流式传感器下一篇 上一篇 传感器原理与应用–传感器基本特性与应变式传感器 自感式电感传感器 将线圈通入电流产生磁场&#xff0c;而间隙的大小将影响磁场的大小&#xff0c;从而进行检测 变气隙式电感传感器&#xf…

2D transform 1-translate

移位&#xff1a;translate 缩放&#xff1a;scale 旋转&#xff1a;rotate 扭曲&#xff1a;skew <style>.outer {width: 200px;height: 200px;border: 2px solid black;margin-top: 100px;}.inner {width: 200px;height: 200px;background-color: pink;transform: t…

el-select多选修改默认显示一个

需求&#xff1a;超出选择框已数字展示 效果 备忘一下 代码 父组件 <template><div><div class"credit_box"><div class"credit_select_box"><div class"credit_select"><span>选择框1</span><…

C#中的Attribute详解(上)

C#中的Attribute详解&#xff08;上&#xff09; 一、Attribute是什么二、Attribute的作用三、Attribute与注释的区别四、系统Attribute范例1、如果不使用Attribute&#xff0c;为了区分这四类静态方法&#xff0c;我们只能通过注释来说明&#xff0c;但这样做会给系统带来很多…

前端文件在虚拟机,后端在本机,两个如何通信

前端文件在虚拟机&#xff0c;后端在本机&#xff0c;两个如何通信 如果前端的文件放在虚拟机里面&#xff0c;但是调用接口的后端在本地调试&#xff0c;如何做到在虚拟机中也能访问到本地的接口内容。 其实这个问题很简单&#xff0c;只要讲本地的IP和虚拟机中的IP结合就可…

unknown variable ‘authentication_policy=mysql_native_password‘

unknown variable authentication_policymysql_native_password 背景解决尝试一尝试二(解决) 总结 背景 mac上安装多个版本数据库。我是通过dmg安装的&#xff0c;先装的5.7&#xff0c;再装的5.8&#xff0c;然后5.8的能正常用&#xff0c;5.7的启动不起来。报错信息为如下 …

Python五子棋程序实现详解

Python五子棋程序实现详解 引言功能实现显示棋盘点击落子判断胜负游戏结束判断交替落子 运行结果完整代码总结 引言 五子棋是一种广泛传播的策略棋类游戏&#xff0c;两人对弈&#xff0c;通过在棋盘上落子&#xff0c;以先形成连续的相同颜色的五子棋为胜利条件。本文将介绍如…

生存分析序章2——生存分析之Python篇:lifelines库入门

目录 写在开头1. 介绍 lifelines 库1.1 lifelines库简介1.2 安装与环境配置 2. 数据准备2.1 数据格式与结构2.2 处理缺失数据2.3 对异常值的处理 3. Kaplan-Meier 曲线3.1 使用 lifelines 绘制生存曲线3.2 曲线解读3.3 额外补充 4. Cox 比例风险模型4.1 lifelines 中的 Cox 模型…

7+非肿瘤+线粒体+PPI+机器学习+实验,多套路搭配干湿结合

今天给同学们分享一篇生信文章“Identification of mitochondrial related signature associated with immune microenvironment in Alzheimers disease”&#xff0c;这篇文章发表在J Transl Med期刊上&#xff0c;影响因子为7.4。 结果解读&#xff1a; 在ND和AD样本中鉴定差…