若依前后端分离Spring Security新增手机号登录
备忘贴
转自:【若依RuoYi短信验证码登录】汇总_数据库_z_xiao_qiang-RuoYi 若依
配置Security:
按照Security的流程图可知,实现多种方式登录,只需要重写三个主要的组件,第一个用户认证处理过滤器,第二个用户认证token类,第三个,自定义短信登录身份认证。
/*** 参考UsernamePasswordAuthenticationToken类,继承AbstractAuthenticationToken,重写以下几个方法,自定义短信登录token验证。* 自定义短信登录token验证*/
public class UsernamePhoneAuthenticationToken extends AbstractAuthenticationToken {/*** 手机号*/private final Object principal;public UsernamePhoneAuthenticationToken(Object principals){super(null);this.principal = principals;setAuthenticated(false);}public UsernamePhoneAuthenticationToken(Object principal, Collection<? extends GrantedAuthority> authorities){super(authorities);this.principal = principal;super.setAuthenticated(true);}@Overridepublic Object getCredentials() {return null;}@Overridepublic Object getPrincipal() {return this.principal;}@Overridepublic void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException{if(isAuthenticated){throw new IllegalArgumentException("Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead");}super.setAuthenticated(false);}@Overridepublic void eraseCredentials(){super.eraseCredentials();}
/*** 重写UserDetailsService类的loadUserByUsername方法,实现用户验证处理。* 用户验证处理*/
@Service("userDetailsByPhone")
public class UsernamePhoneUserDetailsServiceImpl implements UserDetailsService {private static final Logger logger = LoggerFactory.getLogger(UsernamePhoneUserDetailsServiceImpl.class);@Autowiredprivate ISysUserService userService;@Autowiredprivate SysUserMapper sysUserMapper;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {SysUser sysUser;if(Pattern.compile("^[1][1,2,3,4,5,6,7,8,9][0-9]{9}$").matcher(username).matches()){sysUser = sysUserMapper.selectUserByTel(username);}else if(username.matches("\\w{1,30}@[a-zA-Z0-9]{2,20}(\\.[a-zA-Z0-9]{2,20}){1,2}")){sysUser = sysUserMapper.selectUserByEmail(username);}else{throw new ServiceException("请使用手机号或者邮箱进行登录!");}if(StringUtils.isNull(sysUser)){logger.info("登录用户:{} 不存在.", username);throw new ServiceException("登录用户:" + username+ " 不存在");}return createLoginUser(sysUser);}public UserDetails createLoginUser(SysUser user){return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));}
/*** 自定义一个短信登录的身份鉴权, UserDetailsService 只负责根据用户名返回用户信息,AuthenticationProvider负责将 UserDetails 组装成 Authentication 向调用者返回。* 自定义短信登录身份认证*/
public class UsernamePhoneAuthenticationProvider implements AuthenticationProvider {private UserDetailsService userDetailsService;public UsernamePhoneAuthenticationProvider(UserDetailsService userDetailsService){setUserDetailsService(userDetailsService);}/*** 重写authentication方法,实现身份验证逻辑*/@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {UsernamePhoneAuthenticationToken authenticationToken = (UsernamePhoneAuthenticationToken) authentication;String phone = (String) authenticationToken.getPrincipal();//委托 UserDetailsService 查找系统用户UserDetails userDetails = userDetailsService.loadUserByUsername(phone);//鉴权成功,返回一个拥有鉴权的AbstractAuthenticationTokenUsernamePhoneAuthenticationToken authenticationTokenRes = new UsernamePhoneAuthenticationToken(userDetails, userDetails.getAuthorities());authenticationTokenRes.setDetails(authenticationToken.getDetails());return authenticationTokenRes;}/*** 重写supports方法,指定此AuthenticationProvider 仅支持短信验证码身份验证*/@Overridepublic boolean supports(Class<?> authentication){return UsernamePhoneAuthenticationToken.class.isAssignableFrom(authentication);}public UserDetailsService getUserDetailsService() {return userDetailsService;}public void setUserDetailsService(UserDetailsService userDetailsService) {this.userDetailsService = userDetailsService;}
/*** 配置SecurityConfig 的configure方法* spring security配置* * @author victor_zhang*/
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter
{/*** 自定义用户认证逻辑(账号密码)*/@Autowired@Qualifier("userDetailsByPass")private UserDetailsService userDetailsService;/*** 自定义用户认证逻辑(手机号验证码)*/@Autowired@Qualifier("userDetailsByPhone")private UserDetailsService userDetailsByPhone;/*** 认证失败处理类*/@Autowiredprivate AuthenticationEntryPointImpl unauthorizedHandler;/*** 退出处理类*/@Autowiredprivate LogoutSuccessHandlerImpl logoutSuccessHandler;/*** token认证过滤器*/@Autowiredprivate JwtAuthenticationTokenFilter authenticationTokenFilter;//此处省略n行代码....../*** 身份认证接口*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception{//手机或邮箱的验证码的验证auth.authenticationProvider(new UsernamePhoneAuthenticationProvider(userDetailsByPhone));//账号密码的验证 auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());}
相关文章:

若依前后端分离Spring Security新增手机号登录
备忘贴 转自:【若依RuoYi短信验证码登录】汇总_数据库_z_xiao_qiang-RuoYi 若依 配置Security: 按照Security的流程图可知,实现多种方式登录,只需要重写三个主要的组件,第一个用户认证处理过滤器,第二个用户认证tok…...
Oracle操作扩可变字符长度交易影响分析-较小
使用AI帮助学习知识 以下知识来至AI oracle 一张大表,对可变字符串长度从10扩到20位,oracle底层存储是否会发生变化,先锁表,更新表字典信息,然后会不会重新整理表,在有交易的情况下导致大量交易失效&#…...

全栈工程师需要具备哪些技能?
概论: 全栈工程师是一位能够从头到尾构建 Web 应用程序的工程师,能独立完成产品。技术包括前端部分、后端部分和应用程序所在的基础架构。他们在整个技术栈中工作,并了解其中的每个部分。从需求分析开始,到概要设计,详…...

用java实现客服聊天+网络爬虫下载音乐(java网络编程,io,多线程)
一 灵感: 在2022年的暑假,也就是我即将迈进高三的那个暑假,我并没有察觉自己应该要学习了,还是和过往的暑假一样玩着王者荣耀,凌晨2点睡觉,中午12点起床。我依稀记得这种状态一直持续到8月19。然而离开学还…...

基于springboot+vue的医院信息管理系统
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...

乡村振兴与农业科技创新:加大农业科技研发投入,推动农业科技创新,促进农业现代化和美丽乡村建设
一、引言 在当代中国,乡村振兴已成为国家发展的重要战略之一。作为国民经济的基础,农业的发展直接关系到国家的稳定和人民的福祉。随着科技的不断进步,农业科技创新在推动农业现代化和美丽乡村建设中发挥着越来越重要的作用。本文旨在探讨如…...
Java 雪花算法:分布式唯一ID生成的魔法秘籍
欢迎来到本次博客的旅程,今天我们要揭开一个神秘算法的面纱,它就是在分布式系统中广受欢迎的——雪花算法(Snowflake)。这个算法不是用来预测雪花的形状,而是用来生成唯一的ID,保证在分布式系统中ÿ…...
mybatis配置环境流程
mybatis配置环境流程 为啥要用mybatis:通过Mybatis实现快速访问后端pgsql、mysql等数据库。 1.修改pom.xml,添加mybatis相关依赖 <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-s…...

UE5增强输入系统入门
UE4直接在项目设置里设置的轴映射和操作映射在UE5中被标记为废弃,改为使用增强输入系统。 这两天学习了下蓝图和c中增强输入系统的使用,在这里分享一下。 学习使用的模板是第三人称模板(蓝图/c),代码蓝图都参考的模板。 增强输入系统 UE5…...
Python 语法好乱:深度解析与应对策略
Python 语法好乱:深度解析与应对策略 Python,作为一门简洁明了的编程语言,广受编程初学者的喜爱。然而,随着学习的深入,许多学习者会发现Python的语法似乎并不像初看起来那么简单,甚至有时会感到“好乱”。…...
移动端框架:加速移动应用开发与提升跨平台兼容性
在当今快速发展的移动应用领域,开发者们面临着如何快速构建、维护并发布跨平台应用的挑战。为了应对这一挑战,移动端框架应运而生,它们不仅加速了移动应用的开发流程,还提升了应用的跨平台兼容性,并确保了应用性能与原…...
Linux systemctl:掌握软件启动和关闭的利器
Linux systemctl:掌握软件启动和关闭的利器 在 Linux 操作系统中,systemctl 是一个强大的工具,用于管理系统服务的启动、停止和状态监控。本篇博客将深入介绍 systemctl 的使用方法,帮助你更好地掌握软件的启动和关闭。 1. syst…...

Jmeter干货分享:当你的Log viewer不显示日志时,可能是引入的Jar包冲突导致
问题描述 近期使用Jmeter时发现了一个非常奇怪的问题,就是Jmeter是可以正常使用运行脚本,但是在Log viewer中确没有任何日志,如下图: 问题排查过程 真是百思不得其解啊,在网上各种获取资料,大多数都是说跟…...

网络编程TCP
White graces:个人主页 🙉专栏推荐:Java入门知识🙉 🙉 内容推荐:Java网络编程(下)🙉 🐹今日诗词: 壮士当唱大风哥, 宵小之徒能几何?🐹 ⛳️点赞 ☀️收藏⭐️关注💬卑微…...
C++中的迭代器
目录 摘要 迭代器类别 1. 输入迭代器(Input Iterator) 2. 输出迭代器(Output Iterator) 3. 前向迭代器(Forward Iterator) 4. 双向迭代器(Bidirectional Iterator) 5. 随机访…...

8.1 Go 包的概念与使用
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...

第一篇【传奇开心果系列】AI工业应用经典算法和Python示例:基于AI的智能制造技术经典算法与Python实践
传奇开心果博文系列 系列博文目录AI工业应用经典算法和Python示例系列 博文目录前言一、AI在智能制造方面的应用场景介绍二、基于AI的智能制造技术经典算法介绍三、支持向量机机器学习算法Python示例代码四、随机森林机器学习算法Python示例代码五、深度学习算法Python示例代码…...

Mathtype插入编号的高级格式会重置之前的简单格式的问题
文章标题没说人话,大致意思是: 先以简单格式插入几个编号 再设置高级格式的编号时,即使没有选择插入编号,在点击下图的确定键时,会连带前面的简单公式一并更新 我在网上没有找到相关的问题,即使关闭了…...

弘君资本:存储芯片概念强势,西测测试三连板,佰维存储涨超10%
存储芯片概念3日盘中强势拉升,截至发稿,西测测验、万润科技涨停,佰维存储涨超10%,香农芯创涨近7%,航天智装、普冉股份等涨超5%。值得注意的是,西测测验已连续3个交易日涨停。 职业方面,当时干流…...

【机器学习】逻辑回归:原理、应用与实践
🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 💫个人格言: "如无必要,勿增实体" 文章目录 逻辑回归:原理、应用与实践引言1. 逻辑回归基础1.1 基本概念1.2 Sig…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...

对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...

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

android RelativeLayout布局
<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

9-Oracle 23 ai Vector Search 特性 知识准备
很多小伙伴是不是参加了 免费认证课程(限时至2025/5/15) Oracle AI Vector Search 1Z0-184-25考试,都顺利拿到certified了没。 各行各业的AI 大模型的到来,传统的数据库中的SQL还能不能打,结构化和非结构的话数据如何和…...
【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统
Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...
绕过 Xcode?使用 Appuploader和主流工具实现 iOS 上架自动化
iOS 应用的发布流程一直是开发链路中最“苹果味”的环节:强依赖 Xcode、必须使用 macOS、各种证书和描述文件配置……对很多跨平台开发者来说,这一套流程并不友好。 特别是当你的项目主要在 Windows 或 Linux 下开发(例如 Flutter、React Na…...
用鸿蒙HarmonyOS5实现国际象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的国际象棋小游戏的完整实现代码,使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├── …...