spring security 源码分析

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】

表单登录

UsernamePasswordAuthenticationFilter

/login Post 请求

会被这个过滤器拦截

20191102100632\_1.png

如果为/login时 会经过

    if (!this.requiresAuthentication(request, response))

判断是否和设置的loginProcessingUrl一致

20191102100632\_2.png

20191102100632\_3.png

此时 由相应的AuthenticationProvider(这里是DaoAuthenticationProvider)匹配Authentication,如果support()

可以自定义provider给ProviderManager:

在webconfig中重写

         @Override
         protected AuthenticationManager authenticationManager() throws Exception {
             ProviderManager authenticationManager = new   ProviderManager(Arrays.asList(inMemoryAuthenticationProvider,daoAuthenticationProvider()));
             //不擦除认证密码,擦除会导致TokenBasedRememberMeServices因为找不到Credentials再调用UserDetailsService而抛出       UsernameNotFoundException
             authenticationManager.setEraseCredentialsAfterAuthentication(false);
             return authenticationManager;
         }

20191102100632\_4.png

20191102100632\_5.png

AbstractUserDetailsAuthenticationProvider 内置了缓存机制,从缓存中获取不到的 UserDetails 信息的话,就调用如下方法获取用户信息,然后和 用户传来的信息进行对比来判断是否验证成功。

验证:provider.authenticate(authentication),进入retrieveUser()

20191102100632\_6.png

开始调用

    UserDetailsService().loadUserByUsername(username);

根据username查出整个user

和之前的authentication

    调用 this.additionalAuthenticationChecks(user, (UsernamePasswordAuthenticationToken)authentication);

验证成功后

20191102100632\_7.png

然后通过

    this.getRedirectStrategy().sendRedirect(request, response, targetUrl);

重定向,故在此进入filter

20191102100632\_8.png

整个最基本的流程图:

20191102100632\_9.png

spring security 加密 ,这里使用

    BCryptPasswordEncoder

BCryptPasswordEncoder 使用BCrypt的强散列哈希加密实现,并可以由客户端指定加密的强度strength,强度越高安全性自然就越高,默认为10.

特点:每一次hash都自动生成不同的盐,并将盐值放在hash值中

20191102100632\_10.png

security 核心——-过滤器链

  • SecurityContextPersistenceFilter: 整个Spring Security 过滤器链的开端,它有两个作用:一是当请求到来时,检查Session中是否存在SecurityContext,如果不存在,就创建一个新的SecurityContext。二是请求结束时将SecurityContext放入 Session中,并清空 SecurityContextHolder
  • UsernamePasswordAuthenticationFilter: 继承自抽象类 AbstractAuthenticationProcessingFilter,当进行表单登录时,该Filter将用户名和密码封装成一个 UsernamePasswordAuthentication进行验证。
  • AnonymousAuthenticationFilter: 匿名身份过滤器,当前面的Filter认证后依然没有用户信息时,该Filter会生成一个匿名身份——AnonymousAuthenticationToken。一般的作用是用于匿名登录。
  • ExceptionTranslationFilter: 异常转换过滤器,用于处理 FilterSecurityInterceptor抛出的异常。
  • FilterSecurityInterceptor: 过滤器链最后的关卡,从 SecurityContextHolder中获取 Authentication,比对用户拥有的权限和所访问资源需要的权限。

20191102100632\_11.png

SecurityContextPersistenceFilter

请求先经过 SecurityContextPersistenceFilter 过滤器,在前面就曾提到,该Filter有两个作用,其中之一就是在请求到来时,创建 SecurityContext安全上下文,我们来看看它内部是如何做的,部分源码如下:

20191102100632\_12.png

我们这里是第一次请求,读取的安全上下文中是没有 Authentication身份信息的,将安全上下文设置到 SecurityContextHolder之后,进入下一个过滤器。

UsernamePasswordAuthenticationFilter

经过 SecurityContextPersistenceFilter过滤器后来到 UsernamePasswordAuthenticationFilter过滤器,因为我们假定的是第一次请求,所以 SecurityContext并没有包含认证过的 Authentication从此过滤器开始的操作对于表单登录来说是非常关键的,包含了表单登录的核心认证步骤

UsernamePasswordAuthenticationFilter 的父类是 AbstractAuthenticationProcessingFilter,首先进入父类的 foFilter方法

20191102100632\_13.png

具体都在跟上面说的一样

AnonymousAuthenticationFilter

匿名认证过滤器,它主要是针对匿名登录,如果前面的Filter,比如UsernamePasswordAuthenticationFilter执行完毕后,SecurityContext依旧没有用户信息,那么AnonymousAuthenticationFilter才会起作用,生成一个匿名身份信息——AnonymousAuthenticationToken

20191102100632\_14.png

ExceptionTranslationFilter

ExceptionTranslationFilter 简单的说就是处理 FilterSecurityInterceptor 抛出的异常,其内部doFilter方法源码如下:

20191102100632\_15.png

FilterSecurityInterceptor

FilterSecurityInterceptor 过滤器是最后的关卡,之前的请求最终会来到这里,它的大致工作流程就是

  • 封装请求信息
  • 从系统中读取配信息,即资源所需的权限信息
  • SecurityContextHolder中获取之前认证过的 Authentication对象,即表示当前用户所拥有的权限
  • 然后根据上面获取到的三种信息,传入一个权限校验器中,对于当前请求来说,比对用户拥有的权限和资源所需的权限。若比对成功,则进入真正系统的请求处理逻辑,反之,会抛出相应的异常

20191102100632\_16.png

使用第三方登录(github登录)

加入过滤器

    IntegrationAuthenticationFilter(自己写的)

当符合/oauth/github时,不执行chain.doFileter,直接重定向

下面是spring security的源码 也是类似的处理方式

20191102100632\_17.png


来源:http://ddrv.cn

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » spring security 源码分析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏