若依前后端分离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…...
从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
聊一聊接口测试的意义有哪些?
目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...
