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 异常处理机制!

Spring security 3.1如何处理不同的认证异常?

Spring Security入门(3-4)Spring Security 异常处理异常传递和异常获取

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常

Spring boot 前后台分离项目 怎么处理spring security 抛出的异常