Изначально Spring вернул 403 для обоих. Затем я добавил конфигурациюExceptionHandling:
WebSecurityConfig.java:
Код: Выделить всё
...
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(AbstractHttpConfigurer::disable)
.formLogin(AbstractHttpConfigurer::disable)
.rememberMe(AbstractHttpConfigurer::disable)
.httpBasic(AbstractHttpConfigurer::disable)
.logout(AbstractHttpConfigurer::disable)
.cors(c -> c.configurationSource(corsConfigurationSource()))
.authorizeHttpRequests(c -> c
.requestMatchers(HttpMethod.OPTIONS).permitAll()
.requestMatchers(UNPROTECTED_PATHS).permitAll()
.anyRequest().authenticated()
)
.exceptionHandling(c -> c
.authenticationEntryPoint((request, response, authException) -> response.sendError(
HttpServletResponse.SC_UNAUTHORIZED, authException.getMessage() // this one
))
.accessDeniedHandler((request, response, accessDeniedException) -> response.sendError(
HttpServletResponse.SC_FORBIDDEN, accessDeniedException.getMessage() // and this
))
)
.sessionManagement(c -> c.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}
...
Код: Выделить всё
...
@Component
@RequiredArgsConstructor
@Slf4j
public class JwtRequestFilter extends OncePerRequestFilter {
private static final String HEADER_AUTHORIZATION = "Authorization";
private static final String AUTHORIZATION_PREFIX = "Bearer";
private final JwtService jwtService;
private final UserDao userDao;
@Override
protected void doFilterInternal(
@NonNull HttpServletRequest request,
@NonNull HttpServletResponse response,
@NonNull FilterChain filterChain
) throws ServletException, IOException {
filterRequest(request);
filterChain.doFilter(request, response);
}
private void filterRequest(HttpServletRequest request) {
Authentication existAuthentication = SecurityContextHolder.getContext().getAuthentication();
if (existAuthentication != null && existAuthentication.isAuthenticated()) {
return;
}
String token = getToken(request);
if (token == null) {
return;
}
User user = jwtService.getUser(token).orElse(null);
if (user == null) {
return;
}
userDao.register(user);
setAuthentication(request, user);
}
@Nullable
private String getToken(HttpServletRequest request) {
String authorizationHeader = request.getHeader(HEADER_AUTHORIZATION);
if (authorizationHeader == null || !authorizationHeader.startsWith(AUTHORIZATION_PREFIX + " ")) {
return null;
}
return authorizationHeader.substring(7);
}
private static void setAuthentication(HttpServletRequest request, UserDetails userDetails) {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
userDetails,
null,
userDetails.getAuthorities()
);
authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
}
}
Код: Выделить всё
AuthenticationExceptionКак это предотвратить? p>
Я использую Spring Security v.6.2.3.
В настоящее время я использую обходной путь с ControllerAdvice:
Код: Выделить всё
@ExceptionHandler(AccessDeniedException.class)
public ResponseEntity handleException(AccessDeniedException e) {
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
Подробнее здесь: https://stackoverflow.com/questions/790 ... iedhandler
Мобильная версия