如果授权不成功,我需要返回HTTP 401状态。我使用Spring Security和以下设置授权:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatcher(ADMIN_MATCHERS)
.authorizeRequests()
.antMatchers(ADMIN_MATCHERS)
.access("hasRole('ADMIN')")
.anyRequest().authenticated()
.and()
.formLogin()
.usernameParameter(USERNAME)
.passwordParameter(PASSWORD)
.loginPage(ADMIN_LOGIN)
.permitAll()
.loginProcessingUrl("/admin/login/auth")
.failureHandler(customAuthFailureHandler)
.successHandler(successHandler())
.and()
.logout()
.logoutUrl("/admin/logout")
.logoutSuccessUrl(ADMIN_LOGIN)
.and()
.exceptionHandling()
.accessDeniedPage(ADMIN_LOGIN)
.and()
.csrf().disable()
.httpBasic();
我使用failureHandler()
来处理它。
我写了一个自定义处理程序:
@Component("customAuthFailureHandler")
public class CustomAuthFailureHandler extends SimpleUrlAuthenticationFailureHandler {
private static final String ADMIN_LOGIN = "/admin/login";
private static final Integer STATUS_UNAUTHORIZED = 401;
private static final String RESPONSE_CODE_KEY = "Response-Code";
private static final String RESPONSE_BAD_CREDENTIALS = "bad-credentials";
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
response.setStatus(STATUS_UNAUTHORIZED);
response.addHeader(RESPONSE_CODE_KEY, RESPONSE_BAD_CREDENTIALS);
getRedirectStrategy().sendRedirect(request, response, ADMIN_LOGIN);
}
}
标题返回OK,但状态为302而不是401。
答案 0 :(得分:0)
当您调用sendError时,它将把请求分派到/ error(它是Spring Boot注册的错误处理代码。但是,Spring Security将截获/ error并看到您未通过身份验证,因此将您重定向到登录表单
答案 1 :(得分:0)
处理程序:
@Order(Ordered.HIGHEST_PRECEDENCE)
@ControllerAdvice
public class RestExceptionHandler extends ResponseEntityExceptionHandler {
@Override
protected ResponseEntity<Object> handleHttpMessageNotReadable(HttpMessageNotReadableException ex,
final HttpHeaders headers,
final HttpStatus status,
final WebRequest request) {
String error = "Malformed JSON request";
return buildResponseEntity(new ApiError(HttpStatus.BAD_REQUEST, error, ex));
}
private ResponseEntity<Object> buildResponseEntity(ApiError apiError) {
return new ResponseEntity<>(apiError, apiError.getStatus());
}
/**
* Handle NoSuchElementException
**/
@ExceptionHandler(NoSuchElementException.class)
protected ResponseEntity<Object> handleEntityNotFound(NoSuchElementException ex) {
ApiError apiError = new ApiError(HttpStatus.NOT_FOUND);
apiError.setMessage(apiError.getMessage());
return buildResponseEntity(apiError);
}
@ExceptionHandler(Exception.class)
public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) {
ApiError apiError = new ApiError(HttpStatus.NOT_FOUND);
//apiError.setMessage(Translator.toLocale(apiError.getMessage(), null));
apiError.setMessage(ex.getMessage());
return buildResponseEntity(apiError);
}
}
ApiError:
public class ApiError {
@Getter
@Setter
private HttpStatus status;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd-MM-yyyy hh:mm:ss")
private LocalDateTime timestamp;
@Setter
@Getter
private String message;
@Setter
@Getter
private String debugMessage;
@Setter
@Getter
private List<ApiValidationError> subErrors;
private ApiError() {
timestamp = LocalDateTime.now();
}
public ApiError(HttpStatus status) {
this();
this.status = status;
}
ApiError(HttpStatus status, Throwable ex) {
this();
this.status = status;
this.message = "Unexpected error";
this.debugMessage = ex.getLocalizedMessage();
}
public ApiError(HttpStatus status, String message, Throwable ex) {
this();
this.status = status;
this.message = message;
this.debugMessage = ex.getLocalizedMessage();
}
}