Spring Security怎么使用JWT来验证用户的身份和权限
时间: 2024-02-22 15:49:34 浏览: 144
SpringBoot+SpringSecurity+JWT+MybatisPlus实现基于注解的权限验证
4星 · 用户满意度95%
Spring Security可以使用JWT(JSON Web Token)来验证用户的身份和权限。
1.添加JWT依赖项:在pom.xml文件中添加以下依赖项:
```
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
```
2.创建JWT工具类:创建一个JWT工具类来生成和验证JWT。
```
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class JwtUtils {
private final String JWT_SECRET = "mysecretkey";
private final int JWT_EXPIRATION_MS = 86400000;
public String generateJwtToken(Authentication authentication) {
User user = (User) authentication.getPrincipal();
return Jwts.builder()
.setSubject((user.getUsername()))
.setIssuedAt(new Date())
.setExpiration(new Date((new Date()).getTime() + JWT_EXPIRATION_MS))
.signWith(SignatureAlgorithm.HS512, JWT_SECRET)
.compact();
}
public boolean validateJwtToken(String authToken) {
try {
Jwts.parser().setSigningKey(JWT_SECRET).parseClaimsJws(authToken);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
public String getUsernameFromJwtToken(String token) {
return Jwts.parser()
.setSigningKey(JWT_SECRET)
.parseClaimsJws(token)
.getBody().getSubject();
}
}
```
3.创建JWT过滤器:创建一个JWT过滤器来验证JWT并设置用户的身份和权限。
```
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import com.example.demo.security.services.UserDetailsServiceImpl;
import io.jsonwebtoken.ExpiredJwtException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class JwtAuthTokenFilter extends OncePerRequestFilter {
@Autowired
private JwtUtils jwtUtils;
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
try {
String jwt = parseJwt(request);
if (jwt != null && jwtUtils.validateJwtToken(jwt)) {
String username = jwtUtils.getUsernameFromJwtToken(jwt);
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
} catch (ExpiredJwtException e) {
logger.error("JWT token is expired: {}", e.getMessage());
} catch (Exception e) {
logger.error("Cannot set user authentication: {}", e.getMessage());
}
chain.doFilter(request, response);
}
private String parseJwt(HttpServletRequest request) {
String headerAuth = request.getHeader("Authorization");
if (headerAuth != null && headerAuth.startsWith("Bearer ")) {
return headerAuth.substring(7, headerAuth.length());
}
return null;
}
}
```
4.配置Spring Security:在Spring Security配置中添加JWT过滤器。
```
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import com.example.demo.security.jwt.JwtAuthTokenFilter;
import com.example.demo.security.services.UserDetailsServiceImpl;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(
// securedEnabled = true,
// jsr250Enabled = true,
prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthTokenFilter jwtAuthTokenFilter;
@Autowired
private UserDetailsServiceImpl userDetailsService;
@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
@Bean
public DaoAuthenticationProvider authenticationProvider() {
DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider();
authProvider.setUserDetailsService(userDetailsService);
authProvider.setPasswordEncoder(bCryptPasswordEncoder);
return authProvider;
}
@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
authenticationManagerBuilder.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/auth/**").permitAll()
.anyRequest().authenticated();
http.addFilterBefore(jwtAuthTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
}
```
现在,Spring Security将使用JWT来验证用户的身份和权限。您可以在需要身份验证和授权的端点上使用Spring Security注释,例如@PreAuthorize和@PostAuthorize。
阅读全文