SpringSecurity认证授权完整流程

SpringSecurity认证流程:loadUserByUsername()方法内部实现。

实现步骤:

  1. 构建一个自定义的service接口,实现SpringSecurity的UserDetailService接口。
  2. 建一个service实现类,实现此loadUserByUsername方法。
  3. 调用登录的login接口,会经过authenticationManager.authenticate(authenticationToken)方法。此方法会调用loadUserByUsername方法。
  4. 方法内部做用户信息的查询,判断用户名和密码是否正确,这是第一道认证。
@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;
}

登录成功

登陆失败

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/71685.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

本地部署DeepSeek R1大数据模型知识库

DeepSeek-V3 的综合能力 DeepSeek-V3 在推理速度上相较历史模型有了大幅提升。在目前大模型主流榜单中&#xff0c;DeepSeek-V3 在开源模型中位列榜首&#xff0c;与世界上最先进OpenAI 闭源模型不分伯仲。 1、下载Ollama运行大数据库 Ollama支持 Llama 3.3, DeepSeek-R1, Phi-…

云端秘境:EC2的奇幻之旅

在一个神秘的云端世界里&#xff0c;流传着一个传说——只要掌握了 EC2&#xff08;Elastic Compute Cloud&#xff09; 的奥秘&#xff0c;就能召唤出强大的骑士军团&#xff0c;在云端之上建造属于自己的帝国。年轻的程序法师 艾伦&#xff08;Allen&#xff09;&#xff0c;…

【javaEE】多线程(基础)

1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; Hello, Hello~ 亲爱的朋友们&#x1f44b;&#x1f44b;&#xff0c;这里是E绵绵呀✍️✍️。 如果你喜欢这篇文章&#xff0c;请别吝啬你的点赞❤️❤️和收藏&#x1f4d6;&#x1f4d6;。如果你对我的…

一周学会Flask3 Python Web开发-WTForms表单验证

锋哥原创的Flask3 Python Web开发 Flask3视频教程&#xff1a; 2025版 Flask3 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili 我们可以通过WTForms表单类属性的validators属性来实现表单验证。 常用的WTForms验证器 验证器说明DataRequired(messageNo…

STM32标准库代码详解之GPIO

GPIO的初始化代码如下&#xff1a; /*开启时钟*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启GPIOA的时钟&#xff0c;使用外设必须开启/*GPIO初始化*/ GPIO_InitTypeDef GPIO_InitStructure; //定义结构体变量 GPIO_InitStructure.GPIO_Mode GPIO_Mo…

华为欧拉系统 Tomcat 安装详解

1. 安装或确认安装 Java Tomcat 需要 Java 环境(JDK 或 JRE)才能运行。如果系统尚未安装 Java,可以使用以下命令安装 OpenJDK: # 更新软件包索引 yum update -y# 安装 OpenJDK 21(可根据需求安装其他版本,如 8、11、17 等) yum install -y java-21-openjdk java-21-op…

第六课:数据库集成:MongoDB与Mongoose技术应用

本文详细介绍了如何在Node.js应用程序中集成MongoDB数据库&#xff0c;并使用Mongoose库进行数据操作。我们将涵盖MongoDB在Ubuntu 20系统中的安装、Bash命令的CRUD操作、Mongoose数据建模&#xff08;Schema/Model&#xff09;、关联查询与聚合管道&#xff0c;以及实战案例—…

大数据学习(56)-Impala

&&大数据学习&& &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 承认自己的无知&#xff0c;乃是开启智慧的大门 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一下博主哦&#x1f91…

【C#】async与await介绍

1. 实例1 1.1 代码 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace ConsoleApp1 {class Program{static void Main(string[] args){Method1();Method2();Console.ReadKey();}public static…

【大模型基础_毛玉仁】1.1 基于统计方法的语言模型

【大模型基础_毛玉仁】1.1 基于统计方法的语言模型 1.语言模型基础1.1 基于统计方法的语言模型1.1.1 n-grams 语言模型1.1.2 n-grams 的统计学原理 1.语言模型基础 语言是概率的。语言模型&#xff08;LanguageModels, LMs&#xff09;旨在准确预测语言符号的概率。 将按照语…

JavaScript(最后一个元素的索引就是数组的长度减 1)array.length - 1

在不同的编程语言中&#xff0c;表示数组中最后一个元素的方法略有不同&#xff0c;但基本思路都是利用数组的长度或索引来实现。 以下是一些常见编程语言中获取数组最后一个元素的方法&#xff1a; 1. JavaScript: 使用 array.length - 1 索引: 这是最常见和传统的方法。Java…

SpringCloud中使用服务名调用场景总结

一 API Gateway 在 Spring Cloud API Gateway 中&#xff0c;通过使用 lb:// 前缀可以实现基于服务名的负载均衡路由。以下是具体的配置和使用方法&#xff1a; 1. 配置服务注册与发现 确保你的服务已经注册到服务注册中心&#xff08;如 Nacos 或 Eureka&#xff09;。API …

7V 至 30V 的超宽 VIN 输入范围,转换效率高达 96%的WD5030

WD5030 具备 7V 至 30V 的超宽 VIN 输入范围&#xff0c;这一特性使其能够适应多种不同电压等级的供电环境&#xff0c;无论是在工业设备中常见的较高电压输入&#xff0c;还是在一些便携式设备经过初步升压后的电压&#xff0c;WD5030 都能轻松应对&#xff0c;极大地拓展了应…

深度学习模型Transformer核心组件—自注意力机制

第一章&#xff1a;人工智能之不同数据类型及其特点梳理 第二章&#xff1a;自然语言处理(NLP)&#xff1a;文本向量化从文字到数字的原理 第三章&#xff1a;循环神经网络RNN&#xff1a;理解 RNN的工作机制与应用场景(附代码) 第四章&#xff1a;循环神经网络RNN、LSTM以及GR…

利用Ollama+AnythingLLM+本地向量数据库Milvus+本地DeepSeek大模型实现知识库的搭建

1. Ollama的搭建 基本介绍 Ollama是一个支持在Windows、Linux和MacOS上本地运行大语言模型的工具。它允许用户非常方便地运行和使用各种大语言模型,比如Qwen模型等。用户只需一行命令就可以启动模型。 Ollama 下载&#xff1a;https://ollama.com/download Ollama 官方主页&a…

如何搭建个人静态住宅IP:从零开始

你好&#xff01;今天我们将一起探索如何从头开始搭建个人静态住宅IP。无论您是为了远程办公、在线教育还是游戏加速&#xff0c;静态住宅IP都能带给您更稳定的网络体验。 一、准备阶段 1. 明确需求 首先&#xff0c;您需要清楚自己为什么需要静态住宅IP。可能是为了实现远程…

国产编辑器EverEdit - 安装扩展功能的方式

1 扩展管理 1.1 应用场景 由于各行各业工作场景的不同&#xff0c;编辑器不可能为所有行业都定制功能&#xff0c;因此&#xff0c;对于一些特殊的行业应用场景&#xff0c;某些资深工程师可能已经做了一些扩展&#xff0c;并分享到了共享平台&#xff0c;普通工程师可以安装这…

CUDA计时函数:精确测量GPU代码执行时间

在GPU编程中&#xff0c;精确测量代码执行时间是性能优化的关键步骤。CUDA提供了专门的计时工具来帮助开发者准确获取核函数&#xff08;Kernel&#xff09;、内存拷贝等操作的耗时。本文将详细介绍CUDA计时函数的使用方法&#xff0c;并通过实例代码演示如何高效测量GPU代码的…

Go语言集成DeepSeek API和GoFly框架文本编辑器实现流式输出和对话(GoFly快速开发框架)

说明 本文是GoFly快速开发框架集成Go语言调用 DeepSeek API 插件&#xff0c;实现流式输出和对话功能。为了方便实现更多业务功能我们在Go服务端调用AI即DeepSeek接口&#xff0c;处理好业务后再用Gin框架实现流失流式输出到前端&#xff0c;前端使用fetch请求接收到流式的mar…

SAP服务器进程预警通知

在财务月结&#xff0c;HR薪资核算等系统用户集中使用高峰时期。通过判断判断当前系统可用的并行对话框进程数&#xff0c;用户使用过多给出提示&#xff0c;服务器进程预警通知。 1. 根据配置的进程最大可使用率80%&#xff0c;根据进程数判断&#xff1a;当进程可用数少于20%…