文章总结: 本文是JavaEE身份验证实战笔记,深入解析JWT与SpringSecurity技术。文中详述JWT结构、代码实现及密钥泄露等安全风险,剖析SpringSecurity核心概念、整合流程及权限绕过漏洞。通过代码示例与对比表格提供完整指导,建议开发者注重密钥保护与正确配置,适合初学者查阅。 综合评分: 80 文章分类: 应用安全,安全开发,WEB安全
第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技术详解
- 什么是JWT?
JWT(JSON Web Token)是一种紧凑的、URL安全的令牌,由服务端通过加密算法对信息签名,保证数据的完整性和不可伪造性。JWT自身包含所有必要信息(如用户ID、角色),因此服务端无需存储会话数据,非常适合分布式、无状态的应用场景。
- JWT的结构
JWT由三部分组成,用点(.)连接:
· Header(头部):声明类型和加密算法(如HMAC SHA256)。
· Payload(载荷):存放实际数据(如用户ID、过期时间),注意:Payload仅Base64编码,切勿存放敏感信息。
· Signature(签名):使用密钥对Header和Payload进行签名,防止篡改。
- 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) // Header
.withClaim("userid", 1001) // Payload
.withClaim("username", "xiaodi")
.withClaim("password", "encryptedPass") // 注意:切勿存明文密码
.sign(Algorithm.HMAC256("xiaodisec")); // 签名密钥
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 登录校验流程
-
用户登录成功 → 服务端生成JWT(含用户标识)返回给客户端。
-
客户端后续请求携带JWT(通常放在Authorization头)。
-
服务端解析并验证JWT签名,若通过则获取用户信息,完成身份认证。
关键点:在未知签名密钥的情况下,攻击者无法伪造合法Token,也无法篡改Token内容。
- JWT的安全问题
· 密钥泄露:若签名密钥被窃取,攻击者可任意伪造Token。
· Payload敏感信息泄露:Payload仅Base64编码,并非加密,切勿存放密码等敏感数据。
· 无状态吊销困难:JWT一旦签发,在有效期内无法撤销(除非服务端维护黑名单,但违背无状态初衷)。
· 算法混淆攻击:若服务端未正确验证算法,攻击者可能将RS256改为HS256,利用公钥作为密钥签名。
更多JWT安全细节可参考:JWT安全指南
三、Spring Security深度解析
Spring Security是Spring Boot底层安全模块的默认选型,提供认证(Authentication)和授权(Authorization)两大核心功能。它基于过滤器链实现,支持多种认证方式(如表单登录、OAuth2、LDAP),并通过注解简化权限控制。
- 核心概念
· 认证:验证用户身份(你是谁?),如用户名密码校验。
· 授权:控制用户访问权限(你能做什么?),如角色判断。
· SecurityContextHolder:存储当前已认证用户信息。
· UserDetailsService:加载用户特定数据的接口。
· 密码编码器:如BCryptPasswordEncoder,安全加密密码。
- 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() // 首页允许所有人
.antMatchers("/level1/\*\*").hasRole("vip1") // level1需要vip1角色
.antMatchers("/level2/\*\*").hasRole("vip2")
.antMatchers("/level3/\*\*").hasRole("vip3")
.and()
.formLogin() // 开启表单登录
.loginPage("/toLogin") // 自定义登录页
.usernameParameter("username") // 默认参数名
.passwordParameter("password")
.loginProcessingUrl("/login"); // 登录表单提交地址
}
// 认证配置(内存用户)
@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。
- 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完全学习笔记》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论