如何处理spring ProviderManager中抛出的Spring安全性InternalAuthenticationServiceException

时间:2016-09-30 10:30:51

标签: java spring spring-security spring-boot

ProviderManager在DaoAuthenticationProvider.class中检索用户时抛出InternalAuthenticationServiceException.class,

 loadedUser = this.getUserDetailsService().loadUserByUsername(username);

我想处理此异常并将自定义响应返回给客户端。

我不想通过编写自定义ProviderManager来处理这个问题。

对于所有其他OAuth异常,我可以使用Custom WebResponseExceptionTranslator处理异常。

但是我无法捕获像InternalAuthenticationServiceException.class这样的安全异常。

我没有选择将ErrorController与/ error路径一起使用,它会破坏其他流程。

3 个答案:

答案 0 :(得分:3)

首先你需要实现自己的 AuthenticationEntryPoint 这个名字真的不是自动解释...

例如,如果您需要始终返回状态代码200(仅用于学习目的,请不要在现实世界中进行...)

@Component("myOwnAuthenticationEntryPoint")
public class MyOwnAuthenticationEntryPoint implements AuthenticationEntryPoint {
    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, org.springframework.security.core.AuthenticationException authException) throws IOException, ServletException {
        response.sendError(HttpServletResponse.SC_OK, "Unauthorized");
    } 

然后在WebSecurityConfig中,您需要将其设置为身份验证异常处理程序入口点。

...

public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    ...

    @Autowired
    MyOwnAuthenticationEntryPoint myOwnAuthenticationEntryPoint;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.exceptionHandling().authenticationEntryPoint(myOwnAuthenticationEntryPoint);
    ...
    }

多数民众赞成。 :)

答案 1 :(得分:1)

您可以编写一个使用@ControllerAdvice注释并拥有@ExceptionHandler(value=InternalAuthenticationServiceException.class)的课程。

例如: -

@ControllerAdvice
public class ExceptionHandler {

    @ExceptionHandler(InternalAuthenticationServiceException.class)
    public ResponseEntity<String> handleInternalAuthenticationServiceException(InternalAuthenticationServiceException e) {
        ResponseEntity<String> response = new ResponseEntity<String>(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
        return response;
    }

}

答案 2 :(得分:0)

我已经通过覆盖过滤器中的unsuccessfulAuthentication方法解决了该问题,并使用所需的HTTP状态代码向客户端发送了错误响应。就我而言,我还创建了从服务中抛出的自定义异常(RecordNotFoundException)。

@Override
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
        AuthenticationException failed) throws IOException, ServletException {

    if (failed.getCause() instanceof RecordNotFoundException) {
        response.sendError((HttpServletResponse.SC_NOT_FOUND), failed.getMessage());
    }
}