我创建了一个带有自定义jwt身份验证的spring boot restapi。我的问题是,当我发送一个带有过期或无效jwt令牌的请求时,会出现如下异常:
com.auth0.jwt.exceptions.SignatureVerificationException: The Token's Signature resulted invalid when verified using the Algorithm: HmacSHA512
这显然是正常的,但是响应主体是空的,因此客户机不知道403错误的原因。
这个问题和spring的异常等是一样的。。。
如何将这些异常转换为自定义错误响应而不是“403禁止”?
spring web配置:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final UserDetailsServiceImpl userDetailsService;
@Autowired
public WebSecurityConfig(UserDetailsServiceImpl userDetailsService) {
this.userDetailsService = userDetailsService;
}
@Override
protected void configure(HttpSecurity http) throws Exception {
JWTAuthenticationFilter filter = new JWTAuthenticationFilter(authenticationManager());
filter.setFilterProcessesUrl(AUTH_URL);
http.cors().and().csrf().disable().authorizeRequests()
.antMatchers(HttpMethod.POST, SIGN_UP_URL).permitAll()
.anyRequest().authenticated()
.and()
.addFilter(filter)
.addFilter(new JWTAuthorizationFilter(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
@Override
public void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", new CorsConfiguration().applyPermitDefaultValues());
return source;
}
}
jwtauthenticationfilter文件
private final AuthenticationManager authenticationManager;
@Autowired
public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Override
public Authentication attemptAuthentication(HttpServletRequest req,
HttpServletResponse res) throws AuthenticationException {
try {
String decoded = new String(Base64.getDecoder().decode(new String(req.getInputStream().readAllBytes())));
AuthenticationDetails details = new Gson().fromJson(decoded, AuthenticationDetails.class);
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
details.getUsername(),
details.getPassword(),
new ArrayList<>()));
} catch (TokenExpiredException e) {
req.setAttribute("expired", e.getMessage());
throw new TokenExpiredException(e.getMessage());
} catch (Exception e){
throw new RuntimeException(e);
}
}
@Override
protected void successfulAuthentication(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain,
Authentication auth) throws IOException, ServletException {
String token = JWT.create()
.withSubject(((User) auth.getPrincipal()).getUsername())
.withExpiresAt(new Date(System.currentTimeMillis() + EXPIRATION_TIME))
.sign(Algorithm.HMAC512(SECRET.getBytes()));
res.addHeader(HEADER_STRING, TOKEN_PREFIX + token);
}
}
JWT授权筛选器
public JWTAuthorizationFilter(AuthenticationManager authManager) {
super(authManager);
}
@Override
protected void doFilterInternal(HttpServletRequest req,
HttpServletResponse res,
FilterChain chain) throws IOException, ServletException {
String header = req.getHeader(HEADER_STRING);
if (header == null || !header.startsWith(TOKEN_PREFIX)) {
chain.doFilter(req, res);
return;
}
UsernamePasswordAuthenticationToken authentication = getAuthentication(req);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(req, res);
}
private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
String token = request.getHeader(HEADER_STRING);
if (token != null) {
String user = JWT.require(Algorithm.HMAC512(SECRET.getBytes()))
.build()
.verify(token.replace(TOKEN_PREFIX, ""))
.getSubject();
if (user != null) {
return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
}
return null;
}
return null;
}
}
1条答案
按热度按时间41zrol4v1#
如果你要延长
JWTAuthenticationFilter
从AbstractAuthenticationProcessingFilter
,您可以覆盖unsuccessfulAuthentication
如下所示:现在,如您所见,我已将失败处理委托给
failureHandler
哪种类型的org.springframework.security.web.authentication.AuthenticationFailureHandler
.为此,您需要注册自定义失败处理程序。您可以通过从
org.springframework.security.web.authentication.AuthenticationFailureHandler
和覆盖onAuthenticationFailure
,并检查从JWTAuthenticationFilter
,如下所示: