有人可以分享在 SpringBoot 中处理 401、403 响应正文的分步代码,而不使用 WebSecurityConfigurerAdapter 进行令牌验证吗?使用 FIlterChain 或其他方法。
如果有人帮助我那就太好了。
谢谢你
我检查了google,发现WebSecurityConfigurerAdapter仅用于令牌验证。但是,我还没有找到其他替代方案。
要使用自定义响应正文处理 Spring Boot 应用程序中的
401 Unauthorized
和 403 Forbidden
HTTP 响应,您可以实现自定义过滤器。该过滤器将拦截请求并检查身份验证和授权问题。以下是有关如何使用 FilterChain
和自定义异常来实现此目的的分步指南。
OncePerRequestFilter
创建自定义过滤器,这可确保每个请求仅调用您的过滤器一次。import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import com.fasterxml.jackson.databind.ObjectMapper;
@Component
public class CustomAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
try {
// Pass the request to the next filter in the chain
filterChain.doFilter(request, response);
} catch (UnauthorizedException e) {
// Handle 401 Unauthorized
handleException(response, e, HttpStatus.UNAUTHORIZED);
} catch (ForbiddenException e) {
// Handle 403 Forbidden
handleException(response, e, HttpStatus.FORBIDDEN);
}
}
private void handleException(HttpServletResponse response, Exception ex, HttpStatus status) throws IOException {
response.setStatus(status.value());
response.setContentType("application/json");
ErrorResponse errorResponse = new ErrorResponse(status.value(), ex.getMessage());
ObjectMapper mapper = new ObjectMapper();
String responseBody = mapper.writeValueAsString(errorResponse);
response.getWriter().write(responseBody);
}
// Custom ErrorResponse class
public static class ErrorResponse {
private int status;
private String message;
public ErrorResponse(int status, String message) {
this.status = status;
this.message = message;
}
// Getters and Setters
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
}
UnauthorizedException
(针对 401 错误)和 ForbiddenException
(针对 403 错误)创建自定义异常类。public class UnauthorizedException extends RuntimeException {
public UnauthorizedException(String message) {
super(message);
}
}
public class ForbiddenException extends RuntimeException {
public ForbiddenException(String message) {
super(message);
}
}
SecurityConfig
类中配置它。import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
@EnableWebSecurity
public class SecurityConfig {
private final CustomAuthenticationFilter customAuthenticationFilter;
public SecurityConfig(CustomAuthenticationFilter customAuthenticationFilter) {
this.customAuthenticationFilter = customAuthenticationFilter;
}
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
// Add your filter before the authentication filter
.addFilterBefore(customAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().disable(); // Disable default login page
return http.build();
}
}
401
或 403
错误时,将返回自定义响应以及包含状态和错误消息的 JSON 正文。{
"status": 401,
"message": "Unauthorized access"
}
或
{
"status": 403,
"message": "Forbidden access"
}
401 Unauthorized
和 403 Forbidden
异常的自定义过滤器。