如何处理Spring Security身份验证提供程序抛出的运行时异常?我使用的是Spring Boot 1.4.2,但我觉得这也适用于经典的Spring应用程序。
我们说我已经配置了<system.serviceModel>
<services>
<service behaviorConfiguration="Default" name="BlogService.Service1">
<endpoint address="" behaviorConfiguration="webBehavior" binding="webHttpBinding" contract="BlogService.IService1" bindingConfiguration="WHB" />
<host>
<baseAddresses>
<add baseAddress="http://localhost:60500/Service1.svc" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp defaultOutgoingResponseFormat="Json" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
<behavior name="Default">
<serviceMetadata httpGetEnabled="true"/>
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="WHB" crossDomainScriptAccessEnabled="true">
<security mode="None" />
</binding>
</webHttpBinding>
</bindings>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true"/>
</system.serviceModel>
来根据我的公司AD对用户进行身份验证。当身份验证因验证失败而导致身份验证失败时,这一切都适用于Spring Security(抛出ActiveDirectoryLdapAuthenticationProvider
,由Spring Security机制正确处理=应用程序返回登录屏幕并显示身份验证错误)
然而有时,AD会暂时停止并且会引发AuthenticationException
。此异常是运行时异常,因此不受Spring安全机制的限制,因为它不会扩展org.springframework.ldap.CommunicationException
。
在这种情况下会发生的是,应用程序被重定向到默认错误页面(这是/错误)。我想要做的是仍然显示带有自定义消息的登录屏幕。
如果我创建类似
的内容,我发现我可以这样做AuthenticationException
这有效,但我觉得必须有更好的方法。
我已尝试创建一个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;
}
带注释的类,但它不会被POST调用以由Spring Security登录。我想这是因为POST是由Spring安全过滤器处理的,它是Servlet过滤器,位于主要的Spring MVC调度程序servlet之上。
我还尝试创建一个ControllerAdvice
来处理SimpleMappingExceptionResolver
并重定向到登录页面,但这并不是因为我的CommunicationException
没有&也可以被召唤。
我提出的其他解决方法是在错误页面本身处理异常,例如(使用Thymeleaf)
SimpleMappingExceptionResolver
我仍然觉得应该有更好的方法。如何配置DispatcherServlet以确保将CommunicationException重定向到/ login控制器,而不是错误页面?或者更一般地说......如何在登录阶段配置登录阶段的任何异常?
答案 0 :(得分:0)
遇到了相同的问题,并通过创建自定义Spring AuthenticationFailureHandler解决了该问题。它通过在自定义AuthenticationProvider类中抛出BadCredentialsException来捕获错误。