SpringBoot3.4.1和Spring Security6.4.2实现基于内存和MySQL的用户认证
SpringBoot3.4.1和Spring Security6.4.2实现基于内存和MySQL的用户认证

前一篇文章基于SpringBoot3.4.1整合Spring Security6.4.2实现了简单的身份认证。今天基于SpringBoot3.4.1和Spring Security6.4.2实现基于内存和数据库的用户认证,并结合Swagger对代码进行测试。在上一篇文章的项目中,我们启动项目后系统会生成默认的用户user和密码(控制台打印),如果你不想使用默认的用户名和密码,你可以在项目的application.properties文件中添加如下配置
spring.security.user.name=admin
spring.security.user.password=123456
完整代码在文章最后,如果觉得本篇文章对你有用,记得点赞、关注、收藏哦。你的支持是我持续更新的动力!
文章最后可以加入免费的Java技术栈沟通社群,请按照要求加入。在群中可以聊开发、系统设计、架构、行业趋势、AI等等话题
SpringBoot3专栏软件环境
- JDK17.0.12
- SpringBoot3.4.1
- Spring Security6.4.2
- Thymeleaf3.4.1
- MySQL8.4.3
- mybatis-plus-spring-boot3-starter3.5.9
- knife4j-openapi3-jakarta-spring-boot-starter4.5.0
- IDEA2024.3.2
我们先看本篇文章对应的项目结构,请看下图

Spring Security官方文档
https://docs.spring.io/spring-security/reference/servlet/configuration/java.html
1 父工程依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.itbeien</groupId>
<artifactId>springboot3-labs-master</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>springboot-springsecurity</artifactId>
<packaging>pom</packaging>
<modules>
<module>springsecurity-simple</module>
<module>springsecurity-memory</module>
<module>springsecurity-mysql8.4.3</module>
</modules>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2 基于内存实现用户认证
2.1 基于内存用户认证流程
- 创建InMemoryUserDetailsManager对象
- 创建User对象,设置用户名和密码
- 使用InMemoryUserDetailsManager将User存入内存
- SpringSecurity自动调用InMemoryUserDetailsManager的loadUserByUsername方法从内存中获取User对象
- 在UsernamePasswordAuthenticationFilter过滤器中的attemptAuthentication方法中将用户输入的用户名、密码和从内存中获取的用户信息进行比对,最后进行用户认证
2.2 代码实现
package cn.itbeien.springsecurity.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
/**
* @author itbeien
* 项目网站:https://www.itbeien.cn
* 公众号:贝恩聊架构
* 全网同名,欢迎小伙伴们关注
* Copyright© 2024 itbeien
*/
@Configuration
//@EnableWebSecurity //springboot项目中可以不用写该配置注解
public class FrameworkSecurityConfig {
@Bean
public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withDefaultPasswordEncoder().username("itbeien").password("itbeien").roles("USER").build());
return manager;
}
}
2.3 代码测试
2.3.1 启动项目

2.3.2 登录系统
访问http://localhost:8888/ss,输入itbeien/itbeien登录系统

3 基于数据库实现用户认证
3.1 基于数据库用户认证流程
- 创建MySQLUserDetailsManager类,实现接口UserDetailsManager,UserDetailsPasswordService
- SpringSecurity自动调用MySQLUserDetailsManager的loadUserByUsername方法从数据库中获取User对象
- 在UsernamePasswordAuthenticationFilter过滤器中的attemptAuthentication方法中将用户输入的用户名、密码和从数据库中获取的用户信息进行比对,最后进行用户认证
3.2 子工程依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>cn.itbeien</groupId>
<artifactId>springboot-springsecurity</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<artifactId>springsecurity-mysql8.4.3</artifactId>
<properties>
<mysql-connector-java-version>8.0.33</mysql-connector-java-version>
<knife4j-openapi3-jakarta-spring-boot-starter-version>4.5.0</knife4j-openapi3-jakarta-spring-boot-starter-version>
</properties>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java-version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId>
<version>${knife4j-openapi3-jakarta-spring-boot-starter-version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
3.3 配置信息
server.port=8888
server.servlet.context-path=/ss
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.0.105:3306/ss
spring.datasource.username=root
spring.datasource.password=rootpwd20241215
spring.sql.init.schema-locations=classpath:db/table-mysql.sql
spring.sql.init.data-locations=classpath:db/data-mysql.sql
spring.sql.init.mode=always
logging.level.cn.itbeien.mybatis.plus=debug
3.4 数据库表和数据
DROP TABLE IF EXISTS sys_user;
-- 创建用户表
CREATE TABLE `sys_user`
(
`id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
`user_name` VARCHAR(50) NOT NULL,
`password` VARCHAR(500) NOT NULL
);
-- 创建唯一索引
create unique index `user_name_index` on sys_user (`user_name`);
DELETE FROM sys_user;
INSERT INTO `sys_user` (`user_name`, `password`) VALUES ('itbeien', '{bcrypt}$2a$10$wPk8oL1SONvc90d5dB.whew4TqzEs6zzmmgmCV7e5DRt.wXW1WxgG');
INSERT INTO `sys_user` (`user_name`, `password`) VALUES ('itdatong', '{bcrypt}$2a$10$syDjRnXAPOmNE5eqWFwjDeXDqpOUKr.JYNeK8fYQpbOqJOlWpyZEe');
3.5 核心代码
3.5.1 配置类代码
package cn.itbeien.springsecurity.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
/**
* @author itbeien
* 项目网站:https://www.itbeien.cn
* 公众号:贝恩聊架构
* 全网同名,欢迎小伙伴们关注
* Copyright© 2024 itbeien
*/
@Configuration
//@EnableWebSecurity //springboot项目中可以不用写该配置注解
public class FrameworkSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(authorize -> authorize
.anyRequest().authenticated()
)
.formLogin(Customizer.withDefaults())
.httpBasic(Customizer.withDefaults());
//方便使用swagger测试先关闭csrf攻击防御
http.csrf(csrf->csrf.disable());
return http.build();
}
/* @Bean
public UserDetailsService userDetailsService() {
InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
manager.createUser(User.withDefaultPasswordEncoder().username("itbeien").password("itbeien").roles("USER").build());
return manager;
}*/
/**
* 创建基于MySQL数据库的用户信息
* @return
*/
/* @Bean
public UserDetailsService userDetailsService() {
MySQLUserDetailsManager manager = new MySQLUserDetailsManager();
return manager;
}*/
}
3.5.2 Spring Security用户信息管理类
package cn.itbeien.springsecurity.config;
import cn.itbeien.springsecurity.entity.SysUser;
import cn.itbeien.springsecurity.mapper.SysUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Resource;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsPasswordService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.provisioning.UserDetailsManager;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.Collection;
/**
* @author itbeien
* 项目网站:https://www.itbeien.cn
* 公众号:贝恩聊架构
* 全网同名,欢迎小伙伴们关注
* Copyright© 2025 itbeien
*/
@Component
public class MySQLUserDetailsManager implements UserDetailsManager, UserDetailsPasswordService {
@Resource
private SysUserMapper sysUserMapper;
@Override
public UserDetails updatePassword(UserDetails user, String newPassword) {
return null;
}
/**
* 向数据库中创建用户
* @param user
*/
@Override
public void createUser(UserDetails user) {
SysUser sysUser = new SysUser();
sysUser.setUsername(user.getUsername());
sysUser.setPassword(user.getPassword());
sysUserMapper.insert(sysUser);
}
@Override
public void updateUser(UserDetails user) {
}
@Override
public void deleteUser(String username) {
}
@Override
public void changePassword(String oldPassword, String newPassword) {
}
@Override
public boolean userExists(String username) {
return false;
}
/**
* 根据用户名从数据库中查询用户信息
* @param username the username identifying the user whose data is required.
* @return
* @throws UsernameNotFoundException
*/
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_name", username);
SysUser sysUser = sysUserMapper.selectOne(queryWrapper);
if (sysUser == null) {
throw new UsernameNotFoundException(username);
}else {
Collection<GrantedAuthority> authorities = new ArrayList<>();
return new User(sysUser.getUsername(), sysUser.getPassword(), true, true,
true, true, authorities);
}
}
}
3.5.3 Service层代码
package cn.itbeien.springsecurity.service.impl;
import cn.itbeien.springsecurity.config.MySQLUserDetailsManager;
import cn.itbeien.springsecurity.entity.SysUser;
import cn.itbeien.springsecurity.mapper.SysUserMapper;
import cn.itbeien.springsecurity.service.SysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
/**
* @author itbeien
* 项目网站:https://www.itbeien.cn
* 公众号:贝恩聊架构
* 全网同名,欢迎小伙伴们关注
* Copyright© 2024 itbeien
*/
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
@Resource
private MySQLUserDetailsManager mySQLUserDetailsManager;
@Override
public void saveSysUser(SysUser sysUser) {
UserDetails userDetails = User.withDefaultPasswordEncoder().
username(sysUser.getUsername()).password(sysUser.getPassword()).build();
mySQLUserDetailsManager.createUser(userDetails);
}
public static void main(String[] args) {
UserDetails userDetails = User.withDefaultPasswordEncoder().username("itbeien").password("itbeien").build();
System.out.println( userDetails.getPassword());
}
}
3.5.4 Controller层代码
package cn.itbeien.springsecurity.controller;
import cn.itbeien.springsecurity.entity.SysUser;
import cn.itbeien.springsecurity.service.SysUserService;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @author itbeien
* 项目网站:https://www.itbeien.cn
* 公众号:贝恩聊架构
* 全网同名,欢迎小伙伴们关注
* Copyright© 2025 itbeien
*/
@RestController
@RequestMapping("/user")
public class SysUserController {
@Resource
private SysUserService sysUserService;
@GetMapping("/list")
public List<SysUser> getUsers() {
return sysUserService.list();
}
@PostMapping("/add")
public String addUser(@RequestBody SysUser sysUser) {
sysUserService.saveSysUser(sysUser);
return "success";
}
}
3.6 基于初始化用户登录
初始化到数据库中的两个用户及密码为itbeien/itbeien,itdatong/itdatong
3.6.1 启动系统

3.6.2 登录系统
访问http://localhost:8888/ss,输入itbeien/itbeien登录系统

3.7 基于Swagger新增用户
访问http://localhost:8888/ss,输入itbeien/itbeien登录系统后,再访问http://localhost:8888/ss/doc.html
注意:基于Swagger新增用户必须先把Spring Security默认开启的CSRF先关闭,详细配置信息见3.5.1

点击发送新增test用户

3.7.1 基于新增用户登录
先退出系统,然后输入http://localhost:8888/ss进行登录


以上就是我们今天SpringBoot3.4.1和Spring Security6.4.2实现基于内存和MySQL的用户认证的全部内容,完整代码在文章最后进行获取!
欢迎大家关注我的项目实战内容itbeien.cn,一起学习一起进步,在项目和业务中理解各种技术。

欢迎沟通交流技术和支付业务,一起探讨聚合支付/预付卡系统业务、技术、系统架构、微服务、容器化。并结合聚合支付系统深入技术框架/微服务原理及分布式事务原理。加入我的知识星球吧

SpringBoot3专栏
01SpringBoot3专栏-SpringBoot3.4.0整合Mybatis-plus和Mybatis
02SpringBoot3.4.0结合Mybatis-plus实现动态数据源
03mapstruct对象映射在Springboot3中这样用就对了
04RocketMQ5.3.1集成SpringBoot3.4.0就这样简单
05SpringBoot3.4.0整合Redisson实现分布式锁
06MySQL增量数据同步利器Canal1.1.7环境搭建流程
07SpringBoot3.4.0集成Canal1.1.7实现MySQL实时同步数据到Redis
08基于Docker-SpringBoot3.4.0集成Apache Pulsar4.0.1实现消息发布和订阅
09SpringBoot3.4.0整合消息中间件Kafka和RabbitMQ
10SpringBoot3.4.0整合ActiveMQ6.1.4
11SpringBoot3整合Spring Security6.4.2 安全认证框架实现简单身份认证
跟着我学微服务系列
01跟着我学微服务,什么是微服务?微服务有哪些主流解决方案?
05SpringCloudAlibaba之图文搞懂微服务核心组件在企业级支付系统中的应用
06JDK17+SpringBoot3.4.0+Netty4.1.115搭建企业级支付系统POS网关
07JDK17+SpringCloud2023.0.3搭建企业级支付系统-预付卡支付交易微服务
08JDK17+Dubbo3.3.2搭建企业级支付系统-预付卡支付交易微服务
09JDK17+SpringBoot3.3.6+Netty4.1.115实现企业级支付系统POS网关签到功能
贝恩聊架构-项目实战地址
欢迎大家一起讨论学习,加我备注"JAVA"拉你进入技术讨论群,在技术学习、成长、工作的路上不迷路!加我后不要急,每天下午6点左右通过!营销号免入

4 源码地址
贝恩聊架构-SpringBoot3专栏系列文章、资料和源代码会同步到以下地址,代码和资料每周都会同步更新
该仓库地址主要用于贝恩聊架构-SpringBoot3专栏、基于企业级支付系统,学习微服务整体技术栈
