AbstractAuthenticationProcessingFilter 源碼解析

AbstractAuthenticationProcessingFilter 是處理 form 登陸的過濾器,與 form 登陸有關的所有操作都是在該類及其子類中進行的。

繼承關系

public abstract class AbstractAuthenticationProcessingFilter extends GenericFilterBean
        implements ApplicationEventPublisherAware, MessageSourceAware {

AbstractAuthenticationProcessingFilter 繼承自 GenericFilterBean,而 GenericFilterBeanspring 框架中的過濾器類,實現(xiàn)了接口 javax.servlet.Filter

成員變量

AbstractAuthenticationProcessingFilter 中的成員變量主要有以下

public abstract class AbstractAuthenticationProcessingFilter extends GenericFilterBean
        implements ApplicationEventPublisherAware, MessageSourceAware {
    // ~ Static fields/initializers
    // =====================================================================================

    // ~ Instance fields
    // ================================================================================================

    protected ApplicationEventPublisher eventPublisher;
    protected AuthenticationDetailsSource<HttpServletRequest, ?> authenticationDetailsSource = new WebAuthenticationDetailsSource();
    private AuthenticationManager authenticationManager;
    protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
    private RememberMeServices rememberMeServices = new NullRememberMeServices();

    private RequestMatcher requiresAuthenticationRequestMatcher;

    private boolean continueChainBeforeSuccessfulAuthentication = false;

    private SessionAuthenticationStrategy sessionStrategy = new NullAuthenticatedSessionStrategy();

    private boolean allowSessionCreation = true;

    private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
    private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();

其中有幾個比較重要的成員變量:

  1. authenticationManager 即為我們在 spring 配置文件中注冊的 <authentication-manager/> 的實現(xiàn)類。
  2. AuthenticationSuccessHandler 為授權成功處理類。
  3. AuthenticationFailureHandler 為授權失敗處理類。

流程分析

因為 AbstractAuthenticationProcessingFilter 為本質上是一個 servlet 過濾器,因此找到其入口函數 doFilter()

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        if (!requiresAuthentication(request, response)) {
            chain.doFilter(request, response);

            return;
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Request is to process authentication");
        }

        Authentication authResult;

        try {
--> 1       authResult = attemptAuthentication(request, response);
            if (authResult == null) {
                // return immediately as subclass has indicated that it hasn't completed
                // authentication
                return;
            }
            sessionStrategy.onAuthentication(authResult, request, response);
        }
        catch (InternalAuthenticationServiceException failed) {
            logger.error(
                    "An internal error occurred while trying to authenticate the user.",
                    failed);
--> 2       unsuccessfulAuthentication(request, response, failed);

            return;
        }
        catch (AuthenticationException failed) {
            // Authentication failed
--> 3      unsuccessfulAuthentication(request, response, failed);

            return;
        }

        // Authentication success
        if (continueChainBeforeSuccessfulAuthentication) {
            chain.doFilter(request, response);
        }

--> 4   successfulAuthentication(request, response, chain, authResult);
    }

其中:

  • try代碼快中的--> 1 處代碼表示該處會調用 attemptAuthentication()方法進行身份校驗處理。attemptAuthentication()方法本體如下所示:
public abstract Authentication attemptAuthentication(HttpServletRequest request,
            HttpServletResponse response) throws AuthenticationException, IOException,
            ServletException;

可見該方法是個等待子類實現(xiàn)的虛擬方法,對于用戶帳號密碼的校驗在該方法中進行。

  • catch 代碼塊中的 --> 2--> 3 處代碼表示身份校驗失敗之后調用方法 unsuccessfulAuthentication(),該方法本體如下所示:
protected void unsuccessfulAuthentication(HttpServletRequest request,
            HttpServletResponse response, AuthenticationException failed)
            throws IOException, ServletException {
        SecurityContextHolder.clearContext();

        if (logger.isDebugEnabled()) {
            logger.debug("Authentication request failed: " + failed.toString(), failed);
            logger.debug("Updated SecurityContextHolder to contain null Authentication");
            logger.debug("Delegating to authentication failure handler " + failureHandler);
        }

        rememberMeServices.loginFail(request, response);

        failureHandler.onAuthenticationFailure(request, response, failed);
    }

該方法中最重要的一條語句是failureHandler.onAuthenticationFailure(request, response, failed);,表明驗證身份信息失敗之后調用類 failureHandleronAuthenticationFailure() 方法。而 failureHandlerAuthenticationFailureHandler 的實例變量。

  • --> 4 處代碼表示驗證身份信息成功后,調用 successfulAuthentication() 方法,其方法本體如下:
    protected void successfulAuthentication(HttpServletRequest request,
            HttpServletResponse response, FilterChain chain, Authentication authResult)
            throws IOException, ServletException {

        if (logger.isDebugEnabled()) {
            logger.debug("Authentication success. Updating SecurityContextHolder to contain: "
                    + authResult);
        }

        SecurityContextHolder.getContext().setAuthentication(authResult);

        rememberMeServices.loginSuccess(request, response, authResult);

        // Fire event
        if (this.eventPublisher != null) {
            eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(
                    authResult, this.getClass()));
        }

        successHandler.onAuthenticationSuccess(request, response, authResult);
    }

其中,最重要的一行代碼是 successHandler.onAuthenticationSuccess(request, response, authResult);,表示身份驗證成功后調用 successHandleronAuthenticationSuccess 方法。而 successHandlerAuthenticationSuccessHandler 的實現(xiàn)變量。

AbstractAuthenticationProcessingFilter處理請求流程.png

參考

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,578評論 19 139
  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,811評論 11 349
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,094評論 25 709
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,275評論 6 342
  • 秋天我們的胃口也是變得很好,這時候許多人又在愁吃了太多的東西會發(fā)胖,其實不是所有的食物都是會讓你發(fā)胖的,也有許多既...
    健康訂閱閱讀 273評論 0 0

友情鏈接更多精彩內容