java—有没有任何方法可以将authenticationexception抛出到authenticationentrypoint中?

pvcm50d1  于 2021-07-24  发布在  Java
关注(0)|答案(0)|浏览(290)

我已经实现了jwt授权系统。它工作正常,但我应该通知客户端,他们的令牌已过期。
我配置了spring安全:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Autowired
UserDetailsServiceImpl userDetailsService;

@Autowired
private JwtAuthEntryPoint unauthorizedHandler;

@Bean
public JwtAuthTokenFilter authenticationJwtTokenFilter() {
    return new JwtAuthTokenFilter();
}

@Bean
public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
}

@Override
public void configure(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
    authenticationManagerBuilder
            .userDetailsService(userDetailsService)
            .passwordEncoder(passwordEncoder());
}

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
            .csrf().disable()
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
            .authorizeRequests()
            .antMatchers("/login", "/signup", "/email-exist", "/username-exist", "/refresh-tokens", "/public/**").permitAll()
            .antMatchers("/api/trainer/default-config").hasRole(Role.ROLE_ADMIN.name().replace("ROLE_",""))
            .anyRequest().authenticated()
            .and()
            .exceptionHandling().authenticationEntryPoint(unauthorizedHandler);

    http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
    http.addFilterAt(this.corsFilter(), CorsFilter.class);
}
}

所以如果我抓到 TokenExpiredException 或者 SignatureVerificationException 在我的 AuthFilter ,我要用消息通知客户端: Token is expired 或者 Token is invalid ```
@Slf4j
public class JwtAuthTokenFilter extends OncePerRequestFilter {

@Autowired
private TokenProvider tokenProvider;

@Autowired
UserDetailsServiceImpl userDetailsService;

@Autowired
JwtAuthEntryPoint authenticationEntryPoint;

@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
throws ServletException, IOException {
try {

    String actionToken = tokenProvider.getToken(request);
    if (actionToken !=null) {
        String username = tokenProvider.getUserNameFromJwtToken(actionToken);
        List<GrantedAuthority> authorities = tokenProvider.getAuthoritiesFromJwtToken(actionToken);

        UsernamePasswordAuthenticationToken authentication
                = new UsernamePasswordAuthenticationToken(userDetailsService.loadUserByUsername(username), null, authorities);
        authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));

        SecurityContextHolder.getContext().setAuthentication(authentication);
    }
} catch (IllegalArgumentException e) {
    logger.error("an error occured during getting username from token", e);
} catch (TokenExpiredException e) {
    logger.warn("the token is expired and not valid anymore", e);
} catch(SignatureVerificationException e){
    logger.error("Someone change the token!");
} catch (Exception e) {
    log.error("Can NOT set user authentication -> Message: {}", e);
}

filterChain.doFilter(request, response);

}
}

我还有一个 `exceptionHandler` 为了 `Authentication` ```
@Component
@Slf4j
public class JwtAuthEntryPoint implements AuthenticationEntryPoint {

@Override
public void commence(HttpServletRequest request,
                     HttpServletResponse response,
                     AuthenticationException e) 
                             throws IOException, ServletException {

    log.error(e.getMessage());
    response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
}
}

如果令牌过期或无效,我总是发送消息 Full authentication is required to access this resource . 但我必须通知我的客户关于过期的代币。
我试着打电话 commence 方法在我的 JwtAuthTokenFilter 但它不起作用:

} catch (TokenExpiredException e) {
     authenticationEntryPoint.commence(request, response, new CredentialsExpiredException(e.getMessage()));
     logger.warn("the token is expired and not valid anymore", e);
} catch(SignatureVerificationException e){
     authenticationEntryPoint.commence(request, response, new BadCredentialsException(e.getMessage()));
     logger.error("Someone change the token!");
}

那么,有没有什么方法可以通过我的异常将关于令牌的消息传递到 JwtAuthEntryPoint ?

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题