若依系统(Security)增加微信小程序登录(自定义登录)
若依系统(分离版后端)自带的账号验证是基于
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
验证,然后在系统中controller或service类中 SecurityUtils 工具类中直接可获取用户或用户ID等
SecurityUtils.getLoginUser().getUser();
现在想实现,微信小程序通过code等登录后返回和之前一样的token后原逻辑中的SecurityUtils一样可以获取到,则需要自定义扩展登录类。废话不多说,上代码:
类似于UsernamePasswordAuthenticationToken类,自定义AuthCodeAuthenticationToken.java
在这个位置:

AuthCodeAuthenticationToken.java:
package com.ruoyi.framework;import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;import java.util.Collection;public class AuthCodeAuthenticationToken extends AbstractAuthenticationToken {private final Object principal;public AuthCodeAuthenticationToken(Object principal) {super(null);this.principal= principal;}public AuthCodeAuthenticationToken(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);}
}
AuthCodeAuthenticationProvider.java
package com.ruoyi.framework;import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;public class AuthCodeAuthenticationProvider implements AuthenticationProvider {private UserDetailsService userDetailsService;public AuthCodeAuthenticationProvider(UserDetailsService userDetailsService) {setUserDetailsService(userDetailsService);}@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {AuthCodeAuthenticationToken authCodeAuthenticationToken = (AuthCodeAuthenticationToken) authentication;String telephone = (String) authentication.getPrincipal();UserDetails userDetails = userDetailsService.loadUserByUsername(telephone);AuthCodeAuthenticationToken authenticationResult = new AuthCodeAuthenticationToken(userDetails, userDetails.getAuthorities());authenticationResult.setDetails(authentication.getDetails());return authenticationResult;}@Overridepublic boolean supports(Class<?> authentication) {return AuthCodeAuthenticationToken.class.isAssignableFrom(authentication);}public UserDetailsService getUserDetailsService() {return userDetailsService;}public void setUserDetailsService(UserDetailsService userDetailsService) {this.userDetailsService = userDetailsService;}
}
在这里还要重写UserDetailsServiceByAuthCodeImpl.java原逻辑是调用的UserDetailsServiceImpl.java中的loadUserByUsername方法。
package com.ruoyi.framework.web.service;import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.UserStatus;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;@Slf4j
@Service("userDetailsByAuthCode")
public class UserDetailsServiceByAuthCodeImpl implements UserDetailsService {@Autowiredprivate ISysUserService userService;@Autowiredprivate SysPermissionService permissionService;@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException{SysUser user = userService.selectUserByUserName(username);if (StringUtils.isNull(user)){log.info("登录用户:{} 不存在.", username);throw new ServiceException(MessageUtils.message("user.not.exists"));}else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())){log.info("登录用户:{} 已被删除.", username);throw new ServiceException(MessageUtils.message("user.password.delete"));}else if (UserStatus.DISABLE.getCode().equals(user.getStatus())){log.info("登录用户:{} 已被停用.", username);throw new ServiceException(MessageUtils.message("user.blocked"));}return createLoginUser(user);}public UserDetails createLoginUser(SysUser user){return new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));}
}
在SecurityConfig.java中配置自定义的登录逻辑(顶部注入,下面增加配置)
配置中api开头的接口,该放开(登录获取token的接口)的放开:



温馨提示:一定要区分原来的UserDetailsService 使用注解@Qualifier("userDetailsByAuthCode")区分,原来的也要加上,不然启动时候注入重复,原来的serviceImpl实现类也要加上,如下:

SysLoginService.java中
public String wxLogin(String userName){// 用户验证Authentication authentication = null;try{AuthCodeAuthenticationToken authCodeAuthenticationToken = new AuthCodeAuthenticationToken(userName);AuthenticationContextHolder.setContext(authCodeAuthenticationToken);// 该方法会去调用UserDetailsServiceImpl.loadUserByUsernameauthentication = authenticationManager.authenticate(authCodeAuthenticationToken);}catch (Exception e){if (e instanceof BadCredentialsException){AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));throw new UserPasswordNotMatchException();}else{AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGIN_FAIL, e.getMessage()));throw new ServiceException(e.getMessage());}}finally{AuthenticationContextHolder.clearContext();}AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));LoginUser loginUser = (LoginUser) authentication.getPrincipal();recordLoginInfo(loginUser.getUserId());// 生成tokenreturn tokenService.createToken(loginUser);}
接口调用中可以如下调用了:

相关文章:
若依系统(Security)增加微信小程序登录(自定义登录)
若依系统(分离版后端)自带的账号验证是基于 UsernamePasswordAuthenticationToken authenticationToken new UsernamePasswordAuthenticationToken(username, password); 验证,然后在系统中controller或service类中 SecurityUtils 工具类中直接可获取用户或用户…...
道可云人工智能元宇宙每日资讯|2024互联网岳麓峰会在长沙召开
道可云元宇宙每日简报(2024年9月10日)讯,今日元宇宙新鲜事有: 2024互联网岳麓峰会在长沙召开 9月9日,2024互联网岳麓峰会在长沙召开,湖南省副省长曹志强在峰会表示,今年上半年湖南省人工智能产…...
MySQL JDBC URL各参数详解
jdbc:mysql://localhost:3306/test?userroot&password123456&useUnicodetrue&characterEncodinggbk &autoReconnecttrue&failOverReadOnlyfalse&serverTimezoneUTC&drivercom.mysql.cj.jdbc.Driver 参数名称参数说明缺省值user指定用于连接数据库…...
celery control.shutdown
Celery 提供了 control 模块,允许你发送控制命令给正在运行的 worker。其中 shutdown 命令可以用来关闭一个或多个 worker。下面是如何使用 control.shutdown 来关闭 worker 的详细说明。 使用 control.shutdown 1. 导入必要的模块 首先,你需要导入 C…...
数据库设计与软件工程阶段的对应关系
数据库设计的很多阶段确实可以与软件工程的各阶段对应起来,这体现了数据库设计作为软件工程中一个核心组成部分的紧密关联性。 1. 需求分析阶段 数据库设计:需求分析是数据库设计的初始阶段,主要任务是收集和分析用户的需求,包括…...
基于ASP+ACCESS的教师信息管理系统
摘要 随着我国社会主义市场经济的发展和改革开放的不断深入,计算机的应用已遍及国民经济的各个领域,计算机来到我们的工作和生活中,改变着我们和周围的一切。在以前,学校用手工处理教师档案以及工资发放等繁多的工作和数据时&…...
【智能体】浅谈大模型之AI Agent
随着ChatGPT推出插件和函数调用功能,构建以LLM(大语言模型)为核心控制器的AI Agent愈发成为一个拥有无限可能的概念。 AI Agent是一种超越简单文本生成的人工智能系统。它使用大型语言模型(LLM)作为其核心计算引擎&am…...
大疆 嵌入式 笔记 面试题目汇总大全[嵌入式找工作必看] 比较有难度适合进阶收藏学习
24届大疆车载嵌入式系统安全面试经验 投递岗位:(大疆车载)嵌入式系统安全 投递时间:大疆大概在7月-8月月初开秋招岗位。8月月中开始笔试,8月月末开始面试。(理论上9月,10月开奖。)…...
线程池以及详解使用@Async注解异步处理方法
目录 一.什么是线程池: 二.使用线程池的好处: 三.线程池的使用场景: 四.使用线程池来提高Springboot项目的并发处理能力: 1.在application.yml配置文件中配置: 2.定义配置类来接受配置文件内的属性值:…...
css鼠标移动过去变成手的图标
在css中定义 cursor:pointer;直接在html中指定 <div class"mt-2 mt-md-2 mt-lg-1 fs-md-1 fs-lg-2 " style"cursor:pointer;"></div>...
uniapp 懒加载、预加载、缓存机制深度解析
uniapp 懒加载、预加载、缓存机制深度解析 文章目录 uniapp 懒加载、预加载、缓存机制深度解析一、为什么要使用uniapp的懒加载、预加载和缓存机制二、如何使用uniapp的懒加载、预加载和缓存机制1. 懒加载2. 预加载3. 缓存机制 四、扩展与高级技巧1. 结合懒加载和预加载优化页面…...
《OpenCV计算机视觉》—— 图像形态学(腐蚀、膨胀等)
文章目录 一、图像形态学基本概念二、基本运算1.简单介绍2.代码实现 三、高级运算1.简单介绍2.代码实现 一、图像形态学基本概念 图像形态学是图像处理科学的一个独立分支,它基于集合论和数学形态学的理论,专门用于分析和处理图像中的形状和结构。图像形…...
【Rust光年纪】海洋学研究的利器:Rust语言海洋学计算库详解
探索Rust语言下的海洋学计算库:功能对比与选择指南 前言 随着科学技术的不断发展,海洋学领域对于计算和数据处理的需求也日益增长。在Rust语言中,出现了一系列专注于海洋学计算和数据处理的库,它们为海洋学工作者提供了强大的工…...
Word文档的读入【2】
现在,乔老师已经了解了Word文档的基本结构。 下面,我们通过观察一份答题卡来思考一下每条信息的具体位置。这样,在后面几天的学习和操作中,我们就能更快、更准确地读取到答题卡中的信息。 这份答题卡是由一个表格和一些段落组成。…...
报名开启 | 游戏开发缺队友?首期繁星招聘会来袭!
**点击蓝链领取游戏开发教程 ** EE GAMES 创作者社区是专注于链接每一位游戏创作者,提供社区交流、团队匹配、经验共享、成果展示、知识整合、最新活动资讯等全方位服务的游戏领域垂类社区。 这里不仅仅是一个游戏创作的互助平台,更是每一位游戏创作者…...
无法加载源https://api.nuget.org/v3/index.json的服务索引
我是用的visual studio2022 17.11.2版本,在运行.net c#项目的时候显示“无法加载源https://api.nuget.org/v3/index.json的服务索引”,从网上找了一堆方法全部没用,最后用这个方法解决了。亲测有效家人们 关闭VS,删除C:\Users\xx…...
C#--CM+Fody+HCWPF开发组合
CM:Caliburn.Micro(简称CM)一经推出便备受推崇,作为一款MVVM开发模式的经典框架,越来越多的受到wpf开发者的青睐.我们看一下官方的描述:Caliburn是一个为Xaml平台设计的小型但功能强大的框架。Micro实现了各种UI模式,用…...
力扣474-一和零(Java详细题解)
题目链接:474. 一和零 - 力扣(LeetCode) 前情提要: 因为本人最近都来刷dp类的题目所以该题就默认用dp方法来做。 最近刚学完01背包,所以现在的题解都是以01背包问题为基础再来写的。 如果大家不懂01背包的话&#…...
【话题】量子计算:前沿技术与应用前景深度解析
引言 在当今信息时代,计算能力已成为推动科技进步和社会发展的重要驱动力。随着摩尔定律逐渐接近其物理极限,传统计算机硬件的性能提升面临前所未有的挑战。在此背景下,量子计算作为一种革命性的计算范式,凭借其独特的量子力学属性…...
第11章 32位x86处理器编程架构
第11章 32位x86处理器编程架构 IA-32(INTEL Architecture, 32-bit):INTEL 32位处理器架构简称IA-3,以8086处理器为基础发展起来的。该章重点介绍了IA-32处理器的工作方式和相关技术。 IA-32架构的基本执行环境 寄存器的扩展 32位处理器通用寄存器&am…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
Xshell远程连接Kali(默认 | 私钥)Note版
前言:xshell远程连接,私钥连接和常规默认连接 任务一 开启ssh服务 service ssh status //查看ssh服务状态 service ssh start //开启ssh服务 update-rc.d ssh enable //开启自启动ssh服务 任务二 修改配置文件 vi /etc/ssh/ssh_config //第一…...
Go 语言接口详解
Go 语言接口详解 核心概念 接口定义 在 Go 语言中,接口是一种抽象类型,它定义了一组方法的集合: // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的: // 矩形结构体…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
spring:实例工厂方法获取bean
spring处理使用静态工厂方法获取bean实例,也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下: 定义实例工厂类(Java代码),定义实例工厂(xml),定义调用实例工厂ÿ…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
