min*_*lkr 5 java spring exception-handling spring-security spring-boot
如何处理 Spring Security Authentication Providers 抛出的运行时异常?我使用的是 Spring Boot 1.4.2,但我觉得这也适用于经典的 Spring 应用程序。
假设我有一个ActiveDirectoryLdapAuthenticationProvider
配置来根据我的公司 AD 对用户进行身份验证。当由于凭据错误导致身份验证失败时,Spring Security 一切都很好(AuthenticationException
抛出一个 由 Spring Security 机制正确处理的问题 = 应用程序返回登录屏幕并且可以显示身份验证错误)。
然而,有时,AD 会暂时关闭,org.springframework.ldap.CommunicationException
而是抛出a 。此异常是运行时异常,因此不会被 Spring 的安全机制捕获,因为它没有扩展AuthenticationException
。
在这种情况下,应用程序被重定向到默认错误页面(即 /error)。我想要做的是仍然显示带有自定义消息的登录屏幕。
我发现我可以做到这一点,如果我创建类似的东西
public class ActiveDirectoryLdapExtendedAuthenticationProvider implements AuthenticationProvider {
private final ActiveDirectoryLdapAuthenticationProvider adAuthenticationProvider;
public ActiveDirectoryLdapExtendedAuthenticationProvider(ActiveDirectoryLdapAuthenticationProvider adAuthenticationProvider) {
this.adAuthenticationProvider = adAuthenticationProvider;
}
@Override
public Authentication authenticate(Authentication a) throws AuthenticationException {
Authentication auth = null;
try {
auth = adAuthenticationProvider.authenticate(a);
}
catch(CommunicationException communicationException) {
throw new AuthenticationServiceException("Could not reach User Directory. Please try again in a few minutes");
}
return auth;
}
Run Code Online (Sandbox Code Playgroud)
这有效,但我觉得必须有更好的方法。
我已经尝试创建一个带ControllerAdvice
注释的类,但它没有被 POST 调用以通过 Spring Security 登录。我想这是因为 POST 是由 Spring Security 过滤器处理的,它是 Servlet 过滤器,位于主要的 Spring MVC 调度程序 servlet 之上。
我还尝试创建 aSimpleMappingExceptionResolver
来处理 aCommunicationException
并重定向到登录页面,但这也不起作用,因为我的SimpleMappingExceptionResolver
也没有被调用。
我想出的另一种解决方法是在错误页面本身解决异常,例如(使用 Thymeleaf)
<div class="container error" th:switch="${exception}">
<span th:case="'org.springframework.ldap.CommunicationException'">Error communicating with User Directory. Please try again in a few minutes</span>
<span th:case="*">An unexpected error has occurred</span>
</div>
Run Code Online (Sandbox Code Playgroud)
我仍然觉得应该有更好的方法。如何配置 DispatcherServlet 以确保将 CommunicationException 重定向到 /login 控制器,而不是错误页面?或者更一般地说......我如何配置登录阶段的任何异常显示在登录屏幕上?
小智 0
遇到了同样的问题并通过创建自定义 Spring AuthenticationFailureHandler解决了它。它通过在自定义AuthenticationProvider类中抛出 BadCredentialsException 来捕获错误 。
归档时间: |
|
查看次数: |
1658 次 |
最近记录: |