第51天-JavaEE身份验证实战:JWT与SpringSecurity完全学习笔记

admin 2026-03-03 06:08:19 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文是JavaEE身份验证实战笔记,深入解析JWT与SpringSecurity技术。文中详述JWT结构、代码实现及密钥泄露等安全风险,剖析SpringSecurity核心概念、整合流程及权限绕过漏洞。通过代码示例与对比表格提供完整指导,建议开发者注重密钥保护与正确配置,适合初学者查阅。 综合评分: 80 文章分类: 应用安全,安全开发,WEB安全


cover_image

第51天-JavaEE身份验证实战:JWT与Spring Security完全学习笔记

原创

萧瑶 萧瑶

AlphaNet

2026年2月25日 11:40 江苏

在Web开发中,身份验证是保障系统安全的第一道防线。无论是传统的Session-Cookie,还是现代的Token机制,选择合适的技术方案至关重要。本文基于SpringBoot环境,深入讲解JWT和Spring Security两大主流身份验证技术,涵盖基础概念、快速入门、代码示例及常见安全问题,适合初学者及开发者查阅。


一、身份验证常见技术概览

身份验证技术发展至今,已有多种成熟方案:

· JWT (JSON Web Token):基于Token的无状态认证,适合分布式系统。

· Shiro:轻量级Java安全框架,提供认证、授权、加密等功能。

· Spring Security:Spring家族的安全框架,功能强大,与SpringBoot无缝集成。

· OAuth 2.0:开放授权协议,常用于第三方登录(如微信、GitHub)。

· SSO (单点登录):一次登录,多系统访问。

· JAAS (Java Authentication and Authorization Service):Java原生认证服务。

本文重点探讨JWT与Spring Security,它们在Java生态中应用最广泛。


二、JWT技术详解

  1. 什么是JWT?

JWT(JSON Web Token)是一种紧凑的、URL安全的令牌,由服务端通过加密算法对信息签名,保证数据的完整性和不可伪造性。JWT自身包含所有必要信息(如用户ID、角色),因此服务端无需存储会话数据,非常适合分布式、无状态的应用场景。

  1. JWT的结构

JWT由三部分组成,用点(.)连接:

· Header(头部):声明类型和加密算法(如HMAC SHA256)。

· Payload(载荷):存放实际数据(如用户ID、过期时间),注意:Payload仅Base64编码,切勿存放敏感信息。

· Signature(签名):使用密钥对Header和Payload进行签名,防止篡改。

  1. JWT快速入门(Java实现)

以下使用com.auth0:java-jwt库演示JWT的创建与解析。

3.1 引入依赖

<dependency>

<groupId>com.auth0</groupId>

<artifactId>java-jwt</artifactId>

<version>3.4.0</version>

</dependency>

3.2 创建JWT

import com.auth0.jwt.JWT;

import com.auth0.jwt.algorithms.Algorithm;

import java.util.HashMap;

import java.util.Map;

public class JwtDemo {

public static String createToken() {

// 设置Header

Map<String, Object> header = new HashMap<>();

header.put("alg", "HS256");

header.put("typ", "JWT");

// 生成Token

String token = JWT.create()

.withHeader(header)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// Header

.withClaim("userid", 1001)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Payload

.withClaim("username", "xiaodi")

.withClaim("password", "encryptedPass") // 注意:切勿存明文密码

.sign(Algorithm.HMAC256("xiaodisec"));&nbsp; // 签名密钥

return token;

}

}

3.3 解析JWT

import com.auth0.jwt.JWT;

import com.auth0.jwt.JWTVerifier;

import com.auth0.jwt.algorithms.Algorithm;

import com.auth0.jwt.interfaces.DecodedJWT;

public class JwtDemo {

public static void verifyToken(String token) {

// 使用相同密钥构建解析器

JWTVerifier verifier = JWT.require(Algorithm.HMAC256("xiaodisec")).build();

DecodedJWT decodedJWT = verifier.verify(token); // 验证签名并解析

// 提取数据

Integer userId = decodedJWT.getClaim("userid").asInt();

String username = decodedJWT.getClaim("username").asString();

System.out.println("userid: " + userId + ", username: " + username);

}

}

3.4 登录校验流程

  1. 用户登录成功 → 服务端生成JWT(含用户标识)返回给客户端。

  2. 客户端后续请求携带JWT(通常放在Authorization头)。

  3. 服务端解析并验证JWT签名,若通过则获取用户信息,完成身份认证。

关键点:在未知签名密钥的情况下,攻击者无法伪造合法Token,也无法篡改Token内容。

  1. JWT的安全问题

· 密钥泄露:若签名密钥被窃取,攻击者可任意伪造Token。

· Payload敏感信息泄露:Payload仅Base64编码,并非加密,切勿存放密码等敏感数据。

· 无状态吊销困难:JWT一旦签发,在有效期内无法撤销(除非服务端维护黑名单,但违背无状态初衷)。

· 算法混淆攻击:若服务端未正确验证算法,攻击者可能将RS256改为HS256,利用公钥作为密钥签名。

更多JWT安全细节可参考:JWT安全指南


三、Spring Security深度解析

Spring Security是Spring Boot底层安全模块的默认选型,提供认证(Authentication)和授权(Authorization)两大核心功能。它基于过滤器链实现,支持多种认证方式(如表单登录、OAuth2、LDAP),并通过注解简化权限控制。

  1. 核心概念

· 认证:验证用户身份(你是谁?),如用户名密码校验。

· 授权:控制用户访问权限(你能做什么?),如角色判断。

· SecurityContextHolder:存储当前已认证用户信息。

· UserDetailsService:加载用户特定数据的接口。

· 密码编码器:如BCryptPasswordEncoder,安全加密密码。

  1. Spring Security整合SpringBoot实战

2.1 创建项目并引入依赖

使用Spring Initializr创建项目,添加依赖:

· Spring Web

· Spring Security

· Thymeleaf(可选,用于前端页面)

2.2 配置Thymeleaf(application.properties)

spring.thymeleaf.cache=false

spring.thymeleaf.prefix=classpath:/templates/

spring.thymeleaf.suffix=.html

2.3 添加前端页面

在src/main/resources/templates下创建页面:

· index.html(首页)

· views/login.html(登录页)

· views/level1/1.html、views/level2/1.html等(不同权限的页面)

2.4 创建路由控制器

@Controller

public class RouterController {

@RequestMapping("/index")

public String index() {

return "index";

}

@RequestMapping("/toLogin")

public String toLogin() {

return "views/login";

}

@RequestMapping("/level1/{id}")

public String level1(@PathVariable("id") int id) {

return "views/level1/" + id;

}

@RequestMapping("/level2/{id}")

public String level2(@PathVariable("id") int id) {

return "views/level2/" + id;

}

@RequestMapping("/level3/{id}")

public String level3(@PathVariable("id") int id) {

return "views/level3/" + id;

}

}

2.5 配置Spring Security(授权与认证)

创建配置类SecurityConfig,继承WebSecurityConfigurerAdapter。

@EnableWebSecurity

public class SecurityConfig extends WebSecurityConfigurerAdapter {

// 授权配置

@Override

protected void configure(HttpSecurity http) throws Exception {

http.authorizeRequests()

.antMatchers("/").permitAll()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 首页允许所有人

.antMatchers("/level1/\*\*").hasRole("vip1") // level1需要vip1角色

.antMatchers("/level2/\*\*").hasRole("vip2")

.antMatchers("/level3/\*\*").hasRole("vip3")

.and()

.formLogin()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // 开启表单登录

.loginPage("/toLogin")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 自定义登录页

.usernameParameter("username")&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 默认参数名

.passwordParameter("password")

.loginProcessingUrl("/login");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// 登录表单提交地址

}

// 认证配置(内存用户)

@Override

protected void configure(AuthenticationManagerBuilder auth) throws Exception {

// 使用BCrypt密码加密

auth.inMemoryAuthentication()

.passwordEncoder(new BCryptPasswordEncoder())

.withUser("admin")

.password(new BCryptPasswordEncoder().encode("123456"))

.roles("vip1", "vip2", "vip3")

.and()

.withUser("xiaodi")

.password(new BCryptPasswordEncoder().encode("123456"))

.roles("vip1")

.and()

.withUser("gay")

.password(new BCryptPasswordEncoder().encode("123456"))

.roles("vip3");

}

}

说明:

· hasRole(“vip1”)要求用户具备ROLE_vip1角色(Spring Security会自动添加ROLE_前缀)。

· 密码必须加密,示例中使用BCryptPasswordEncoder。

· 自定义登录页需在Controller中映射/toLogin。

  1. Spring Security的安全问题

3.1 常见代码漏洞

· 明文密码:必须加密存储,禁止直接比较明文。

· CSRF防护:Spring Security默认开启CSRF,若禁用需谨慎评估。

· 权限配置错误:如使用permitAll()开放敏感接口。

3.2 版本漏洞与配置绕过

· 历史漏洞:Spring Security曾爆出权限绕过漏洞,如antMatchers配置不当可能被绕过。

· 配置示例(漏洞演示):

http.authorizeRequests()

.antMatchers("/admin/\*\*").hasRole("ADMIN")

.antMatchers("/admin/login").permitAll() // 注意顺序!此处若放在后面会被忽略

由于规则按顺序匹配,若/admin/login规则放在/admin/**之后,则永远不会生效,导致登录页无法访问。

· 利用双斜杠绕过:某些版本中,URL包含双斜杠(如//admin/)可能绕过antMatchers匹配,造成未授权访问。

参考安全文章:

· Spring Security权限绕过案例分析

· 深入Spring Security漏洞与修复


四、总结与对比

维度 JWT Spring Security

状态管理 无状态,服务端不存储会话 默认基于Session,可配置为无状态(如JWT)

适用场景 分布式系统、微服务、移动端API 单体应用、与Spring生态紧密集成的项目

安全性 依赖签名密钥保护,注意Payload加密 提供完整的安全机制,但需正确配置

学习曲线 简单,轻量级 较陡峭,但功能全面

无论选择哪种技术,安全配置始终是核心。开发者需时刻关注:

· 密钥/密码的存储与保护

· 正确的权限匹配顺序

· 及时更新依赖版本,修复已知漏洞


五、参考资源

· Spring Boot 官方文档

· Spring Security 官网

· JWT 官方介绍

· JWT 安全建议

· Spring Security 漏洞分析


最后:身份验证是Web安全的基石,希望本文能帮助你快速掌握JWT与Spring Security的核心用法。在实际开发中,务必结合业务场景选择合适方案,并遵循安全最佳实践。如有疑问,欢迎留言讨论!

本文由读者投稿整理,内容基于实际开发经验,转载请注明出处。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:AlphaNet 萧瑶 萧瑶《第51天-JavaEE身份验证实战:JWT与Spring Security完全学习笔记》

河北网盾全国招聘英才 网络安全文章

河北网盾全国招聘英才

文章总结: 该文档主要包含河北网盾网络科技有限公司的全国招聘启事及网络安全攻防实验室社群的推广信息。招聘方面面向全国诚聘大客户经理,不限学历与地域,覆盖多个省市
实战漏洞挖掘 网络安全文章

实战漏洞挖掘

文章总结: 文档记录了一次针对统一身份认证系统的渗透测试实战。作者利用灯塔资产收集目标,因系统缺乏验证码实施密码喷洒成功登录。随后发现越权漏洞可遍历获取大量敏感
评论:0   参与:  0