[英]How to handle run time exceptions thrown by Spring Security AuthenticationProviders?
How to handle runtime exceptions thrown by Spring Security Authentication Providers ? 如何处理Spring Security Authentication Providers抛出的运行时异常? I'm using Spring Boot 1.4.2 but I feel like this applies also to classic Spring applications. 我正在使用Spring Boot 1.4.2,但我觉得这也适用于经典的Spring应用程序。
Let's say I have an ActiveDirectoryLdapAuthenticationProvider
configured to authenticate users against my corporate AD. 假设我有一个ActiveDirectoryLdapAuthenticationProvider
配置为根据我的公司AD对用户进行身份验证。 It all works nice with Spring Security when the authentication fails due to bad credentials (an AuthenticationException
is thrown which is properly handled by the Spring Security mechanism = the app goes back to the login screen and the authentication error can be shown). 当身份验证因验证失败而导致身份验证失败时,这一切都适用于Spring Security(抛出AuthenticationException
,由Spring安全机制正确处理=应用程序返回登录屏幕并显示身份验证错误)。
However it so happens that sometimes, the AD is down temporarily and a org.springframework.ldap.CommunicationException
is thrown instead. 但是,有时候,AD会暂时关闭,而是抛出org.springframework.ldap.CommunicationException
。 This exception is a runtime exception and therefore isn't trapped by Spring's security mechanism because it doesn't extend AuthenticationException
. 此异常是运行时异常,因此不会被Spring的安全机制捕获,因为它不会扩展AuthenticationException
。
What happens in this case, is that the app is redirected to the default error page (which is /error). 在这种情况下会发生的是,应用程序被重定向到默认错误页面(这是/错误)。 What I want to do, is to still show the login screen with a custom message. 我想要做的是仍然显示带有自定义消息的登录屏幕。
I've found that I can do that, if I create something like 如果我创造了类似的东西,我发现我可以做到这一点
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;
}
This works but I feel that there must be a better way. 这有效,但我觉得必须有更好的方法。
I've tried creating a ControllerAdvice
annotated class but it doesn't get called by the POST to login by Spring Security. 我已经尝试创建一个ControllerAdvice
注释类,但它不会被POST调用以由Spring Security登录。 I would imagine that it's because POST is handled by Spring Security filters, which being Servlet filters, sit above the main Spring MVC dispatcher servlet. 我想这是因为POST是由Spring安全过滤器处理的,它是Servlet过滤器,位于主要的Spring MVC调度程序servlet之上。
I've also tried to create a SimpleMappingExceptionResolver
to handle a CommunicationException
and redirect to the login page, but that doesn't work either as my SimpleMappingExceptionResolver
doesn't get called either. 我还尝试创建一个SimpleMappingExceptionResolver
来处理CommunicationException
并重定向到登录页面,但这也不起作用,因为我的SimpleMappingExceptionResolver
也没有被调用。
The other workaround that I've come up with is to tackle the exception at the error page itself, something like (using Thymeleaf) 我提出的另一个解决方法是在错误页面本身处理异常,例如(使用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>
I still feel like there should be a better way. 我仍然觉得应该有更好的方法。 How can I configure the DispatcherServlet to ensure that a CommunicationException is to be redirected to the /login controller, and not the error page ? 如何配置DispatcherServlet以确保将CommunicationException重定向到/ login控制器,而不是错误页面? Or more generically... how can I configure that any exception at the login stage, is shown on the login screen ? 或者更一般地说......如何在登录阶段显示登录阶段的任何异常?
Experienced same problem and solved it creating custom Spring AuthenticationFailureHandler . 经验丰富的相同问题并解决了它创建自定义Spring AuthenticationFailureHandler 。 It caught error by throwing BadCredentialsException in custom AuthenticationProvider class. 它通过在自定义AuthenticationProvider类中抛出BadCredentialsException来捕获错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.