AbstractAuthenticationProcessingFilter 源码解析

AbstractAuthenticationProcessingFilter 是处理 form 登陆的过滤器,与 form 登陆有关的所有操作都是在该类及其子类中进行的。

继承关系

public abstract class AbstractAuthenticationProcessingFilter extends GenericFilterBean
        implements ApplicationEventPublisherAware, MessageSourceAware {

AbstractAuthenticationProcessingFilter 继承自 GenericFilterBean,而 GenericFilterBeanspring 框架中的过滤器类,实现了接口 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/> 的实现类。
  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;

可见该方法是个等待子类实现的虚拟方法,对于用户帐号密码的校验在该方法中进行。

  • 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 的实现变量。

AbstractAuthenticationProcessingFilter处理请求流程.png

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,859评论 18 139
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,351评论 11 349
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,977评论 25 708
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,935评论 6 342
  • 秋天我们的胃口也是变得很好,这时候许多人又在愁吃了太多的东西会发胖,其实不是所有的食物都是会让你发胖的,也有许多既...
    健康订阅阅读 221评论 0 0