Spring Security 认证异常处理
Posted
技术标签:
【中文标题】Spring Security 认证异常处理【英文标题】:Spring security authenticate exceptions handling 【发布时间】:2012-09-25 17:14:02 【问题描述】:我有一个使用 Spring Security 3.0.x 的应用程序。我有一个自定义的AuthenticationProvider
:
public class AppAuthenticationProvider implements AuthenticationProvider
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException
...
if (!check1()) throw new UsernameNotFoundException();
if (!check2()) throw new DisabledException();
...
我想针对每个异常发送自定义响应代码,例如 UsernameNotFoundException 的 404、DisabledException 的 403 等。现在我的 spring 安全配置中只有 authentication-failure-url,所以我在每个异常上都重定向到它authenticate() 中的异常。
【问题讨论】:
【参考方案1】:提供有关身份验证失败原因的详细信息通常不是一个好主意,因为它可以为攻击者提供有用的信息。例如,它可以让他们探测有效的帐户名称。
如果您需要自定义事物,那么您可以使用authentication-failure-handler-ref
注入自定义AuthenticationFailureHandler
bean,而不是使用authentication-failure-url
,您可以在其中根据异常实现不同的行为。
【讨论】:
如何将信息从AuthenticationFailureHandler传递给控制器方法?【参考方案2】:身份验证失败处理程序:
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler
@Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException
super.onAuthenticationFailure(request, response, exception);
if(exception.getClass().isAssignableFrom(UsernameNotFoundException.class))
showMessage("BAD_CREDENTIAL");
else if (exception.getClass().isAssignableFrom(DisabledException.class))
showMessage("USER_DISABLED");
配置:
<bean id="customAuthenticationFailureHandler"
class="com.apackage.CustomAuthenticationFailureHandler">
<property name="defaultFailureUrl" value="/index.jsp"/>
</bean>
<security:http auto-config="true">
<security:form-login default-target-url="/welcome.jsp" authentication-failure-handler-ref="customAuthenticationFailureHandler" />
</security:http>
【讨论】:
我在 SimpleUrlAuthenticationFailureHandler 类中没有找到 showMessage() 方法(我使用的是 Spring Security 版本 3.1.x)。你知道你用的是哪个版本吗? 抱歉,showMessage 方法是针对我的实现的,并非来自 spring。原始代码太多,无法显示。 @baraber 如何将异常类型传递给控制器方法? @g*** 控制器方法?我的示例中没有控制器,对不起,我不明白这个问题:(【参考方案3】:在 jsp 页面中使用以下标签进行自定义身份验证。
<c:if test="$sessionScope[\"SPRING_SECURITY_LAST_EXCEPTION\"].message eq 'Bad credentials'">
Username/Password entered is incorrect.
</c:if>
<c:if test="$sessionScope[\"SPRING_SECURITY_LAST_EXCEPTION\"].message eq 'User is disabled'">
Your account is disabled, please contact administrator.
</c:if>
<c:if test="$fn:containsIgnoreCase(sessionScope[\"SPRING_SECURITY_LAST_EXCEPTION\"].message,'A communications error has been detected')">
Database connection is down, try after sometime.
</c:if>
还包括以下标签库以正常工作
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib uri="http://www.springframework.org/security/tags" prefix="sec"%>
...
【讨论】:
以上是关于Spring Security 认证异常处理的主要内容,如果未能解决你的问题,请参考以下文章
spring security oauth2 认证端异常处理(基于前后分离统一返回json)
Spring security 3.1如何处理不同的认证异常?
Spring Security入门(3-4)Spring Security 异常处理异常传递和异常获取