springboot整合springsecurity和jwt
时间: 2023-08-23 08:08:09 浏览: 215
详解SpringBoot+SpringSecurity+jwt整合及初体验
好的,这是一个比较常见的需求,下面是大致的步骤:
1. 在pom.xml中引入spring-security和jwt相关依赖
```xml
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring-security.version}</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
```
其中 `${spring-security.version}` 和 `${jjwt.version}` 分别为 Spring Security 和 JWT 的版本号。
2. 配置 Spring Security
在 Spring Boot 中,使用 Java Config 来配置 Spring Security。具体的配置可以参考如下代码:
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
@Bean
public JwtAuthenticationFilter jwtAuthenticationFilter() {
return new JwtAuthenticationFilter();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.exceptionHandling()
.authenticationEntryPoint(jwtAuthenticationEntryPoint)
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
```
上面的代码中,我们配置了:
- `userDetailsService`:用于从数据库中读取用户信息。
- `JwtAuthenticationEntryPoint`:用于处理认证失败的情况。
- `JwtAuthenticationFilter`:用于处理 JWT 认证。
在 `configure(HttpSecurity http)` 中,我们配置了哪些请求需要认证,哪些请求不需要认证,以及异常处理和 session 管理等。
3. 配置 JWT
在 JWT 中,我们需要定义一个 secret key 用于签名和验证 JWT。可以在 application.properties 中配置:
```properties
jwt.secret=mySecretKey
jwt.expirationMs=86400000
```
其中,`jwt.secret` 是用于签名和验证 JWT 的 secret key,`jwt.expirationMs` 是 JWT 的过期时间(单位为毫秒)。
然后,我们可以定义一个 `JwtUtils` 类来生成和解析 JWT:
```java
@Component
public class JwtUtils {
@Value("${jwt.secret}")
private String jwtSecret;
@Value("${jwt.expirationMs}")
private int jwtExpirationMs;
public String generateJwtToken(Authentication authentication) {
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
return Jwts.builder()
.setSubject(userPrincipal.getUsername())
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + jwtExpirationMs))
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
public String getUsernameFromJwtToken(String token) {
return Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(token).getBody().getSubject();
}
public boolean validateJwtToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException e) {
logger.error("Invalid JWT signature: {}", e.getMessage());
} catch (MalformedJwtException e) {
logger.error("Invalid JWT token: {}", e.getMessage());
} catch (ExpiredJwtException e) {
logger.error("JWT token is expired: {}", e.getMessage());
} catch (UnsupportedJwtException e) {
logger.error("JWT token is unsupported: {}", e.getMessage());
} catch (IllegalArgumentException e) {
logger.error("JWT claims string is empty: {}", e.getMessage());
}
return false;
}
}
```
上面的代码中,我们使用了 `Jwts.builder()` 和 `Jwts.parser()` 来生成和解析 JWT。
4. 配置认证接口
最后,我们可以在认证接口中生成 JWT 并返回给客户端:
```java
@RestController
@RequestMapping("/api/auth")
public class AuthController {
@Autowired
private AuthenticationManager authenticationManager;
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserDetailsService userDetailsService;
@PostMapping("/signin")
public ResponseEntity<?> authenticateUser(@RequestBody LoginRequest loginRequest) {
Authentication authentication = authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
String jwt = jwtUtils.generateJwtToken(authentication);
UserDetails userDetails = userDetailsService.loadUserByUsername(loginRequest.getUsername());
return ResponseEntity.ok(new JwtResponse(jwt, userDetails.getUsername(), userDetails.getAuthorities()));
}
}
```
上面的代码中,我们使用了 `AuthenticationManager` 来进行认证,然后使用 `JwtUtils` 生成 JWT 并返回给客户端。
以上就是整合 Spring Security 和 JWT 的大致步骤,具体实现过程还需根据实际情况进行调整。
阅读全文