SpringSecurity认证授权完整流程
SpringSecurity认证流程:loadUserByUsername()方法内部实现。
实现步骤:
- 构建一个自定义的service接口,实现SpringSecurity的UserDetailService接口。
- 建一个service实现类,实现此loadUserByUsername方法。
- 调用登录的login接口,会经过authenticationManager.authenticate(authenticationToken)方法。此方法会调用loadUserByUsername方法。
- 方法内部做用户信息的查询,判断用户名和密码是否正确,这是第一道认证。
@Service
@RequiredArgsConstructor
public class UserDetailsServiceImpl implements UserDetailsService {private final SysUserMapper sysUserMapper;//用户登录请求/login,自动调用方法//根据用户名获取用户信息//UserDetails 存储用户信息,包括用户名,密码,权限@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<>();wrapper.eq(SysUser::getUsername, username);SysUser sysUser = sysUserMapper.selectOne(wrapper);if (Objects.isNull(sysUser)){throw new UsernameNotFoundException("用户名不存在");}//认证成功回UserDetails对象return new LoginUser(sysUser);}}

@ToString
public class LoginUser implements UserDetails {private SysUser sysUser;public LoginUser(SysUser sysUser) {this.sysUser = sysUser;}// 权限@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return List.of();}@Overridepublic String getPassword() {return sysUser.getPassword();}@Overridepublic String getUsername() {return sysUser.getUsername();}// 账号是否过期@Overridepublic boolean isAccountNonExpired() {return true;}// 账号是否被锁定@Overridepublic boolean isAccountNonLocked() {return true;}// 密码是否过期@Overridepublic boolean isCredentialsNonExpired() {return true;}// 账号是否可用@Overridepublic boolean isEnabled() {return true;}
}
5.如果没有查到信息就抛出异常。
6.如果查到信息了再接着查用户的权限信息,返回权限信息到loginUser实体。
7.此实体实现了SpringSecurity自带的userDetail接口。实现了getAuthorities方法。
.8每次查询权限都会调用此方法。
9.查询到的权限,会被返回到login接口。进行后续操作。
10.如果认证通过,通过身份信息中的userid生产一个jwt。
11.把完整的用户信息作为value,token作为key存入redis。
@RestController
@Tag(name = "认证模块", description = "认证模块")
@RequestMapping("/auth")
@RequiredArgsConstructor
public class AuthController {//注入AuthenticationManager(认证管理器)private final AuthenticationManager authenticationManager;private final JwtUtils jwtUtils;@PostMapping("/login")@Operation(summary = "登录")public Result login(@RequestParam("username") String username, @RequestParam("password") String password) {System.out.println(username + password);//登录逻辑//调用UserDetailsService.loadUserByUsername方法获取//不能直接调用,需要通过AuthenticationManager进行认证Authentication authentication = new UsernamePasswordAuthenticationToken(username, password);Authentication authenticate = null;try {authenticate = authenticationManager.authenticate(authentication);} catch (BadCredentialsException e) {return Result.failed(ResultCode.USERNAME_OR_PASSWORD_ERROR);}//认证成功方法tokenString token=jwtUtils.generateToken(authenticate);return Result.success(token);}
}

@Configuration
@EnableWebSecurity // 开启web安全
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {private final IgnoredUrl ignoredUrl;/*** 配置认证管理器 AuthenticationManager* 作用:用于身份认证* 参数:UserDetailsService, PasswordEncoder*/@Beanpublic AuthenticationManager authenticationManager(UserDetailsService userDetailsService, PasswordEncoder passwordEncoder) {DaoAuthenticationProvider provider = new DaoAuthenticationProvider();provider.setUserDetailsService(userDetailsService);provider.setPasswordEncoder(passwordEncoder);return new ProviderManager(provider);}/*** 密码编码器** @return*/@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {//关闭csrf防护,否则回导致登录失败http.csrf(a -> a.disable()); //禁用SCRF//配置安全拦截规则http.authorizeHttpRequests(req ->req.requestMatchers(ignoredUrl.getUrls()).permitAll().anyRequest().authenticated());/*** 配置登录页*/http.formLogin(form -> form.loginPage("/").successForwardUrl("/index") //登录成功跳转页面.loginProcessingUrl("/login")//登录处理url.failureForwardUrl("/error") //登录失败跳转页面// .usernameParameter("name")//自定义用户名参数// .passwordParameter("password")//自定义密码参数);return http.build();}
}
@Component
public class JwtUtils {@Value("${jwt.secret}")private String secret;@Value("${jwt.expiration}")private Integer expiration;/****/public String generateToken(Authentication authentication) {Date now = new Date();Date expirationDate = DateUtil.offsetSecond(now, expiration);Map<String, Object> claims = new HashMap<>();claims.put("username", authentication.getName());//用户名claims.put("exp", expirationDate);// claims.put();return JWTUtil.createToken(claims, secret.getBytes());}
}
@Component
@Data
@ConfigurationProperties(prefix = "security.ignored")
@ToString
public class IgnoredUrl {private String[] urls;
}

登录成功

登陆失败

相关文章:
SpringSecurity认证授权完整流程
SpringSecurity认证流程:loadUserByUsername()方法内部实现。 实现步骤: 构建一个自定义的service接口,实现SpringSecurity的UserDetailService接口。建一个service实现类,实现此loadUserByUsername方法。…...
MongoDB用户管理和复制组
用户管理 1、建用户时,use到的库就是此用户的验证库 2、登录时必须明确指定验证库才能登录 3、通常管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库 4、如果直接登录到数据库,不进行use(示例ÿ…...
【Android】setText调用导致的悬浮窗抖动问题
在Android13中,有这么一个bug,写一个可以拖到的悬浮窗,这个悬浮窗里有TextView,在拖到某个位置后,再调用TextView的setText方法,会发现出现了一个窗口动画,悬浮窗跳到了起始位置,从开…...
【从零开始学习计算机科学】数字逻辑(四)数字系统设计
【从零开始学习计算机科学】数字逻辑(四)数字系统设计 数字系统设计硬件描述语言 HDL(Hardware Description Language)Verilog HDL 的起源与发展HDL 软核、固核和硬核的重用HDL 的应用数字系统设计实现数字系统设计 一个数字集成电路的可以从不同的层次(系统级、算法级、…...
QT 作业 C++ day5
作业 代码 MyQThread.h class MyThread : public QThread {Q_OBJECT public:MyThread(QObject *parent nullptr); protected:void run() override; signals://向ui界面发送的 "复制进度" 的信号void copy_process_signal(int index); public slots:// "复…...
洛谷 P2234:[HNOI2002] 营业额统计 ← STL set
【题目来源】 https://www.luogu.com.cn/problem/P2234 【题目描述】 Tiger 最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger 拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析…...
植物神经功能紊乱检查不出来,浑身难受?
植物神经功能紊乱,又称为自主神经功能失调,是一种功能性神经症,它涉及身体多个系统的不规则反应,通常没有器质性病变作为基础。这意味着,尽管患者可能会体验到多种症状,如焦虑、紧张、心悸、疲劳、失眠等&a…...
vue3 遇到babel问题(exports is not defined) 解决方案
由于我在引用ant-design-vue插件,于是产生了下图的问题。 1.问题分析 Babel 是一个 JavaScript 编译器,主要用于:将 ES6 代码转译为 ES5 代码,以兼容旧版浏览器。处理模块化语法(如 import/export)。 2.解…...
基于SpringBoot+Vue的工商局商家管理系统
开发语言:Java框架:springbootJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:…...
ESP8266 入门(第 2 部分):使用 AT 命令
使用 AT 命令对 WiFi 收发器ESP8266编程 本教程是上一个教程 ESP8266 入门(第 1 部分)的延续。因此,简单回顾一下,在之前的教程中,我们介绍了 ESP 模块,并学习了一些基础知识。我们还使用 FTDI 串行适配器模块制作了一个开发板,该模块可以很容易地用于使用 AT 命令和 A…...
【CSS3】筑基篇
目录 复合选择器后代选择器子选择器并集选择器交集选择器伪类选择器 CSS 三大特性继承性层叠性优先级 背景属性背景色背景图背景图平铺方式背景图位置背景图缩放背景图固定背景复合属性 显示模式显示模式块级元素行内元素行内块元素 转换显示模式 结构伪类选择器结构伪类选择器…...
11-Agent中配置自己的插件
目录 关键词 摘要 速览 配置和集成自定义插件 使用AI插件在直播间绘制图像 API接口调用及配置说明 创建和配置API工具以生成图像 编写和配置参数及API调用说明 如何配置和使用API进行HTTP请求 配置和测试API插件的步骤 思维导图 发言总结 要点回顾 如何配置一个专…...
2025-03-08 学习记录--C/C++-PTA 习题10-1 判断满足条件的三位数
合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。💪🏻 一、题目描述 ⭐️ 裁判测试程序样例: #include <stdio.h> #include <math.h>int search( int n );int…...
INFINI Labs 产品更新 | Easysearch 增加异步搜索等新特性
INFINI Labs 产品更新发布!此次更新,Easysearch 增加了新的功能和数据类型,包括 wildcard 数据类型、Point in time 搜索 API、异步搜索 API、数值和日期字段的 doc-values 搜索支持,Console 新增了日志查询功能。 INFINI Easyse…...
关于网络数通工程师 OSPF 协议的常见面试问题
基础理论部分 OSPF是什么?其核心设计目标及主要特性有哪些? OSPF(开放式最短路径优先)是基于链路状态的内部网关协议(IGP),使用Dijkstra的SPF算法计算最短路径树,核心目标包括…...
Go 语言 + libbpfgo 实战 eBPF 开发
Go 语言 libbpfgo 实战 eBPF 开发 1. 引言 这是专栏的第一篇文章,我们将从环境准备、示例代码运行和详解三个方面,带你快速入门 eBPF 开发。 📌 读完这篇文章,你将学会: ✔️ 如何用 Go libbpfgo 开发 eBPF 程序。…...
练习题:74
目录 Python题目 题目 题目分析 需求理解 关键知识点 实现思路分析 复杂度分析 可能遇到的问题及注意事项 代码实现 代码解释 运行思路 1. 列表定义阶段 2. for 循环启动阶段 3. 偶数判断与 continue 语句执行阶段 4. 奇数元素输出阶段 5. 循环结束阶段 结束语…...
Python 性能优化:从入门到精通的实用指南
Langchain系列文章目录 01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...
C# OPC DA获取DCS数据(提前配置DCOM)
OPC DA配置操作手册 配置完成后,访问远程ip,就能获取到服务 C#使用Interop.OPCAutomation采集OPC DA数据,支持订阅(数据变化)、单个读取、单个写入、断线重连...
xinference docker 部署方式
文章目录 简绍docker 安装方式访问地址对应官网在 dify 中 添加 xinference 容器内置大语言模型嵌入模型图像模型音频模型重排序模型视频模型 简绍 Xorbits Inference (Xinference) 是一个开源平台,用于简化各种 AI 模型的运行和集成。借助 Xinference,…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
