【问题标题】:In Spring Security how do I capture exceptions from a custom AuthenticationManager?在 Spring Security 中,如何从自定义 AuthenticationManager 中捕获异常?
【发布时间】:2018-05-07 23:38:26
【问题描述】:

我正在使用 Crowd 的 Java 集成到 Spring Security 中,这涉及将 Crowds SimpleAuthenticationManager 配置为身份验证提供程序。当用户基于无法通过身份验证的原因而无法通过身份验证时,SimpleAuthenticationManager 会引发几个异常。我想知道在 Spring Security 中如何捕获该异常并将 JSON 响应返回给客户端?

我已经尝试添加一个 AccessDeniedHandler,但是这会收到一个新异常,该异常没有原始异常作为原因。

【问题讨论】:

    标签: java spring spring-security atlassian-crowd


    【解决方案1】:

    我在谷歌搜索 StackOverflow 时错过了这篇文章: Spring security 3 http-basic authentication-success-handler

    事实证明,正如其他问题/答案所指出的,您需要扩展 BasicAuthenticationFilter 并实现 onUnsuccessfulAuthentication() 方法。然后将其添加到您的安全配置中:

    http.addFilter(new CustomBasicAuthenticationFilter(authenticationManagerBean()))
    

    编辑实际上,此时 Spring 似乎仍在包装异常,但是您可以获得一些更具体的异常,这很有帮助。

    【讨论】:

      【解决方案2】:

      您可以使用@ControllerAdvice 注释扩展ResponseEntityExceptionHandler。这将捕获异常,您可以处理和发送自定义响应。示例:

      @ControllerAdvice
      public class CustomExceptionHandler extends ResponseEntityExceptionHandler {
          private static final Logger log = LoggerFactory.getLogger(CustomExceptionHandler.class);
      
          public CustomExceptionHandler() {
          }
      
          // overriding an exception that already is been handled in ResponseEntityExceptionHandler
          @Override
          protected ResponseEntity<Object> handleMissingPathVariable(MissingPathVariableException ex,
                  HttpHeaders headers, HttpStatus status, WebRequest request) {
              log.warn(ex.toString());
      
              final String parameter = ex.getParameter().getParameterName();
              final String detailMessage = ex.getMessage();
              final String message = "Parameter " + parameter + " is missing.";
      
              final ErrorMessageDTO result = new ErrorMessageDTO(HttpStatus.BAD_REQUEST, message, parameter, detailMessage, null);
              return ResponseEntity.badRequest().body(result);
          }
      
          // Custom handle to intercept BadCredentialsException
          @ExceptionHandler(BadCredentialsException.class)
          @ResponseBody
          ResponseEntity<Object> handleBadCredentialsException(HttpServletRequest req,
                  BadCredentialsException ex) {
              log.warn(ex.toString());
      
              final ErrorMessageDTO result = new ErrorMessageDTO(HttpStatus.UNAUTHORIZED, ex.getMessage());
              return ResponseEntity.badRequest().body(result);
          }
      
      }
      

      【讨论】:

      • 不幸的是,我认为这不会起作用,因为身份验证发生在实际调用控制器方法之前,因此@ExceptionHandler 不会拾取它抛出的异常。
      • 如果您使用无状态方法,使用 oauth2、jwt、基本身份验证等类似的东西,则在调用其余请求时会引发身份验证错误(并且您甚至在进入控制器)
      猜你喜欢
      • 2016-12-07
      • 2012-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多