springsecurity整合jwt具体怎么做
时间: 2023-07-24 14:33:36 浏览: 162
Spring Security 和 JWT(JSON Web Token)可以一起使用以实现安全认证和授权。下面是整合的一些步骤:
1. 添加依赖
在 pom.xml 文件中添加 Spring Security 和 JWT 的依赖。
```xml
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
```
2. 配置 Spring Security
在 Spring Security 配置文件中添加对 JWT 的支持。
```java
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationEntryPoint unauthorizedHandler;
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and().csrf().disable().
authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated()
.and()
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.apply(new JwtTokenFilterConfigurer(jwtTokenProvider));
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder(12);
}
@Bean
public JwtTokenFilter jwtTokenFilter() {
return new JwtTokenFilter();
}
}
```
3. 创建 JWT 工具类
创建一个 JWT 工具类,用于生成和解析 JWT。
```java
@Service
public class JwtTokenProvider {
@Value("${app.jwtSecret}")
private String jwtSecret;
@Value("${app.jwtExpirationInMs}")
private int jwtExpirationInMs;
public String generateToken(Authentication authentication) {
UserPrincipal userPrincipal = (UserPrincipal) authentication.getPrincipal();
Date now = new Date();
Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);
return Jwts.builder()
.setSubject(Long.toString(userPrincipal.getId()))
.setIssuedAt(new Date())
.setExpiration(expiryDate)
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
public Long getUserIdFromToken(String token) {
Claims claims = Jwts.parser()
.setSigningKey(jwtSecret)
.parseClaimsJws(token)
.getBody();
return Long.parseLong(claims.getSubject());
}
public boolean validateToken(String authToken) {
try {
Jwts.parser().setSigningKey(jwtSecret).parseClaimsJws(authToken);
return true;
} catch (SignatureException ex) {
System.out.println("Invalid JWT signature");
} catch (MalformedJwtException ex) {
System.out.println("Invalid JWT token");
} catch (ExpiredJwtException ex) {
System.out.println("Expired JWT token");
} catch (UnsupportedJwtException ex) {
System.out.println("Unsupported JWT token");
} catch (IllegalArgumentException ex) {
System.out.println("JWT claims string is empty.");
}
return false;
}
}
```
4. 创建 JWT 过滤器
创建一个 JWT 过滤器,用于从 HTTP 请求中提取 JWT,并将它交给 Spring Security 进行认证和授权。
```java
public class JwtTokenFilter extends OncePerRequestFilter {
@Autowired
private JwtTokenProvider jwtTokenProvider;
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
FilterChain filterChain) throws ServletException, IOException {
String jwt = getJwtFromRequest(httpServletRequest);
if (StringUtils.hasText(jwt) && jwtTokenProvider.validateToken(jwt)) {
Long userId = jwtTokenProvider.getUserIdFromToken(jwt);
UserDetails userDetails = userDetailsService.loadUserById(userId);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpServletRequest));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
private String getJwtFromRequest(HttpServletRequest request) {
String bearerToken = request.getHeader("Authorization");
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
return bearerToken.substring(7);
}
return null;
}
}
```
5. 创建 JWT 认证入口
创建一个 JWT 认证入口,用于处理认证失败的情况。
```java
@Component
public class JwtAuthenticationEntryPoint implements AuthenticationEntryPoint {
@Override
public void commence(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException {
httpServletResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Unauthorized");
}
}
```
6. 创建自定义用户详情服务
创建一个自定义用户详情服务,用于从数据库中获取用户信息。
```java
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
@Transactional
public UserDetails loadUserByUsername(String usernameOrEmail) throws UsernameNotFoundException {
User user = userRepository.findByUsernameOrEmail(usernameOrEmail, usernameOrEmail)
.orElseThrow(() ->
new UsernameNotFoundException("User not found with username or email : " + usernameOrEmail)
);
return UserPrincipal.create(user);
}
@Transactional
public UserDetails loadUserById(Long id) {
User user = userRepository.findById(id).orElseThrow(
() -> new ResourceNotFoundException("User", "id", id)
);
return UserPrincipal.create(user);
}
}
```
这些步骤只是整合 Spring Security 和 JWT 的基本步骤,具体还需根据项目需求进行调整和完善。
阅读全文