我将为您详细讲解如何实现基于JWT的Spring Boot权限验证技术。
1. JWT 的概念
JWT(JSON Web Token)是一种使用 JSON 格式编写的 token(令牌)标准,并且可被用于浏览器和移动端之间的身份认证。
JWT 由三部分组成:头部(header)、载荷(payload)和签名(signature)。
- 头部(header):包含了 token 的类型(即 JWT)、使用的算法等信息。
- 载荷(payload):用于存放实际请求时所携带的数据。其中包含了用户的信息、有效期等信息。
- 签名(signature):使用密钥对头部和载荷进行签名生成的字符串,以保证 token 的安全性。
2. Spring Boot 中 JWT 的使用
在 Spring Boot 中,我们可以使用一些第三方库来实现 JWT 的使用,如 jjwt 等。
2.1. 添加 jjwt 依赖
首先,在我们的项目中添加 jjwt 依赖:
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.11.2</version>
<scope>runtime</scope>
</dependency>
2.2. 配置 SecretKey
接下来,我们需要生成一个 SecretKey,用于对 JWT 进行签名,可以将 SecretKey 的生成放在一个配置类中:
import io.jsonwebtoken.security.Keys;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.crypto.SecretKey;
@Configuration
public class JwtConfig {
private final String secret = "mySecretKeyForJwt";
@Bean
public SecretKey secretKey() {
return Keys.hmacShaKeyFor(secret.getBytes());
}
}
2.3. 生成 Token
接下来,我们可以使用 jjwt 库生成一个 JWT token,示例代码如下:
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import javax.crypto.SecretKey;
import java.util.Date;
public class JWTTokenProvider {
// 过期时间为 10 分钟
private static final long EXPIRATION_TIME = 10 * 60 * 1000;
private final SecretKey secretKey;
public JWTTokenProvider(SecretKey secretKey) {
this.secretKey = secretKey;
}
public String generateToken(User user) {
Date now = new Date();
Date expiryDate = new Date(now.getTime() + EXPIRATION_TIME);
return Jwts.builder()
.setSubject(Long.toString(user.getId()))
.setIssuedAt(now)
.setExpiration(expiryDate)
.signWith(secretKey)
.compact();
}
}
其中,setSubject() 方法可以设置用户名等信息,setIssuedAt() 方法表示创建时间,setExpiration() 方法表示过期时间。最后使用 signWith() 方法对 token 进行签名。
2.4. 验证 Token
在实际的应用场景中,我们需要验证用户提交的 token 是否有效,代码示例如下:
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import javax.crypto.SecretKey;
import java.util.Optional;
public class JWTTokenValidator {
private final SecretKey secretKey;
public JWTTokenValidator(SecretKey secretKey) {
this.secretKey = secretKey;
}
public Optional<Long> getUserIdFromJWT(String token) {
try {
Jws<Claims> claims = Jwts.parser()
.setSigningKey(secretKey)
.parseClaimsJws(token);
Claims body = claims.getBody();
Long userId = Long.parseLong(body.getSubject());
return Optional.of(userId);
} catch (Exception ex) {
return Optional.empty();
}
}
}
其中,Jwts.parser() 方法返回一个 JwtParser 对象,使用 setSigningKey() 方法设置密钥,使用 parseClaimsJws() 方法解析 token。如果解析成功,将返回一个 Claims 对象,可以从中获取用户的信息。
3. 示例说明
接下来,我将介绍两个示例:
3.1. 实现用户登录
用户登录成功后,我们可以使用上述方法生成一个 token,并返回给客户端。
@PostMapping("/login")
public ResponseEntity<?> authenticateUser(@Valid @RequestBody LoginRequest loginRequest) {
// Authenticate User
UserDetails userDetails = myUserDetailsService.loadUserByUsername(loginRequest.getUsername());
String jwt = jwtTokenProvider.generateToken(userDetails);
return ResponseEntity.ok(new JwtAuthenticationResponse(jwt));
}
在该示例中,我们将用户提交的用户名和密码进行验证,并使用 loadUserByUsername() 方法获取用户的详细信息。然后,将用户信息传入生成 token 的方法中,即可得到一个 token 并返回给客户端。
3.2. 验证用户访问权限
在某些场景下,我们需要验证用户是否有访问某一页面或资源的权限。示例代码如下:
@GetMapping("/private")
public ResponseEntity<?> getPrivateData(@CurrentUser UserPrincipal userPrincipal) {
if(userPrincipal.getAuthorities().contains(new SimpleGrantedAuthority("ROLE_ADMIN"))) {
return ResponseEntity.ok("You have access to this page.");
} else {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
}
其中,@CurrentUser 注解代表当前登录用户,通过 userPrincipal.getAuthorities() 方法可以获取当前用户所拥有的权限,然后对权限进行判断并返回相应的结果。如果用户没有权限,我们可以直接返回一个 HttpStatusCode 为 Forbidden 的响应。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:基于JWT的spring boot权限验证技术实现教程 - Python技术站