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_下面这篇博客,在此基础上稍作修改,写出这篇博客,能…...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...