此问题在此处已有答案:
Spring Boot 3 with Spring Security Intercepts exceptions I don't want it to(2个答案)
23天前关闭
我在使用Spring Security的应用程序中遇到了问题。如果出现任何错误,在请求到达Dispatcher Servlet之前,返回错误状态403(禁止)。
问题甚至在请求到达Dispatcher Servlet之前就发生了。例如,当我尝试访问/API/v1/offer路径时,我验证字段,发生错误,之后Spring security发送403响应。即使我写了一个不存在的URL而不是404响应(未找到),我也会得到403响应。
如果您能在通过Dispatcher Servlet传递请求之前就如何解决此问题提供任何建议或提示,我将不胜感激。
下面是我的Spring Security配置:
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableMethodSecurity
public class SecurityConfiguration {
private final AuthenticationProvider authenticationProvider;
private final LogoutHandler logoutHandler;
@Value("${adapter.controller.base-path}")
private String basePath;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http, UserDetailsService userDetailsService, JwtService jwtService) throws Exception {
http
.csrf()
.disable()
.cors()
.and()
.authorizeHttpRequests(
c -> c
.requestMatchers("/api/v1/employee/**").hasAnyRole(ADMIN.name(), USER.name(), HR.name())
.requestMatchers(GET, basePath + "/employee/**").hasAnyAuthority(ADMIN_READ.name(), USER_READ.name())
.requestMatchers(POST, basePath + "/employee/**").hasAnyAuthority(ADMIN_CREATE.name(), USER_CREATE.name())
.requestMatchers(PUT, basePath + "/employee/**").hasAnyAuthority(ADMIN_UPDATE.name(), USER_UPDATE.name())
.requestMatchers(DELETE, basePath + "/employee/**").hasAnyAuthority(ADMIN_DELETE.name(), USER_DELETE.name())
.anyRequest()
.authenticated())
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authenticationProvider(authenticationProvider)
.addFilterBefore(new JwtAuthenticationFilter(userDetailsService, jwtService), UsernamePasswordAuthenticationFilter.class)
.logout()
.logoutUrl(basePath + "/auth/logout")
.addLogoutHandler(logoutHandler)
.logoutSuccessHandler((request, response, authentication) -> SecurityContextHolder.clearContext());
return http.build();
}
@Bean
public WebSecurityCustomizer ignoringCustomizer() {
return (web) -> web.ignoring().requestMatchers(basePath + "/auth", "/swagger-ui/**", "/v3/api-docs/**");
}
}
字符串
下面是我的自定义过滤器:
@Slf4j
@RequiredArgsConstructor
public class JwtAuthenticationFilter extends OncePerRequestFilter {
public static final String BEARER_SUBSTRING = "Bearer ";
private final UserDetailsService userDetailsService;
private final JwtService jwtService;
private final AuthenticationEntryPoint entryPoint = new BearerTokenAuthenticationEntryPoint();
@Override
protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain) throws ServletException, IOException {
final String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
final String jwt;
final String userEmail;
if (authHeader == null || !authHeader.startsWith(BEARER_SUBSTRING)) {
log.error("Authentication headers not found.");
entryPoint.commence(request, response, new AuthenticationCredentialsNotFoundException("Authentication headers not found."));
return;
}
jwt = authHeader.substring(BEARER_SUBSTRING.length());
try {
userEmail = jwtService.extractEmail(jwt);
if (userEmail != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(userEmail);
if (jwtService.isTokenValid(jwt, userDetails)) {
UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authToken);
}
}
filterChain.doFilter(request, response);
} catch (ExpiredJwtException e) {
log.error(e.getMessage());
entryPoint.commence(request, response, new CredentialsExpiredException(e.getMessage()));
}
}
}
型
1条答案
按热度按时间7fhtutme1#
允许任何人访问错误端点:
字符串
问题是,当错误发生时,Spring会将用户发送到
/error
端点,但在您的情况下,该端点是受保护的,因此当用户试图访问它时,它会被拒绝,用户会得到403。