Spring Security源码分析二:Spring Security授权过程

前言

本文是接上一章Spring Security源码分析一:Spring Security认证过程进一步分析Spring Security用户名密码登录授权是如何实现得;

类图

http://dandandeshangni.oss-cn-beijing.aliyuncs.com/github/Spring%20Security/security-authentication-Diagram.png

调试过程

使用debug方式启动https://github.com/longfeizheng/logback该项目,浏览器输入http://localhost:8080/persons,用户名随意,密码123456即可;

源码分析

如图所示,显示了登录认证过程中的 filters 相关的调用流程,作者将几个自认为重要的 filters 标注了出来,

http://dandandeshangni.oss-cn-beijing.aliyuncs.com/github/Spring%20Security/security-filers.png

从图中可以看出执行的顺序。来看看几个作者认为比较重要的 Filter 的处理逻辑,UsernamePasswordAuthenticationFilterAnonymousAuthenticationFilterExceptionTranslationFilterFilterSecurityInterceptor 以及相关的处理流程如下所述;

UsernamePasswordAuthenticationFilter

整个调用流程是,先调用其父类 AbstractAuthenticationProcessingFilter.doFilter() 方法,然后再执行 UsernamePasswordAuthenticationFilter.attemptAuthentication() 方法进行验证;

AbstractAuthenticationProcessingFilter

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

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        #1.判断当前的filter是否可以处理当前请求,不可以的话则交给下一个filter处理
        if (!requiresAuthentication(request, response)) {
            chain.doFilter(request, response);

            return;
        }

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

        Authentication authResult;

        try {
            #2.抽象方法由子类UsernamePasswordAuthenticationFilter实现
            authResult = attemptAuthentication(request, response);
            if (authResult == null) {
                // return immediately as subclass has indicated that it hasn't completed
                // authentication
                return;
            }
            #2.认证成功后,处理一些与session相关的方法 
            sessionStrategy.onAuthentication(authResult, request, response);
        }
        catch (InternalAuthenticationServiceException failed) {
            logger.error(
                    "An internal error occurred while trying to authenticate the user.",
                    failed);
            #3.认证失败后的的一些操作
            unsuccessfulAuthentication(request, response, failed);

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

            return;
        }

        // Authentication success
        if (continueChainBeforeSuccessfulAuthentication) {
            chain.doFilter(request, response);
        }
        #3. 认证成功后的相关回调方法 主要将当前的认证放到SecurityContextHolder中
        successfulAuthentication(request, response, chain, authResult);
    }

整个程序的执行流程如下:
1. 判断filter是否可以处理当前的请求,如果不可以则放行交给下一个filter
2. 调用抽象方法attemptAuthentication进行验证,该方法由子类UsernamePasswordAuthenticationFilter实现
3. 认证成功以后,回调一些与 session 相关的方法;
4. 认证成功以后,认证成功后的相关回调方法;认证成功以后,认证成功后的相关回调方法ÿ

  • 7
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值