spring security登录认证授权

news/2024/9/23 21:02:33/

spring_security_0">spring security登录认证授权

是什么

Spring Security 主要实现了Authentication(认证,解决who are you? ) 和 Access Control(访问控制,也就是what are you allowed to do?,也称为Authorization)。Spring Security在架构上将认证与授权分离,并提供了扩展点

使用-1 快速开始 引入依赖,出现登录页面
<!-- 实现对 Spring MVC 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 实现对 Spring Security 的自动化配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>

在这里插入图片描述

自定义登录的用户名密码(练手)

配置类继承适配器 WebSecurityConfigurerAdapter, 重写configure方法,实现UserDetailsService接口,设置用户名,密码
在这里插入图片描述

从数据库读取密码

配置类继承适配器 WebSecurityConfigurerAdapter, 重写configure方法,实现UserDetailsService接口,调用UserDetailsService的已有的实现类,或者调用自定义的类,实现了UserDetailsService实现类接口,重写loadUserByUsername方法(数据库查登录的用户名密码)
在这里插入图片描述
在这里插入图片描述

认证逻辑

认证逻辑:SecurityContextPersistenceFilter Security上下文持久化过滤器拿到登录信息,生成session存储 ->SecurityContextHolderStrategy 策略 ->ThreadLocalSecurityContextHolderStrategy 用的ThreadLocal
AbstractAuthenticationProcessingFilter 的 doFilter方法->attemptAuthentication方法->AuthenticationManager接口的authenticate接口方法
->retrieveUser->getUserDetailsService().loadUserByUsername(获取到自定义的数据库获取用户名密码方法)–>authenticate方法中 调用additionalAuthenticationChecks
检查用户名密码的准确性–>正确的话就走认证成功的逻辑,认证成功后 ->SecurityContextHolder.getContext().setAuthentication设置登录信息到上下文;错误就走认真失败的逻辑

自定义认证成功失败的处理

在这里插入图片描述
](https://img-blog.csdnimg.cn/direct/7a9f49e75ae34c599bed5ed3ff7298c3.png)

在这里插入图片描述

自定义登录成功失败逻辑(执行方法步骤)原理:
认证成功后: successForwardUrl–>ForwardAuthenticationSuccessHandler->调用了AuthenticationSuccessHandler 的onAuthenticationSuccess 方法
因此可以实现AuthenticationSuccessHandler接口,重写 onAuthenticationSuccess 方法
认证失败同理:failureForwardUrl->ForwardAuthenticationFailureHandler->调用了 ForwardAuthenticationFailureHandler的 onAuthenticationFailure 方法
因此可以实现 ForwardAuthenticationFailureHandler接口,重写 onAuthenticationFailure 方法

会话管理(session)

是什么?http请求是无状态的,因此需要在浏览器和服务器端存储状态,即会话。
tomcat 会生成session对象,响应的时候会带给客户端存到浏览器的Cookie中,
下次再请求服务器时,带上JSESSIONID,和服务器的JSESSIONID比对,相同的话响应,否则不响应

原理 :SecurityContextHolder.getContext().getAuthentication()可以获取到登录信息,因为登录的认证信息存在 SecurityContext上下文中
AbstractAuthenticationProcessingFilter 的 doFilter方法 -> successfulAuthentication 认证成功后 ->SecurityContextHolder.getContext().setAuthentication 登录的认证信息存在 SecurityContext上下文中

spring_security_56">会话并发控制-spring security实现

同一个账号只能同时登录一次(后面登录人把前面登录人挤掉)—>可以用redis实现,此处是用spring security实现
http.sessionManagement().maximumSessions(1)
原理:AbstractAuthenticationProcessingFilter -> sessionStrategy.onAuthentication()-> ConcurrentSessionControlAuthenticationStrategy 的onAuthentication方法比较当前登录的session个数是否小于我们自己设置 -> 是的话就session 设置过期- >ConcurrentSessionFilter 并发session过滤器 -> doFilter方法 -> 没有过期则登录成功,否则走session过期策略
可自定义实现SessionInformationExpiredStrategy接口重写onExpiredSessionDetected方法
问题:http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true) //超过最大的登录数,阻止登录
问题:我们在yml配置的http session设置的超时时间和内部SessionInformation 是重新的一个session,超时时间和之前不同,导致http session设置的超时时间超时了,但是SessionInformation 没超时会报多人同时登录的错误最好不要用,可以用redis实现

会话并发控制-redis实现

实现原理:引入的spring session包中有个session仓库的过滤器 SessionRepositoryFilter -> doFilter方法 ->commitSession ->sessionRepository.save(session)实现了重写了RedisSessionRepository中save 方法,把session存到redis中

1.引入spring session依赖

<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.1.0</version>
</dependency>

2.修改application.yml

xmlsession:store-type: redisredis:host: localhostport: 6379

3.开启多个项目实例即可测试

Remember me实现

设置数据源,Spring Security会自动把用户信息存储到数据源中,下次登录直接比对数据库值就ok
原理:RememberMeAuthenticationFilter -> doFilter方法 -> autoLogin ->AbstractRememberMeServices的autoLogin ->PersistentTokenBasedRememberMeServices 的processAutoLoginCookie 取出remember-me的值拆分为series和token 去数据库根据series找到记录,看token是否一致一致就调用 getUserDetailsService().loadUserByUsername方法,实现自动登录
在这里插入图片描述
在这里插入图片描述

退出登录

原理:LogoutFilter-> doFilter方法 -> SecurityContextLogoutHandler的logout方法,setAuthentication为null清除认证状态,销毁HTTPSession对象
SimpleUrlLogoutSuccessHandler的onLogoutSuccess 重定向到登录页面

csrf跨站请求伪造

从 Spring Security4开始CSRF防护默认开启,默认会拦截请求,进行CSRF处理。CSRF为了保证不是其他第三方网站访问,要求访问时携带参数名为 _csrf 值为token(token 在服务端产生,在渲染请求页面时埋入页面)的内容,如果token和服务端的token匹配成功,则正常访问。
原理:CsrfFilter -> doFilter方法 -> 如果没有token 先生成一个,然后放到填充到CSRF_TOKEN中返回给页面,会再走一遍doFilter方法去比对CSRF_TOKEN和服务端的token是否能匹配成功,成功则可以访问,否则不能访问
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

授权

这里是引用访问控制url的匹配
antMatchers ant 表达式,统配符 ? 匹配任何单字符,* 匹配0或者任意数量的字符, ** 匹配0或者更多的目录
hasAuthority 有…的角色权限
hasAnyAuthority 有多个角色权限,符合一个即可
自定义403处理方案
使用 Spring Security 时经常会看见 403(无权限)。Spring Security 支持自定义权限受限处理,需要
实现 AccessDeniedHandler接口
基于方法的授权
1.JSR250注解,可以定义在方法和类上面
配置类开启@EnableGlobalMethodSecurity(jsr250Enabled = true,securedEnabled = true,prePostEnabled = true)
@RolesAllowed 访问对应方法时所应该具有的角色
@PermitAll 不进行权限控制
@DenyAll 无论什么角色都不能访问
2.@Secured注解专门用于判断是否具有角色的,能写在方法或类上。参数要以 ROLE_开头
配置类开启@EnableGlobalMethodSecurity(jsr250Enabled = true,securedEnabled = true,prePostEnabled = true)
3.支持表达式注解
配置类开启@EnableGlobalMethodSecurity(jsr250Enabled = true,securedEnabled = true,prePostEnabled = true)
使用@PreAuthorize和@PostAuthorize 在方法之前,之后进行访问控制

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

授权原理:FilterSecurityInterceptor -> doFilter方法 -> invoke-> beforeInvocation -> attemptAuthorization -> decide(AffirmativeBased) -> vote 投票是否通过授权通过则可以访问资源,失败则跳转到登录页面认证


http://www.ppmy.cn/news/1435264.html

相关文章

【SpringCloud】OpenFeign服务接口调用快速入门

【SpringCloud】OpenFeign服务接口调用快速入门 文章目录 【SpringCloud】OpenFeign服务接口调用快速入门1. 概述2. 引入依赖3. 配置、测试 1. 概述 官网地址&#xff1a;点击跳转 Feign是一个声明性web服务客户端。它使编写web服务客户端变得更容易。使用 Feign 创建一个接口…

Swift-30-高级编程-类型扩展和协议扩展

类型扩展 Swift提供一个叫扩展&#xff08;extension&#xff09;的特性&#xff0c;该特性就是为这种情况设计的。扩展能让你给已有的类型添加功能&#xff0c;可以用来扩展结构体、枚举和类&#xff0c;比如&#xff1a; 添加计算属性添加新的初始化方法添加协议实现添加新…

s AbortController 接口取消多次请求 取消上次请求

AbortController 是一个 JavaScript API&#xff0c;它允许您在客户端中止一个或多个 Fetch 请求。这个 API 是 Fetch API 的一部分&#xff0c;并且与 AbortSignal 对象一起使用&#xff0c;以提供一种机制来控制请求的生命周期。 以下是 AbortController 的基本用法&#xf…

【数据结构】图(Graph)

文章目录 概念图的存储方式邻接矩阵邻接矩阵表示法邻接矩阵表示法的特点 邻接表邻接表表示法邻接表表示法的特点邻接表表示法的定义与实现查找插入删除其它构造函数析构函数创建图输出图 图的遍历深度优先遍历&#xff08;DFS&#xff09;广度优先遍历 图的连接分量和生成树生成…

《深入浅出.NET框架设计与实现》笔记6.1——ASP.NET Core应用程序多种运行模式之一——自宿主(Self-Hosting)

ASP.NET Core应用程序可以在多种运行模式下运行&#xff0c;包括自宿主&#xff08;Self-Hosting&#xff09;、IIS服务承载、桌面应用程序、服务承载。 因此选择和时的模式很重要。 自宿主&#xff08;Self-Hosting&#xff09; 自宿主是指 ASP.NET Core 应用程序独立运行&a…

「ChatGPT」掀起新一轮AI热潮!超越GPT-4 Turbo,商汤日日新大升级!

目录 拳打 GPT-4 Turbo &#xff0c;脚踢 DALLE 3 端侧大模型&#xff0c;唯快不破 AI 应用落地需要一个即插即用的大模型超市 并不存在 AI 这个行业&#xff0c;只有 AI行业&#xff0c;强调 AI 需要与传统产业合作&#xff0c;这种关系是结合与赋能&#xff0c;而不是颠覆…

【VueUse】重新定义状态管理在 Vue 中的体验

在 Vue 生态系统中&#xff0c;状态管理一直是开发者们关注的焦点之一。而随着 VueUse 的出现&#xff0c;我们迎来了一种全新的方式来处理状态管理&#xff0c;它让我们能够以更简单、更灵活的方式来管理应用程序的状态。 在本文中我们将深入探讨 VueUse 中与状态管理相关的内…

Chrome 侧边栏开发示例

前言 最近做项目&#xff0c;需要开发浏览器扩展&#xff0c;但是考虑页面布局兼容性问题&#xff0c;使用了Chrome114开始的侧边栏&#xff0c;浏览器自带的能力毕竟不会出现兼容性问题&#xff0c;不过Chrome123开始&#xff0c;侧边栏居然又可以选择固定右侧扩展栏了&#…