上一篇文章中我们讲了Spring Security个性用户认证流程。这一节我们简单讲一讲SpringSecurity的认证流程。我们先看一个流程图:
按照我们之前的配置,我们来讲解整个流程
1.UsernamePasswordAuthenticationFilter
UsernamePasswordAuthenticationFilter进入UsernamePasswordAuthenticationFilter的方法中,第二个红色方框中的username和password是前端传递的用户名和密码。然后包装为UsernamePasswordAuthenticationToken,这个类实现了Authentication接口!
包装完成之后调用getAuthenticationManager().authenticate(authRequest)。
AuthenticationManager有很多实现类,其中一个就是ProvideManager。
2.ProvideManager
2.1选择provider
ProvideManagerProvideManager负责管理AuthenticationProvider,我们可以看到图中有很多的providers,可以有SocialAuthenticationProvider(第三方接入的时候专用),AbstractUserDetailsAuthenticationProvider(我们配置的时候用到的)等等。其实真正执行的只有一个provider,那么究竟会选择哪一个provider,我们看到有一个supports方法。也就是根据上一步中的authentication的类型来做判断。
2.2调用provider的authenticate方法
2.2.1获取用户信息
这里的关键方法就是调用我们自己实现的UserDetailsService类的方法先把用户获取到。
2.2.2检查获取到的用户信息
是不是很眼熟,对的,就是根据我们返回的UserDetails中的信息做一个检查--是否过期等等。。。
2.2.3验证密码是否正确
2.2.4验证密码是否过期
2.2.5创建UsernamePasswordAuthenticationToken表示认证成功
3.SecurityContextPersistenceFilter
那么我们把用户信息认证完了后,其他请求是如何共享这一次登录验证的呢?这个就是靠SecurityContext上下文来完成这项工作的。用户认证完成之后会把UsernamePasswordAuthenticationToken存入到Context中,而Context会存储到session当中去,这样,下一次请求过来的时候,就不用让用户在登录了。那么是谁把认证信息放到Context里面去的呢?答案就是SecurityContextPersistenceFilter,这个Filter处于所有Filter的最前端位置:
我们会看到在Filter的最后,一定会把context存入到session中,这样如果用户已经登录过一次,session中可以拿到Context,context中就可以拿到UsernamePasswordAuthenticationToken如下图所示
网友评论