Spring Security是一个强大的安全框架,可以支持高度可定制的身份验证和授权功能。而JWT(JSON Web Token)则是一种轻量级的认证和授权技术,可以在分布式系统中传递和验证用户身份信息。本文将介绍如何结合Spring Security和JWT来实现基于token的身份验证和授权。
1. Spring Security和JWT简介
1.1 Spring Security
Spring Security是一个基于Spring框架的安全框架,提供了全面的身份验证和授权功能。Spring Security可以轻松地与Spring框架集成,提供了一套完整的安全解决方案,可以应用于各种应用场景。
1.2 JWT
JSON Web Token(JWT)是一种轻量级的身份验证和授权技术,可以在分布式系统中传递和验证用户身份信息。JWT由三部分组成:头部(Header)、负载(Payload)和签名(Signature)。头部包含了数据的类型(即JWT),使用的算法等信息;负载包含了要传递的用户信息,例如用户ID、用户名等;签名用来验证数据的完整性,防止数据被篡改。
2. Spring Security和JWT结合实现步骤
2.1 引入依赖
在项目的pom文件中添加如下依赖:
<dependencies>
<!-- Spring Boot Web Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot Security Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JWT Starter -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
</dependencies>
2.2 实现Spring Security的配置
在配置类中继承WebSecurityConfigurerAdapter,并覆盖configure方法,如下:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/login").permitAll() // 所有用户均可访问的路径
.anyRequest().authenticated(); // 除上述路径外,所有请求均需身份验证
}
}
2.3 实现JWT的创建和验证
2.3.1 创建JWT
public class JwtUtil {
private static final String SECRET_KEY = "mySecretKey";
private static final long EXPIRATION_TIME = 3600000; // 1 hour
private static final String TOKEN_PREFIX = "Bearer ";
private static final String HEADER_STRING = "Authorization";
public static String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
claims.put("sub", userDetails.getUsername());
claims.put("iat", new Date().getTime());
return Jwts.builder()
.setClaims(claims)
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.signWith(SignatureAlgorithm.HS512, SECRET_KEY)
.compact();
}
}
2.3.2 验证JWT
public class JwtUtil {
...
public static boolean validateToken(String token, UserDetails userDetails) {
String username = extractUsername(token);
return username.equals(userDetails.getUsername()) && !isTokenExpired(token);
}
public static String extractUsername(String token) {
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getSubject();
}
public static boolean isTokenExpired(String token) {
Date expiration = Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody().getExpiration();
return expiration.before(new Date());
}
}
2.4 实现登录接口
@RestController
@RequestMapping("/api")
public class LoginController {
@Autowired
AuthenticationManager authenticationManager;
@GetMapping("/login")
public String login(@RequestParam String username, @RequestParam String password) {
try {
authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(username, password));
UserDetails userDetails = new User(username, password, new ArrayList<>());
String jwt = JwtUtil.generateToken(userDetails);
return jwt;
} catch (AuthenticationException e) {
throw new BadCredentialsException("Invalid username/password supplied");
}
}
}
2.5 实现需要身份验证的接口
@RestController
@RequestMapping("/api")
public class UserController {
@GetMapping("/users")
public List<User> getUsers() {
return Arrays.asList(
new User(1L, "Alice"),
new User(2L, "Bob"),
new User(3L, "Charlie")
);
}
@GetMapping("/users/{userId}")
public User getUser(@PathVariable Long userId) {
return new User(userId, "Alice");
}
}
以上代码片段中的User类可以自行实现,不再赘述。
2.6 测试
使用Postman或其他Http客户端,访问登录接口,GET请求http://host/api/login,并设置用户名和密码为请求参数。如果身份验证通过,将返回JWT;否则将返回401 Unauthorized。
接下来,访问需要身份验证的接口,例如GET请求http://host/api/users,将JWT添加到请求头Authorization中,格式为“Bearer token”。如果身份验证通过,将返回用户列表;否则将返回401 Unauthorized。
3. 示例
上述步骤已经讲解了如何结合Spring Security和JWT来实现基于token的身份验证和授权。下面将给出另外两个示例来进一步说明其使用方法。
3.1 示例1
本示例实现了一个简单的Spring Boot应用,使用Spring Security和JWT来完成基于token的身份验证和授权。具体代码实现请查看附带源码。
3.2 示例2
本示例实现了一个基于Spring Security和JWT的RESTful API,提供了用户注册、登录和获取用户信息的功能。具体代码实现请查看附带源码。
4. 总结
本文介绍了如何结合Spring Security和JWT来实现基于token的身份验证和授权。首先介绍了Spring Security和JWT的概念和原理,然后详细讲解了如何实现Spring Security和JWT的结合,包括创建和验证JWT、实现登录接口和需要身份验证的接口等。最后,给出了两个示例,供读者参考。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Security+JWT简述(附源码) - Python技术站