return ResponseEntity<>(HttpStatus.UNAUTHORIZED) 在 Spring 安全基本身份验证中身份验证失败时如何?
How can I return ResponseEntity<>(HttpStatus.UNAUTHORIZED) when Authentication failed in Spring security basic authentication?
我在我的微服务中使用 spring 安全基本身份验证来对客户端进行身份验证,我向消费者提供了我将 return 响应作为 ResponseEntity<>(HttpStatus.XXX) .对于除 401(未授权)之外的所有其他代码,我可以从其余控制器实现此目的,因为 BasicAuthenticationEntryPoint 过滤器正在处理此问题并在请求中没有授权详细信息时给出响应 header。在这种情况下,我如何 return 作为 ResponseEntity<>(HttpStatus.UNAUTHORIZED) 的响应?
我扩展了 BasicAuthenticationEntryPoint 以将我自己的身份验证入口点自定义为 MyBasicAuthenticationEntryPoint。然后抛出异常并尝试从@ExceptionHandler 进行处理。但是,这是行不通的。另外,我用 @ControllerAdvice 注释 class 并读到这将处理仅从控制器抛出的异常。并且,@ExceptionHandler 将在 DispatcherServlet 之后处理异常,而在我的情况下,请求未到达控制器,因为请求中缺少授权详细信息 header.
我在这里所能做的就是在 HttpServletResponse 中包含我的响应 header 和响应状态。我想知道当客户端尝试将 return 类型期望为 ResponseEntity<>(HttpStatus.XXX).
时是否会由客户端处理
在 WebSecurityConfigurerAdapter 扩展的配置方法中定义了我的自定义身份验证入口点 class。
@Configuration
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
@Autowired
private MyBasicAuthenticationEntryPoint authenticationEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().
authorizeRequests()
.antMatchers(HttpMethod.POST)
.authenticated()
.antMatchers("/api-docs", "/swagger*/**")
.permitAll()
.and()
.httpBasic().authenticationEntryPoint(authenticationEntryPoint)
;
http.headers().frameOptions().disable();
}
}
如下创建我的自定义身份验证入口点,
@Component
public class MyBasicAuthenticationEntryPoint extends
BasicAuthenticationEntryPoint {
@Override
public void commence
(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authEx)
throws IOException, ServletException {
System.out.println("Child Class");
throw new UnauthorizedException("unauthorized");
//response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
通过扩展 RuntimeException class 定义了 UnauthorizedException class。
public class UnauthorizedException extends RuntimeException {
public UnauthorizedException(String message) {
super(message);
}
}
在 ResponseEntityExceptionHandler extended class 中处理上述异常,如下所示,
@ControllerAdvice
@RestController
public class CustomizedResponseEntityExceptionHandler extends
ResponseEntityExceptionHandler {
@ExceptionHandler(UnauthorizedException.class)
public final ResponseEntity<Void>
handleNotFoundException(UnauthorizedException ex, WebRequest request) {
System.out.println("handling 401");
return new ResponseEntity<>((HttpStatus.UNAUTHORIZED));
}
}
我希望 return ResponseEntity<>(HttpStatus.UNAUTHORIZED),但 MyBasicAuthenticationEntryPoint 正在使用 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED).
编写响应
CustomizedResponseEntityExceptionHandler
仅处理在您的控制器中遇到的异常,此 @ControllerAdvice
是 self-explanatory。
您错误配置了 authEntryPoint,请参阅此 answer 了解如何正确配置它。
实现你想要的,可以在MyBasicAuthenticationEntryPoint.commence
中直接写response
我在我的微服务中使用 spring 安全基本身份验证来对客户端进行身份验证,我向消费者提供了我将 return 响应作为 ResponseEntity<>(HttpStatus.XXX) .对于除 401(未授权)之外的所有其他代码,我可以从其余控制器实现此目的,因为 BasicAuthenticationEntryPoint 过滤器正在处理此问题并在请求中没有授权详细信息时给出响应 header。在这种情况下,我如何 return 作为 ResponseEntity<>(HttpStatus.UNAUTHORIZED) 的响应?
我扩展了 BasicAuthenticationEntryPoint 以将我自己的身份验证入口点自定义为 MyBasicAuthenticationEntryPoint。然后抛出异常并尝试从@ExceptionHandler 进行处理。但是,这是行不通的。另外,我用 @ControllerAdvice 注释 class 并读到这将处理仅从控制器抛出的异常。并且,@ExceptionHandler 将在 DispatcherServlet 之后处理异常,而在我的情况下,请求未到达控制器,因为请求中缺少授权详细信息 header.
我在这里所能做的就是在 HttpServletResponse 中包含我的响应 header 和响应状态。我想知道当客户端尝试将 return 类型期望为 ResponseEntity<>(HttpStatus.XXX).
时是否会由客户端处理在 WebSecurityConfigurerAdapter 扩展的配置方法中定义了我的自定义身份验证入口点 class。
@Configuration
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
@Autowired
private MyBasicAuthenticationEntryPoint authenticationEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().
authorizeRequests()
.antMatchers(HttpMethod.POST)
.authenticated()
.antMatchers("/api-docs", "/swagger*/**")
.permitAll()
.and()
.httpBasic().authenticationEntryPoint(authenticationEntryPoint)
;
http.headers().frameOptions().disable();
}
}
如下创建我的自定义身份验证入口点,
@Component
public class MyBasicAuthenticationEntryPoint extends
BasicAuthenticationEntryPoint {
@Override
public void commence
(HttpServletRequest request, HttpServletResponse response,
AuthenticationException authEx)
throws IOException, ServletException {
System.out.println("Child Class");
throw new UnauthorizedException("unauthorized");
//response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
}
通过扩展 RuntimeException class 定义了 UnauthorizedException class。
public class UnauthorizedException extends RuntimeException {
public UnauthorizedException(String message) {
super(message);
}
}
在 ResponseEntityExceptionHandler extended class 中处理上述异常,如下所示,
@ControllerAdvice
@RestController
public class CustomizedResponseEntityExceptionHandler extends
ResponseEntityExceptionHandler {
@ExceptionHandler(UnauthorizedException.class)
public final ResponseEntity<Void>
handleNotFoundException(UnauthorizedException ex, WebRequest request) {
System.out.println("handling 401");
return new ResponseEntity<>((HttpStatus.UNAUTHORIZED));
}
}
我希望 return ResponseEntity<>(HttpStatus.UNAUTHORIZED),但 MyBasicAuthenticationEntryPoint 正在使用 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED).
编写响应CustomizedResponseEntityExceptionHandler
仅处理在您的控制器中遇到的异常,此 @ControllerAdvice
是 self-explanatory。
您错误配置了 authEntryPoint,请参阅此 answer 了解如何正确配置它。
实现你想要的,可以在MyBasicAuthenticationEntryPoint.commence
response