SpringSecurity授权流程源码解析

上篇文章分析了SpringSecurity基于用户名和密码的认证过程,这篇分析下授权流程;授权主要处理权限问题,比如说用户没有登录,如果直接请求某一个需要权限的接口,处理的过程是怎样的;

1>.DelegatingFilterProxy 的doFilter方法

这个是认证的过滤入口,最终调用的是FilterChainProxy的doFilter方法

2>.FilterChainProxy的doFilter

过滤链涉及了14个filter,如图所示

SpringSecurity授权流程源码解析_第1张图片

重要的如图所示,下面一个一个来分析;

3>SecurityContextPersistenceFilter的doFilter

先进行处理的是SecurityContextPersistenceFilter过滤器,关键代码如下所示

SpringSecurity授权流程源码解析_第2张图片

这里通过repo.loadContext从请求中获取session,然后将session信息保存在context中,方便接下来的filter直接获取当前的用户信息;如下图所示

SpringSecurity授权流程源码解析_第3张图片

readSecurityContextFromSession方法具体实现如下,其实就是从session中获取context信息;

SpringSecurity授权流程源码解析_第4张图片
之后返回到SecurityContextPersistenceFilter中,通过SecurityContextHolder.setContext(contextBeforeChainExecution);

SpringSecurity授权流程源码解析_第5张图片

设置context信息到contextHolder中;如下所示,可见是将context信息放在了ThreadLocal中,线程安全的;

SpringSecurity授权流程源码解析_第6张图片

SecurityContextPersistenceFilter的处理流程就到这里;接下来FilterChainProxy的doFilter会调用下面的filter来处理;

4>ExceptionTranslationFilter的doFilter方法

源码如图所示

SpringSecurity授权流程源码解析_第7张图片

这里会继续交给下面的Filter去处理,但是会捕获Filter处理的异常

5>FilterSecurityInterceptor的doFilter方法

这里调用invoke方法来处理,代码如下:

SpringSecurity授权流程源码解析_第8张图片

super.beforeInvocation(fi)调用父类AbstractSecurityInterceptor的beforeInvocation,代码如下所示

SpringSecurity授权流程源码解析_第9张图片

这里authenticateIfRequired会从上下文中取出context信息,代码如下所示,如果没有认证,则重新认证后存储认证信息;

SpringSecurity授权流程源码解析_第10张图片

认证之后调用this.accessDecisionManager.decide(authenticated, object, attributes);来判断当前的请求是否是合法的,具体调用是AffirmativeBased的decide方法,如下所示

SpringSecurity授权流程源码解析_第11张图片

这里通过投票来决定是否通过认证,具体可以继续往下断点,最终就是通过el表达式来判断当前的路径是否有权限访问;deny>0抛出AccessDeniedException异常,之后会被上面提到的ExceptionTranslationFilter捕获到,返回未授权异常信息;

 

你可能感兴趣的:(springboot,源码解析)