SpringBoot3.4.1和Spring Security6.4.2结合JWT实现用户登录
SpringBoot3.4.1和Spring Security6.4.2结合JWT实现用户登录

蛇年到啦,愿你今年的每一个小目标都轻松达成,收获满满的快乐与成长。不管遇到什么,都能元气满满,万事胜意!
前一篇文章SpringBoot3.4.1和Spring Security6.4.2结合OAuth2实现GitHub授权登录。今天基于SpringBoot3.4.1和Spring Security6.4.2结合JWT实现用户登录,登录成功返回Token。
完整代码在文章最后,如果觉得本篇文章对你有用,记得点赞、关注、收藏哦。你的支持是我持续更新的动力!
文章最后可以加入免费的Java技术栈沟通社群,请按照要求加入。在群中可以聊开发、系统设计、架构、行业趋势、AI等等话题
SpringBoot3专栏软件环境
- JDK17.0.12
- SpringBoot3.4.1
- Spring Security6.4.2
- JWT
- MySQL8.4.3
- mybatis-plus-spring-boot3-starter3.5.9
- IDEA2024.3.2
我们先看本篇文章对应的项目结构,请看下图

1 代码实现
1.1 pom依赖
<?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>
<groupId>cn.itbeien.security.jwt</groupId>
<artifactId>springsecurity-jwt</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jaxb-api.version>2.3.1</jaxb-api.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>
<!--JWT(Json Web Token)登录支持-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>${jaxb-api.version}</version>
</dependency>
</dependencies>
</project>
1.2 配置信息
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.110: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
#JWT存储的请求头
jwt.tokenHeader=Authorization
#JWT加解密使用的密钥
jwt.secret=itbeien-ss-secret
#JWT的超期限时间(60*60*24*7)
jwt.expiration=604800
#JWT负载中拿到开头
jwt.tokenHead='Bearer '
secure.ignored.urls=/api/v1/login,/doc.html
1.3 controller
package cn.itbeien.security.jwt.controller;
import cn.itbeien.security.jwt.dto.CommonResult;
import cn.itbeien.security.jwt.dto.SystemLoginParam;
import cn.itbeien.security.jwt.service.SystemService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
/**
* @author itbeien
* 项目网站:https://www.itbeien.cn
* 公众号:贝恩聊架构
* 全网同名,欢迎小伙伴们关注
* Copyright© 2025 itbeien
*/
@RestController
@RequestMapping("/api/v1")
public class SystemController {
@Autowired
private SystemService systemService;
@Value("${jwt.tokenHead}")
private String tokenHead;
@RequestMapping(value = "/login", method = RequestMethod.POST)
@ResponseBody
public CommonResult login(@Validated @RequestBody SystemLoginParam systemLoginParam) {
String token = systemService.login(systemLoginParam.getUsername(), systemLoginParam.getPassword());
if (token == null) {
return CommonResult.validateFailed("用户名或密码错误");
}
Map<String, String> tokenMap = new HashMap<>();
tokenMap.put("token", token);
tokenMap.put("tokenHead", tokenHead);
return CommonResult.success(tokenMap);
}
}
1.4 service
package cn.itbeien.security.jwt.service.impl;
import cn.itbeien.security.jwt.entity.SysResource;
import cn.itbeien.security.jwt.entity.SysUser;
import cn.itbeien.security.jwt.mapper.SysUserMapper;
import cn.itbeien.security.jwt.service.SystemService;
import cn.itbeien.security.jwt.util.Asserts;
import cn.itbeien.security.jwt.util.JwtTokenUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @author itbeien
* 项目网站:https://www.itbeien.cn
* 公众号:贝恩聊架构
* 全网同名,欢迎小伙伴们关注
* Copyright© 2024 itbeien
*/
@Slf4j
@Service
public class SystemServiceImpl implements SystemService {
@Resource
private SysUserMapper sysUserMapper;
@Autowired
private PasswordEncoder passwordEncoder;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Override
public String login(String username, String password) {
String token = "";
//密码需要客户端加密后传递
try {
UserDetails userDetails = loadUserByUsername(username);
if(!passwordEncoder.matches(password,userDetails.getPassword())){
Asserts.fail("密码不正确");
}
if(!userDetails.isEnabled()){
Asserts.fail("帐号已被禁用");
}
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
SecurityContextHolder.getContext().setAuthentication(authentication);
token = jwtTokenUtil.generateToken(userDetails);
} catch (AuthenticationException e) {
log.error("登录异常:{}", e.getMessage());
}
return token;
}
@Override
public UserDetails loadUserByUsername(String username){
//获取用户信息
SysUser sysUser = getSysUserByUsername(username);
if (sysUser != null) {
List<SysResource> resourceList = new ArrayList<>();
return new SysUserDetails(sysUser,resourceList);
}
throw new UsernameNotFoundException("用户名或密码错误");
}
@Override
public SysUser getSysUserByUsername(String username) {
//先从缓存中获取数据
//TODO
//缓存中没有从数据库中获取
QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_name", username);
SysUser sysUser = sysUserMapper.selectOne(queryWrapper);
if (sysUser != null) {
//将数据库中的数据存入缓存中
//TODO
return sysUser;
}
return null;
}
// @Bean
// public PasswordEncoder passwordEncoder() {
// return new BCryptPasswordEncoder();
// }
}
1.5 Spring Security Config 配置类
package cn.itbeien.security.jwt.config;
import cn.itbeien.security.jwt.component.JwtAuthenticationTokenFilter;
import cn.itbeien.security.jwt.component.RestAuthenticationEntryPoint;
import cn.itbeien.security.jwt.component.RestfulAccessDeniedHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
/**
* @author itbeien
* 项目网站:https://www.itbeien.cn
* 公众号:贝恩聊架构
* 全网同名,欢迎小伙伴们关注
* Copyright© 2025 itbeien
*/
@Configuration
public class SecurityConfig {
@Autowired
private IgnoreUrlsConfig ignoreUrlsConfig;
@Autowired
private RestfulAccessDeniedHandler restfulAccessDeniedHandler;
@Autowired
private RestAuthenticationEntryPoint restAuthenticationEntryPoint;
@Autowired
private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
@Bean
SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeHttpRequests(registry -> {
//不需要保护的资源路径允许访问
for (String url : ignoreUrlsConfig.getUrls()) {
registry.requestMatchers(url).permitAll();
}
//允许跨域请求的OPTIONS请求
registry.requestMatchers(HttpMethod.OPTIONS).permitAll();
//任何请求需要身份认证
})
//关闭跨站请求防护
.csrf(AbstractHttpConfigurer::disable)
//修改Session生成策略为无状态会话
.sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
//自定义权限拒绝处理类
.exceptionHandling(configurer -> configurer.accessDeniedHandler(restfulAccessDeniedHandler).authenticationEntryPoint(restAuthenticationEntryPoint))
//自定义权限拦截器JWT过滤器
.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
return httpSecurity.build();
}
}
2 代码测试
2.1 启动项目

2.2 前后端测试
输入以下网址,对系统登录功能进行测试,如果返回如下图中的token则代表登录成功

以上就是我们今天SpringBoot3.4.1和Spring Security6.4.2结合JWT实现用户登录的全部内容,完整代码在文章最后进行获取!
欢迎大家关注我的项目实战内容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 安全认证框架实现简单身份认证
12SpringBoot3.4.1和Spring Security6.4.2实现基于内存和MySQL的用户认证
13SpringBoot3.4.1和Spring Security6.4.2结合OAuth2实现GitHub授权登录
跟着我学微服务系列
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点左右通过!营销号免入

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