Spring Boot 集成 JWT 详细指南(springboot集成junit)
liuian 2025-07-24 19:48 65 浏览
Spring Boot 集成 JWT 详细指南
在当今的 Web 应用开发中,安全认证是至关重要的一环。JSON Web Token(JWT)作为一种轻量级的认证和授权机制,因其跨域支持、自包含性以及易于使用等优点,被广泛应用于各种前后端分离的项目中。Spring Boot 作为一款快速开发框架,与 JWT 的集成可以帮助开发者快速搭建安全可靠的认证体系。本文将详细介绍如何在 Spring Boot 项目中集成 JWT。
一、JWT 简介
JWT 是一种基于 JSON 的开放标准(RFC 7519),用于在各方之间安全地传输声明。它通常由三部分组成:头部(Header)、负载(Payload)和签名(Signature)。
- 头部(Header):包含令牌的类型(通常是 JWT)和使用的签名算法(如 HMAC SHA256 或 RSA)。
- 负载(Payload):包含声明(Claims),声明是关于实体(通常是用户)和其他数据的声明。声明分为三种类型:注册声明、公开声明和私有声明。
- 签名(Signature):为了创建签名部分,需要使用编码后的头部、编码后的负载、一个密钥(secret)和头部中指定的签名算法来进行签名。
二、创建 Spring Boot 项目
首先,我们需要创建一个新的 Spring Boot 项目。可以使用 Spring Initializr来快速生成项目骨架。在创建项目时,选择以下依赖:
- Spring Web
- Spring Security
创建好项目后,导入到 IDE 中。
三、添加 JWT 依赖
在 pom.xml 文件中添加 JWT 相关的依赖:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
四、配置 JWT 工具类
创建一个 JWT 工具类,用于生成和验证 JWT 令牌。以下是一个简单的示例:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
public class JwtUtil {
private static final String SECRET_KEY = "yourSecretKey";
private static final long EXPIRATION_TIME = 1000 * 60 * 60 * 10; // 10 hours
public static String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
return createToken(claims, userDetails.getUsername());
}
private static String createToken(Map<String, Object> claims, String subject) {
return Jwts.builder()
.setClaims(claims)
.setSubject(subject)
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY)
.compact();
}
public static String extractUsername(String token) {
return extractClaims(token).getSubject();
}
public static Date extractExpiration(String token) {
return extractClaims(token).getExpiration();
}
private static Claims extractClaims(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
}
private static Boolean isTokenExpired(String token) {
return extractExpiration(token).before(new Date());
}
public static Boolean validateToken(String token, UserDetails userDetails) {
final String username = extractUsername(token);
return (username.equals(userDetails.getUsername()) &&!isTokenExpired(token));
}
}
五、配置 Spring Security
配置 Spring Security 以使用 JWT 进行认证和授权。创建一个配置类,继承
WebSecurityConfigurerAdapter:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/authenticate").permitAll()
.anyRequest().authenticated()
.and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(new JwtRequestFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
六、创建 JWT 请求过滤器
创建一个 JWT 请求过滤器,用于拦截请求并验证 JWT 令牌:
import io.jsonwebtoken.ExpiredJwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String requestTokenHeader = request.getHeader("Authorization");
String username = null;
String jwtToken = null;
// JWT Token is in the form "Bearer token". Remove Bearer word and get
// only the Token
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
jwtToken = requestTokenHeader.substring(7);
try {
username = JwtUtil.extractUsername(jwtToken);
} catch (IllegalArgumentException e) {
System.out.println("Unable to get JWT Token");
} catch (ExpiredJwtException e) {
System.out.println("JWT Token has expired");
}
} else {
logger.warn("JWT Token does not begin with Bearer String");
}
// Once we get the token validate it.
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
// if token is valid configure Spring Security to manually set
// authentication
if (JwtUtil.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
// After setting the Authentication in the context, we specify
// that the current user is authenticated. So it passes the
// Spring Security Configurations successfully.
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
七、创建认证控制器
创建一个认证控制器,用于处理用户登录请求并生成 JWT 令牌:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AuthenticationController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private UserDetailsService userDetailsService;
@RequestMapping(value = "/authenticate", method = RequestMethod.POST)
public ResponseEntity<?> createAuthenticationToken(@RequestBody AuthenticationRequest authenticationRequest) throws Exception {
try {
authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(authenticationRequest.getUsername(), authenticationRequest.getPassword())
);
}
catch (BadCredentialsException e) {
throw new Exception("Incorrect username or password", e);
}
final UserDetails userDetails = userDetailsService
.loadUserByUsername(authenticationRequest.getUsername());
final String jwt = JwtUtil.generateToken(userDetails);
return ResponseEntity.ok(new AuthenticationResponse(jwt));
}
}
class AuthenticationRequest {
private String username;
private String password;
// Getters and setters
}
class AuthenticationResponse {
private String jwt;
public AuthenticationResponse(String jwt) {
this.jwt = jwt;
}
// Getters and setters
}
八、测试集成
启动 Spring Boot 项目,使用 Postman 等工具进行测试。发送 POST 请求到 /authenticate 端点,提供用户名和密码,获取 JWT 令牌。然后在后续的请求中,在请求头中添加 Authorization: Bearer <token> 来进行认证。
九、总结
通过以上步骤,我们成功地在 Spring Boot 项目中集成了 JWT。JWT 为我们提供了一种安全、便捷的认证和授权方式,结合 Spring Security 的强大功能,可以有效地保护我们的 Web 应用。在实际项目中,还可以根据需求对 JWT 的配置和使用进行进一步的优化和扩展。
相关推荐
- 手机处理器排名最新图(手机处理器排行榜全部)
-
众所周知,手机端SOC很少在插电模式下运行,因此能耗比在移动端CPU性能中特别重要。本文整理了主流的SOC能耗比情况,给大家购买手机做一个参考。SOC能耗比较高的,包括麒麟810,骁龙625,麒麟65...
- pdf版本怎么弄(怎么把word转为pdf)
-
回答如下:要将PDF文件恢复到以前的版本,您需要执行以下步骤:1.找到保存PDF文件的文件夹或位置。2.在该位置中找到以前的版本,这可能是备份文件、自动保存文件或之前保存的版本。3.如果您没有备...
- 万能bt搜索引擎网站(bt万能搜索破解版)
-
最好用最全面的的磁力搜索引擎是磁力熊,因为它是一个内容丰富、还是功能最为强大的一个磁力搜索网站,通过它不仅仅可以搜索磁力熊磁力熊,是一个内容丰富、功能最为强大的一个磁力搜索网站,通过它不仅仅可以搜索...
- 苹果id注册官网登录(appleid官网注册账号)
-
浏览器访问申请AppleID官网注册 1、在浏览器地址栏上面输入:“https://appleid.apple.com/cn”,进入申请AppleID官网界面,点击下面的“创建AppleID...
- 苹果笔记本怎么下载windows系统
-
方法一:使用BootCamp方法二:使用虚拟机方法三:使用Wine简介BootCamp是苹果电脑自带的一个软件,可以帮助用户在Mac上安装Windows操作系统。虚拟机则是运行在Mac上的一个软件...
- 华硕电脑激活码(华硕电脑windows激活码在哪里)
-
你所说的应该是系统激活密钥吧华硕OEM密钥就行!HomePremium(家庭高级版):27GBM-Y4QQC-JKHXW-D9W83-FJQKDUltimate(旗舰版):6K2KY-BF...
- wifi如何防止别人蹭网(wifi如何防止别人蹭网呢)
-
防止WIFI被蹭网的方法1、家庭的wifi信号,一般是通过设置无线路由器发射出来。在设置无线路由器时,一定要注意设置无线密码的安全强度。最好含有大小写字母加数字的组合,不要设置连续数字,比如“1234...
- 无线ap安装示意图(无线ap如何安装方法)
-
商用无线ap安装完成后连接ap应用添加wifi网络信号将无线网卡插入电脑USBWindows7/8系统下,网卡安装成功后直接进行软件安装...2.继续安装类型,推荐保持默认选择,点击“下一步”继续安装...
- miui官网开发版下载(小米miui开发版下载)
-
你好,miui12开发版下载方式如下1打开浏览器,登录小米Rom官网,2进去之后搜索自己的手机型号,3点击进入就可以看到所有发布过的miui版本4点击想要的12版本下载即可。现在的MIUI开发版需要申...
-
- 惠普台式机进入bios设置u盘启动
-
设置u盘启动的步骤如下:1、首先,将u盘插入hp台式机的USB接口处。2、开机快速断续的按F10键进入BIOS设置界面。3、将光标移到【BootDevicePriority】选项按回车键进入。4、选择【HDDGroupBootPr...
-
2026-01-15 00:37 liuian
- 云手机免费版无限挂机怎么用
-
1、登陆后,如果需要挂网页游戏,点击服务器的左下角,找到IE浏览器,然后打开网页游戏,登陆你的账号就行了,不要关闭IE浏览器,你的网页游戏就会24小时挂在云服务器上面。2、如果想要挂机,打开IE浏览器...
- 上海最近3天疫情情况(上海近几天的新冠疫情情况)
-
根据国家卫健委的每天疫情通报及上海市的疫情通报,上海没有一个区属中高风险地区,所以从上海任何一个区返乡都不需要隔离14天。上海这么大的城市,每天人来人往的Ill流不息,能继续做到区级地区没有中高级风险...
- windows media player怎么下载
-
方法如下:在安装WMP11时只是把C:\DocumentsandSettings\AllUsers\ApplicationData\WindowsGenuineAdvantage\data...
- 一周热门
-
-
飞牛OS入门安装遇到问题,如何解决?
-
如何在 iPhone 和 Android 上恢复已删除的抖音消息
-
Boost高性能并发无锁队列指南:boost::lockfree::queue
-
大模型手册: 保姆级用CherryStudio知识库
-
用什么工具在Win中查看8G大的log文件?
-
如何在 Windows 10 或 11 上通过命令行安装 Node.js 和 NPM
-
威联通NAS安装阿里云盘WebDAV服务并添加到Infuse
-
Trae IDE 如何与 GitHub 无缝对接?
-
idea插件之maven search(工欲善其事,必先利其器)
-
如何修改图片拍摄日期?快速修改图片拍摄日期的6种方法
-
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)
- mysql刷新权限 (34)
