
1. JWT 的基本概念
JWT 是一种用于在网络应用环境中安全地传递信息的紧凑的 URL 安全的令牌。它可以被验证和信任,因为它是数字签名的。JWT 通常用于身份验证和信息交换。
这里详细说一下原理,一般有两种形式
- 对称加密:简单速度快,但是风险较高
- 非对称加密:原理复杂,速度慢,但是安全度高
这里说说非对称加密的方式,其实和https类似是一个“藏钥匙”的机制,私钥(sk)保留在服务器中不参与外部服务和模块的迁移,保证安全性,sk加密的签名A和头部、载荷一起发送到客户端,当客户端伪造了权限(一般是载荷中的信息),服务器拿到jwt后根据载荷和头部依据相同算法计算出一个hash(hp),然后用公钥解码签名拿到另一个hash(sp)如果sp和hp一致那么就是没有篡改,因为篡改了载荷的话hash值也就是摘要会变化原理就是这么简单。
2. 依赖项
在 pom.xml 文件中,项目使用了以下依赖项来处理 JWT:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.5</version>
</dependency>
3. JWT 生成
在 JwtUtil 类中,JWT 的生成通过以下方法实现:generateToken 方法: 接收用户名并创建一个包含用户信息的 JWT。createToken 方法: 使用 Jwts.builder() 构建 JWT,设置声明、主题、签发时间和过期时间,并使用安全密钥进行签名。
public String generateToken(String username) {
Map<String, Object> claims = new HashMap<>();
return createToken(claims, username);
}
private 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() + validityInMilliseconds))
.signWith(secretKey) // 使用生成的安全密钥
.compact();
}
4. JWT 验证
在 ProtectedController 类中,JWT 的验证通过以下步骤实现:提取用户名: 使用 jwtUtil.extractUsername(token) 从 JWT 中提取用户名。验证令牌: 使用 jwtUtil.validateToken(token, username) 验证 JWT 的有效性。
@GetMapping("/protected")
public String protectedEndpoint(@RequestHeader("Authorization") String token) {
String username = jwtUtil.extractUsername(token);
if (jwtUtil.validateToken(token, username)) {
return "This is a protected endpoint. Hello, " + username + "!";
} else {
throw new RuntimeException("Invalid token");
}
}
5. 安全配置
在 SecurityConfig 类中,配置了 Spring Security,以允许某些端点(如 /authenticate 和 /hello)不需要身份验证,而其他请求则需要身份验证。
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.requestMatchers("/authenticate").permitAll()
.requestMatchers("/hello").permitAll()
.anyRequest().authenticated();
return http.build();
}
6. 用户认证
在 AuthController 类中,处理用户认证请求。使用硬编码的用户名和密码进行验证,并在成功时生成 JWT。
@PostMapping("/authenticate")
public Map<String, String> authenticate(@RequestBody AuthRequest authRequest) {
if ("user".equals(authRequest.getUsername()) && "password".equals(authRequest.getPassword())) {
String token = jwtUtil.generateToken(authRequest.getUsername());
return Collections.singletonMap("token", token);
} else {
throw new RuntimeException("Invalid credentials");
}
}
7. 密钥管理
在 JwtUtil 类中,使用 Keys.secretKeyFor(SignatureAlgorithm.HS256) 方法生成一个安全的密钥,以确保密钥的大小符合 HS256 的要求(至少 256 位)。
总结
JWT 是一种安全的身份验证机制,适用于现代 Web 应用程序。通过使用 jjwt 库,项目能够有效地生成和验证 JWT,确保用户的身份安全。通过适当的安全配置,应用程序能够控制对受保护资源的访问。如果你有任何其他问题或需要进一步的细节,请告诉我!