如何在自定义 AuthenticationFailureHandler 中返回由具体派生 AuthenticationException 类型解析的不同错误消息

Posted

技术标签:

【中文标题】如何在自定义 AuthenticationFailureHandler 中返回由具体派生 AuthenticationException 类型解析的不同错误消息【英文标题】:How to return different error message resolved by concrete derived AuthenticationException type in custom AuthenticationFailureHandler 【发布时间】:2020-06-02 15:34:54 【问题描述】:

我正在使用 Spring Security 来构建我的博客应用程序的身份验证/授权。我们决定使用 RESTful api,为了在服务器端处理身份验证错误时向客户端返回 json 消息,我必须编写自定义 AuthenticationFailureHandler,例如:

public class RganAuthenticationFailureHandler implements AuthenticationFailureHandler 
    private static Logger logger = LoggerFactory.getLogger(RganAuthenticationFailureHandler.class);


    @Override
    public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException 
        httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
        httpServletResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
        httpServletResponse.getWriter().write("some description");
    

AuthenticationException 有一些具体的派生类型,描述确切的错误,例如: UsernameNotFoundExceptionBadCredentialsExceptionAuthenticationServiceException...

在我看来,我应该为不同的异常类型返回不同的错误消息。例如,对于UsernameNotFoundExceptionBadCredentialsException,我可能会返回“错误的用户名或密码,对于AuthenticationServiceException,我可能会返回“在获取您的凭据时发生某些错误,请稍后重试”和不同的 HTTP 状态代码(像 500)。

现在问题来了,我知道我可以编写如下代码:

if(e instanceof UsernameNotFoundException || e instanceof BadCredentialsException)
    httpServletResponse.getWriter.write("message1");
else if(e instance of AuthenticationServiceException)
    httpServletResponse.getWriter.write("message2");
else if(...)
    // ...

为了解决这个问题,但这似乎不是最好的解决方案,我必须写一系列else if 块。

我读过https://***.com/a/46530064/8510613 之类的帖子,似乎使用@ControllerAdvice 和HandlerExceptionResolver 也不是最好的解决方案。

那么我应该如何处理这个问题呢?

【问题讨论】:

【参考方案1】:

您可以通过使用DelegatingAuthenticationFailureHandler 进一步做出决定

委托给其他人的 AuthenticationFailureHandler AuthenticationFailureHandler 实例基于的类型 AuthenticationException 传入 onAuthenticationFailure

【讨论】:

您的意思是将<ExceptionClass, handler> 映射提供给DelegatingAuthenticationFailureHandler 的构造函数并将其用作我的应用程序的failureHandler 我会这么认为 您至少可以为此添加一个代码示例。

以上是关于如何在自定义 AuthenticationFailureHandler 中返回由具体派生 AuthenticationException 类型解析的不同错误消息的主要内容,如果未能解决你的问题,请参考以下文章

如何在自定义页面 Django 中使用管理表单

织梦CMS如何在自定义表单页调用arclist标签啊,怎么在自定义表单页调用无效!

iOS - 如何在自定义单元格中使用继承?

如何在自定义 UICollectionView 的旋转后触发 drawrect?

如何在自定义 CollectionView 中使用 UIScrollViewDelegate?

如何使用 Python 在自定义 dbus 上导出对象?