Spring Security 实现自定义登录和认证(1)
1 SpringSecurity
1.1 导入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId>
</dependency>
1.2 编写配置类
在spring最新版中禁用了WebSecurityConfigurerAdapter类,官方推荐采用配置类的方法进行配置。
- 新建一个配置类,注意添加注释
@EnableWebSecurity

1.3 示例
-
在类中添加一个Bean,生成过滤方法
@Beanpublic SecurityFilterChain filterChain(HttpSecurity http) throws Exception{http.authorizeHttpRequests((authz) -> authz.anyRequest().authenticated()).httpBasic(withDefaults());return http.build();}
-
忽略某个路径下的请求
@Beanpublic WebSecurityCustomizer webSecurityCustomizer() {return (web) -> web.ignoring().requestMatchers("/level2", "/level3");}效果就是当我请求
http://localhost:8080/level2的时候,就会重复跳出登录页面
1.4 自定义User实现登录
1.4.1 编写User类

1.4.2 定义UserRepository接口,用来实现从数据库或其它地方查询User

1.4.3 自定义一个类实现UserDetails接口
该类实现了UserDetails接口,这个UserDetails接口就是来查找用户名什么的。下面创建一个类,它继承了自定义的MyUser类且实现了UserDetails接口。(为什么要继承MyUser类?因为官方示例这么做的。。。)

package com.wjj.security.domain;import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;import java.util.Collection;
import java.util.Collections;
import java.util.List;public class MyUserDetails extends MyUser implements UserDetails {//定义构造函数public MyUserDetails(MyUser myUser){super(myUser.getId(), myUser.getUsername(), myUser.getPassword());}@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return null;}@Overridepublic String getUsername() {return super.getUsername();//把这里改成父类返回的username}@Overridepublic boolean isAccountNonExpired() {return true;//改成true}@Overridepublic boolean isAccountNonLocked() {return true;}@Overridepublic boolean isCredentialsNonExpired() {return true;}@Overridepublic boolean isEnabled() {return true;}
}
1.4.4 定义一个类实现UserDetailsService接口
这个类是用来检索用户名和密码的,该类被DaoAuthenticationProvider调用,至于DaoAuthenticationProvider是什么可以查看官方文档。

package com.wjj.security.service;import com.wjj.security.domain.MyUser;
import com.wjj.security.domain.UserRepository;
import jakarta.annotation.Resource;
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;@Service
public class CustomUserDetailService implements UserDetailsService {//注入编写的UserRepository@Resourceprivate UserRepository userRepository;//根据username查询user@Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {MyUser user = userRepository.findUserByUsername(username);if(user == null){throw new UsernameNotFoundException(username + " Not found");}//要返回一个UserDetails//这个东西就是前面实现的那个类//用来验证该user是否有效return new MyUserDetails(user);}
}
可以看到本节的功能就是根据username寻找User,然后返回一个UserDetails。我甚至可以在上面的函数中直接从数据库或内存中查询User,而这行代码的功能正是如此:

1.4.5 实现UserRepository接口进行查找用户
在前面的代码中,loadUserByUsername 中的这行代码还没有实现其中的查询逻辑,接下来进行实现。

编写一个类实现findUserByUsername接口

在数据库进行User的查找就可以在这一步中实现了
package com.wjj.security.domain;import java.util.Map;public class MyUserRepository implements UserRepository{private Map<String, MyUser> usernameToUser;public MyUserRepository(Map<String, MyUser> usernameToUser){this.usernameToUser = usernameToUser;}@Overridepublic MyUser findUserByUsername(String username) {return usernameToUser.get(username);}
}
然后将这个MyUser变成Spring的一个Resource,因为我们前面在CustomUserDetailService中引用UserRepository时用到了@Resource注释:

1.4.6 创建内存用户
在Application中new一个MyUserRepository实例,作为一个内存中存在的用户,并把它交给Spring托管:
package com.wjj.security;import com.wjj.security.domain.MyUser;
import com.wjj.security.domain.MyUserRepository;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;import java.util.HashMap;
import java.util.Map;@SpringBootApplication
public class SecurityApplication {public static void main(String[] args) {SpringApplication.run(SecurityApplication.class, args);}@BeanMyUserRepository myUserRepository(){MyUser user = new MyUser(1L, "username", "{bcrypt}$2a$10$h/AJueu7Xt9yh3qYuAXtk.WZJ544Uc2kdOKlHu2qQzCh/A3rq46qm");Map<String, MyUser> myUserMap = new HashMap<>();myUserMap.put("username", user);return new MyUserRepository(myUserMap);}}
代码中的那堆字母时经过加密的密码,在前端用户输入密码之后传到后端时进行了加密。
1.4.7 启动项目进行登录

登陆成功:

相关文章:
Spring Security 实现自定义登录和认证(1)
1 SpringSecurity 1.1 导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId> </dependency>1.2 编写配置类 在spring最新版中禁用了WebSecurityConfigurerAdapter…...
Linux 进程:辨析wait与waitpid
目录一、wait二、waitpid(1)参数:pid(2)参数:status(3)参数:options(4)返回值wait 与 waitpid 这两个函数的作用是:等待子进程退出,在子进程退出后释放子进程资源,防止子进程变成僵尸进程。但准确的说&…...
移除元素(每日一题)
目录 一、题目描述 二、题目分析 2.1 方法一 2.1.1 思路 2.1.2 代码 2.2 方法二 2.2.1 思路 2.2.2 代码 一、题目描述 题目链接:27. 移除元素 - 力扣(LeetCode) 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数…...
打印名片-课后程序(Python程序开发案例教程-黑马程序员编著-第一章-课后作业)
实例2:打印名片 名片是标示姓名及其所属组织、公司单位和联系方法的纸片,也是新朋友互相认识、自我介绍的快速有效的方法。本实例要求编写程序,模拟输出效果如图1所示的名片。 图1 名片样式 实例目标 掌握print()函数的用法 实例分析 名片…...
为啥预编译SQL能够防止SQL注入
前言之前我一个搞网络安全的朋友问了我一个的问题,为啥用 PreparedStatement 预编译的 SQL 就不会有被 SQL 注入的风险?第一时间我联想到的是八股文中关于 Mybatis 的脚本 ${} 和 #{} 的问题,不过再想想,为啥 ${} 会有 SQL 注入的…...
IGKBoard(imx6ull)-SPI接口编程-回环测试
文章目录1- 使能imx6ull开发板SPI驱动2- 回环测试imx6ull开发板物理连接3- 编程SPI回环测试4- 代码重难点分析(1)spi_device结构体(2)spi_ioc_transfer结构体(3)ioctl函数对于SIP不了解的可以参考这篇文章&…...
Python基础学习10——类
基本概念 面向对象编程是最有效的软件编写方法之一。理解面向对象编程可以让你像程序员那样从一个更加宏观的角度去理解代码,并大大提高程序员之间的合作效率。面向对象编程的两个核心概念是对象和类 **对象:**对象是能帮助我们解决问题的具体东西。比如…...
项目实战典型案例14——代码结构混乱 逻辑边界不清晰 页面美观设计不足
代码结构混乱 逻辑边界不清晰 页面美观设计不足一:背景介绍问题1 代码可读性差,代码结构混乱问题2 逻辑边界不清晰,封装意识缺乏示例3.展示效果上的美观设计二:思路&方案问题一,代码可读性差,代码结构混…...
SpringBoot 读取自定义Properties参数
目录 1. 概述 2. 实现方式 2.1 Value方式 2.2 PropertySource与ConfigurationProperties相结合 3. 结束 1. 概述 最近想尝试写一个定时任务管理,相关参数不想在Spring的配置文件Application.yml或者Application.properties获取。想自己新建一个properties文件。顺…...
机器学习100天(三十七):037 朴素贝叶斯-挑个好西瓜!
《机器学习100天》完整目录:目录 机器学习100天,今天讲的是:朴素贝叶斯-挑个好西瓜! 红色石头已经了解了贝叶斯定理和朴素贝叶斯法,接下来已经可以很自信地去买瓜了。买瓜之前,还有一件事情要做,就是搜集样本数据。红色石头通过网上资料和查阅,获得了一组包含 10 组样…...
c#遍历窗口,根据标题获取handle并显示窗口
using System.Runtime.InteropServices;using System.Text;//1,定义//[DllImport("User32.dll", EntryPoint "FindWindow")]//public extern static IntPtr FindWindow(string lpClassName, string lpWindowName);[DllImport("user32.dll…...
MyBatis高频面试专题
一、介绍下MyBatis中的工作原理 1。介绍MyBatis的基本情况:ORM 2。原理: MyBatis框架的初始化操作处理SQL请求的流程 1.系统启动的时候会加载解析全局配置文件和对应映射文件。加载解析的相关信息存储在 Configuration 对象 Testpublic void test1(…...
曹云金郭德纲关系迎曙光,新剧《猎黑行动》被德云社弟子齐点赞
话说天下大势,分久必合,合久必分。这句话经过了历史的证明,如今依然感觉非常实用。 就拿郭德纲和曹云金来说,曾经后者是前者的得门生,两个人不但情同父子,曹云金还是郭德纲默认接班人。然而随着时间的流逝&…...
如何在 OpenEuler 系统中安装 Docker
Docker 是一种流行的开源容器化平台,它能够将应用程序与其依赖项打包成可移植的容器,从而简化了应用程序的部署和管理。本文将介绍在 OpenEuler 系统中安装 Docker 并使用 Docker 容器控制 5G 模块的具体步骤。 安装 Docker 安装 Docker 的具体步骤如下…...
MySQL日志管理
日志管理在数据库保存数据时,有时候不可避免会出现数据丢失或者被破坏,这种时候,我们必须保证数据的安全性和完整性,就需要使用日志来查看或者恢复数据了数据库中数据丢失或被破坏可能原因:误删除数据库数据库工作时&a…...
进 制
进制进制一、进制概念二、进制的转换三、二进制的运算3.1 与运算3.2 或运算3.3 非运算3.4 异或运算3.5 位运算(位移)四、原码、反码、补码4.1 原码4.2 反码4.3 补码五、浮点数十进制转换成二进制进制 一、进制概念 十进制是指逢十进一。 计算机中二进制…...
pycharm关联github、新建以及更新仓
此处已经默认你安装了git以及pycharm,这篇文章将会教给大家如何利用pycharm管理自己的github. 目录 pycharm关联github设置 Github创建新的仓 仓库的更新 pycharm:2022。不同版本界面略有不同。 pycharm关联github设置 设置PyCharm,打开File --> Settings -…...
java基础知识之小碎片(自问自答版本)---嘻嘻,春招加油呀~
1.public/private/protected/default的区别? public:对所有类可见 private 只有类本身可以访问,其他类想访问可以通过该类的成员方法访问如getter/setter protected:对同一包内的类和所有子类可见 default:在同一包内可见,不加修饰符 2.jav…...
蚁群算法c++
//轮盘赌选择下一步行进城市 int citySelect(int k, int f) { int c 0;//记录蚂蚁可行进的城市个数 //1、计算可行进的各城市 选择概率 for (int m 0; m < cityNum; m) { //若城市(i,j)之间有路且j不在蚂蚁k的禁忌表中…...
北大青鸟天府校区IT学习大揭秘
口罩已放开,一切都要重新出发。 开年才一个多月,已经有很多小伙伴想培训转行IT行业或者已经在咨询、报名培训IT技术。作为老牌培训机构,也有很多小伙伴相信我们,选择了我们。很感谢大家的信任,作为老牌培训机构&#…...
Segment-and-Track-Anything实战案例:从街景到细胞的全场景应用
Segment-and-Track-Anything实战案例:从街景到细胞的全场景应用 【免费下载链接】Segment-and-Track-Anything An open-source project dedicated to tracking and segmenting any objects in videos, either automatically or interactively. The primary algorith…...
AI原生应用领域链式思考:构建高效应用架构
AI原生应用领域链式思考:构建高效应用架构 关键词:AI原生应用、链式思考、应用架构、大模型协同、上下文管理 摘要:本文从AI原生应用的核心特征出发,结合"链式思考"这一关键设计模式,系统讲解如何构建高效能…...
如何用QtScrcpy实现跨平台Android设备高效投屏与控制
如何用QtScrcpy实现跨平台Android设备高效投屏与控制 【免费下载链接】QtScrcpy Android实时投屏软件,此应用程序提供USB(或通过TCP/IP)连接的Android设备的显示和控制。它不需要任何root访问权限 项目地址: https://gitcode.com/barry-ran/QtScrcpy 在数字化…...
广东省高级会计师评审辅导知名品牌
在职业发展的道路上,专业资格认证是许多财务从业者提升自我、拓宽职业路径的重要一环。广东省高级会计师评审,作为一项专业性强、要求严格的职业能力认定,其准备过程需要系统性的指导与支持。中山力朗教育咨询有限公司,作为一家立…...
别再手动刷新了!SAP ALV中利用change事件与modify_cell实现智能数据同步
SAP ALV开发进阶:巧用change事件与modify_cell构建智能数据联动体系 在SAP前端开发领域,ALV(ABAP List Viewer)作为最常用的数据展示控件,其交互体验直接影响用户操作效率。传统开发模式中,当用户修改某个单…...
价值投资中的智能城市废水处理与再利用系统分析
价值投资中的智能城市废水处理与再利用系统分析 关键词:价值投资、智能城市、废水处理、废水再利用、系统分析 摘要:本文聚焦于价值投资视角下的智能城市废水处理与再利用系统。首先介绍了研究的背景,包括目的、预期读者、文档结构和相关术语。接着阐述了智能城市废水处理与…...
TTI-Chicago等机构突破性研究:AI学会了一笔一划创作矢量草图
这项由芝加哥丰田技术研究院(TTI-Chicago)、芝加哥大学和麻省理工学院联合开展的研究发表于2026年,论文编号为arXiv:2603.19500v1。有兴趣深入了解技术细节的读者可以通过该编号查询完整论文。当我们看到一位画家创作时,他们通常不…...
【AI知识点】交叉注意力机制:连接不同世界的“信息桥梁”
1. 从"信息桥梁"理解交叉注意力机制 想象你正在同时阅读一本英文书和它的中文翻译版。当你遇到一个不太理解的英文句子时,会自然地在中文版本中寻找对应的段落来帮助理解——这个过程就像交叉注意力机制在神经网络中的工作方式。它就像是架设在两个不同世…...
深入理解SAP RAP中的语义依赖:从/DMO测试数据看BTP应用的数据建模精髓
解密SAP RAP语义依赖:从/DMO测试数据到企业级数据建模实战 在SAP BTP应用开发领域,数据建模的质量直接决定了系统的健壮性和可维护性。当我们在/DMO/CONNECTION表开发中遇到"DISTANCE字段具有单位量转换和EDM类型int32"的元数据错误时…...
5个步骤掌握MelonLoader:让Unity游戏模组开发变得轻松有趣
5个步骤掌握MelonLoader:让Unity游戏模组开发变得轻松有趣 【免费下载链接】MelonLoader The Worlds First Universal Mod Loader for Unity Games compatible with both Il2Cpp and Mono 项目地址: https://gitcode.com/gh_mirrors/me/MelonLoader 你是否曾…...
