Словить AccessDeniedException в SpringSecurity REST API 2.0
Данный вопрос уже задавался вот
Но к сожалению данный вопрос не закрыт и ответ который там предложен не работает.
У меня есть класс унаследованный от WebSecurityConfigurerAdapter который имеет:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf()
.disable()
.authorizeRequests()
.antMatchers("/admin/**")
.hasRole("ADMIN")
//.antMatchers("/auth/login", "/auth/registration", "/error").permitAll()
.antMatchers(AUTH_WHITELIST).permitAll()
.anyRequest().hasAnyRole("USER")
.and()
.exceptionHandling()
.accessDeniedHandler(accessDeniedHandler())
.and()
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(personDetailsService)
.passwordEncoder(getPasswordEncoder());
}
@Bean
public PasswordEncoder getPasswordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public AccessDeniedHandler accessDeniedHandler(){
return new ApiAccessDeniedHandler();
}
Также есть класс:
public class ApiAccessDeniedHandler implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException {
System.out.println("TEST");
}
}
Однако все равно в метод handle так и не заходит при появлении ошибки AccessDeniedException.
подключенный фильтр отрабатывает вроде правильно, вот его код:
@Component
public class JWTFilter extends OncePerRequestFilter {
private final JWTUtil jwtUtil;
private final PersonDetailsService personDetailsService;
@Autowired
public JWTFilter(JWTUtil jwtUtil, PersonDetailsService personDetailsService) {
this.jwtUtil = jwtUtil;
this.personDetailsService = personDetailsService;
}
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
FilterChain filterChain) throws IOException, ServletException {
String authHeader = httpServletRequest.getHeader("Authorization");
if (authHeader != null && !authHeader.isBlank() && authHeader.startsWith("Bearer ")) {
String jwt = authHeader.substring(7);
if (jwt.isBlank()) {
httpServletResponse.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Invalid JWT Token in Bearer Header");
} else {
try {
String username = jwtUtil.validateTokenAndRetrieveClaim(jwt);
UserDetails userDetails = personDetailsService.loadUserByUsername(username);
UsernamePasswordAuthenticationToken authToken =
new UsernamePasswordAuthenticationToken(
userDetails,
userDetails.getPassword(),
userDetails.getAuthorities());
if (SecurityContextHolder.getContext().getAuthentication() == null) {
SecurityContextHolder.getContext().setAuthentication(authToken);
}
} catch (JWTVerificationException | UsernameNotFoundException e) {
httpServletResponse.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Invalid JWT Token");
}
}
} else {
httpServletResponse.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Invalid authorization");
}
filterChain.doFilter(httpServletRequest, httpServletResponse);
}
}
Перерыл уже море вариантов и никакой не сработал, думаю, что упускаю какую-то мелочь как всегда.