spring boot security 自定义AuthenticationProvider
spring boot security 自定义AuthenticationProvider
基于 spring boot 3.x
场景实现 手机验证码登陆
实现
CaptureCodeAuthenticationFilter
public class CaptureCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {private static final String DEFAULT_LOGIN_URL = "/capture/login";private static final String DEFAULT_PHONE_NAME = "phone";private static final String DEFAULT_CODE_NAME = "code";private String codeParamName = DEFAULT_CODE_NAME;private String phoneParamName = DEFAULT_PHONE_NAME;public CaptureCodeAuthenticationFilter(AuthenticationManager authenticationManager) {super(DEFAULT_LOGIN_URL, authenticationManager);}public CaptureCodeAuthenticationFilter(String defaultFilterProcessesUrl, AuthenticationManager authenticationManager) {super(defaultFilterProcessesUrl, authenticationManager);}@Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {if (!request.getMethod().equals("POST")) {throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());}String phone = obtainPhone(request);phone = (phone != null) ? phone.trim() : "";String code = obtainCaptureCode(request);code = (code != null) ? code : "";CaptureCodeAuthenticationToken token = new CaptureCodeAuthenticationToken(phone, code);return this.getAuthenticationManager().authenticate(token);}protected String obtainCaptureCode(HttpServletRequest request) {return request.getParameter(this.codeParamName);}protected String obtainPhone(HttpServletRequest request) {return request.getParameter(this.phoneParamName);}
}
CaptureCodeAuthenticationToken
public class CaptureCodeAuthenticationToken extends UsernamePasswordAuthenticationToken {public CaptureCodeAuthenticationToken(Object principal, Object credentials) {super(principal, credentials);}
}
CaptureCodeAuthenticationProvider
public class CaptureCodeAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {@Overridepublic boolean supports(Class<?> authentication) {return (CaptureCodeAuthenticationToken.class.isAssignableFrom(authentication));}@Overrideprotected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {if (authentication.getPrincipal()==null){throw new BadCredentialsException("Bad credentials "+ authentication.getPrincipal().toString());}if (authentication.getCredentials()==null){throw new BadCredentialsException("Bad credentials "+ authentication.getPrincipal().toString());}}@Overrideprotected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {CaptureCodeAuthenticationToken token = (CaptureCodeAuthenticationToken) authentication;if (!token.getPrincipal().equals("tom")){throw new UsernameNotFoundException("username not fund!");}UserDetails user = User.withUsername("tom").password("tom").build();return user;}}
配置 DefaultSecurityConfig
@Configuration
@EnableWebSecurity
public class DefaultSecurityConfig {@Autowiredprivate ObjectMapper objectMapper;@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(request -> request.anyRequest().authenticated());http.formLogin(Customizer.withDefaults());http.csrf(AbstractHttpConfigurer::disable);http.addFilterBefore(captureCodeAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);return http.build();}public CaptureCodeAuthenticationFilter captureCodeAuthenticationFilter() {ProviderManager providerManager = new ProviderManager(new CaptureCodeAuthenticationProvider());CaptureCodeAuthenticationFilter filter =new CaptureCodeAuthenticationFilter(providerManager);filter.setAuthenticationSuccessHandler((request, response, authentication) -> {response.setStatus(HttpServletResponse.SC_OK);response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);response.getWriter().write(objectMapper.writeValueAsString(Result.ok("认证成功")));response.getWriter().flush();});filter.setAuthenticationFailureHandler((request, response, exception) -> {response.setStatus(HttpServletResponse.SC_OK);response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);response.getWriter().write(objectMapper.writeValueAsString(Result.ok("认证失败")));response.getWriter().flush();});return filter;}@Beanpublic UserDetailsService users(PasswordEncoder passwordEncoder) {UserDetails user = User.withUsername("admin").password(passwordEncoder.encode("admin")).build();return new InMemoryUserDetailsManager(user);}@Beanpublic PasswordEncoder encoder() {return new BCryptPasswordEncoder();}}
相关文章:
spring boot security 自定义AuthenticationProvider
spring boot security 自定义AuthenticationProvider 基于 spring boot 3.x 场景实现 手机验证码登陆 实现 CaptureCodeAuthenticationFilter public class CaptureCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {private static final Strin…...
某电力设计公司绩效考核优化项目成功案例纪实
——引入角色定位考核法,建立多维度评价体系,支持业务转型后的客观评价 【客户行业】电力行业 【问题类型】绩效考核 【客户背景及现状分析】 某电力设计公司成立于2000年左右,是一家从事输变电工程勘察、设计、咨询的专业公司,…...
力扣371周赛
力扣第371场周赛 找出强数对的最大异或值 I 枚举 class Solution { public:int maximumStrongPairXor(vector<int>& a) {int n a.size() , res 0;for(int i 0 ; i < n ; i ){for(int j 0 ; j < n ; j ){if(abs(a[i]-a[j])<min(a[i],a[j])){int c (a…...

Python之字符串、正则表达式练习
目录 1、输出随机字符串2、货币的转换(字符串 crr107)3、凯撒加密(book 实验 19)4、字符替换5、检测字母或数字6、纠正字母7、输出英文中所有长度为3个字母的单词 1、输出随机字符串 编写程序,输出由英文字母大小写或…...

Transmit :macOS 好用的 Ftp/SFtp 工具
Transmit 是一种功能强大的 FTP/SFTP/WebDAV 客户端软件,是一个 Mac OS X 平台上设计的文件传输软件。它由 Panic(一家以软件工具为主的公司)开发和维护,是一款非常受欢迎且易于使用的软件,而且被广泛认为是 Mac OS X …...

【Github】git clone命令下载文件中途停止
方法一: 使用git clone命令下载github上的源代码时,有时文件下载到一定百分比时就停止不动, 这是因为我们所下载的文件很大,超过了git预先分配的Postbuffer容量,所以一直卡在那里。可以使用以下命令查看当前Postbuffe…...

Clickhouse学习笔记(10)—— 查询优化
单表查询 Prewhere 替代 where prewhere与where相比,在过滤数据的时候会首先读取指定的列数据,来判断数据过滤,等待数据过滤之后再读取 select 声明的列字段来补全其余属性 简单来说就是先过滤再查询,而where过滤是先查询出对应…...

[量化投资-学习笔记012]Python+TDengine从零开始搭建量化分析平台-策略回测
上一章节《MACD金死叉策略回测》中,对平安银行这只股票,按照金死叉策略进行了回测。 但通常我们的股票池中有许多股票,每完成一个交易策略都需要对整个股票池进行回测。 下面使用简单的轮询,对整个股票池进行回测。 # 计算单只…...
MySQL 查看 event 执行记录
文章目录 1. 查看 EVENT 执行记录2. 示例3. 结论 MySQL 是一款流行的关系型数据库管理系统,它提供了许多功能来帮助用户管理和操作数据库。其中之一就是 EVENT事件,它允许用户在特定的时间间隔内自动执行指定的操作,类似于计划任务。 在使用 …...

开发知识点-Vue-Electron
Electron ElectronVue打包.exe桌面程序 ElectronVue打包.exe桌面程序 为了不报错 卸载以前的脚手架 npm uninstall -g vue-cli安装最新版脚手架 cnpm install -g vue/cli创建一个 vue 随便起个名 vue create electron-vue-example (随便起个名字electron-vue-example)进入 创建…...

【线性代数】反求矩阵A
...
MyBatis 中的 foreach 的用法
本文将介绍 MyBatis 中的 <foreach> 标签的灵活应用,并结合财经领域的数据处理场景,阐述其在财经系统开发中的重要性和应用价值。 MyBatis中的<foreach>标签简介 MyBatis 是一个优秀的持久层框架,它简化了数据库操作的流程&…...

交叉编译 mysql-connector-c
下载 mysql-connector-c $ wget https://downloads.mysql.com/archives/get/p/19/file/mysql-connector-c-6.1.5-src.tar.gz 注意:mysql-connector 的页面有很多版本,在测试过程中发现很多默认编译有问题,其中上面的 6.1.5 的版本呢是经过测…...
企业如何选择正确的存储服务器租用?
数据时代的发展,让越来越多的企业选择使用存储服务器来存储数据,今天小编就带大家了解一下企业应该怎么正确的选择存储服务器吧,要关注哪些方面的问题呢? 第一点肯定是看自己的需求,不论是选择什么服务器最重要的一点就…...
45.跳跃游戏II
45.跳跃游戏II 题目描述:给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i j] 处: 0 < j < nums[i]i …...

css style、css color 转 UIColor
你能看过来,就说明这个问题很好玩!IT开发是一个兴趣,更是一个挑战!兴趣使你工作有热情。挑战使让你工作充满刺激拉满的状态!我们日复一日年复一年的去撸代码,那些普普通通的功能代码,已经厌倦了…...
C++(20):typename声明类的子类型的简化
C++:typename声明类的子类型_风静如云的博客-CSDN博客 介绍了某些时候需要使用typename来告诉编译器,这是一个类的类型。 C++20简化了对typename的需求,对于明显是类型的地方,可以不再使用typename进行说明: #include <iostream> #include <string>using na…...

一个java文件的JVM之旅
准备 我是小C同学编写得一个java文件,如何实现我的功能呢?需要去JVM(Java Virtual Machine)这个地方旅行。 变身 我高高兴兴的来到JVM,想要开始JVM之旅,它确说:“现在的我还不能进去,需要做一次转换&#x…...

C# wpf 实现任意控件(包括窗口)更多拖动功能
系列文章目录 第一章 Grid内控件拖动 第二章 Canvas内控件拖动 第三章 任意控件拖动 第四章 窗口拖动 第五章 附加属性实现任意拖动 第六章 拓展更多拖动功能(本章) 文章目录 系列文章目录前言一、添加的功能1、任意控件MoveTo2、任意控件DragMove3、边…...

一种ADC采样算法,中位值平均滤波+递推平均滤波
前言 在实际AD采集场景中,会出现周期性变化和偶然脉冲波动干扰对AD采集的影响 这里使用中位值平均滤波递推平均滤波的结合 参考前人写好的代码框架,也参考博主GuYH_下面这篇博客,在此基础上稍作修改,写出这篇博客,能…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
【Java学习笔记】BigInteger 和 BigDecimal 类
BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点:传参类型必须是类对象 一、BigInteger 1. 作用:适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...

Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...