细看spring security单点登陆源码的验证过程


分析得比较好的文章:

http://blog.csdn.net/java_mr_zheng/article/details/52385071    

https://www.cnblogs.com/drizzlewithwind/p/6196080.html







1.form表单请求被UsernamePasswordAuthenticationFilter拦截,先判断请求(请求必须是post请求)地址是否为/j_spring_security_check,如果不是,
则放行,进入下一个过滤器,是则进行校验。
UsernamePasswordAuthenticationFilter继承了AbstractAuthenticationProcessingFilter,form表单请求进来会被
父类的doFilter拦截,doFilter调用UsernamePasswordAuthenticationFilter中的attemptAuthentication方法。
可以用一个类来继承UsernamePasswordAuthenticationFilter,自然就可以继承或者重写父类方法doFilter和attemptAuthentication。
方法attemptAuthentication通过UsernamePasswordAuthenticationToken初始化一些参数(authorities,principal,credentials,authenticated(false)),
构造出一个构造未认证的UsernamePasswordAuthenticationToken
对象。




2.然后通过调用AuthenticationManager(AuthenticationManager的默认实现是ProviderManager)接口实现类ProviderManager的authenticate方法。
        AuthenticationManager说明:顾名思义就是认证管理器,把需要认证的东西分配下去
        管理使用什么AuthenticationProvider验证用户的合法性,AuthenticationManager默认实现类出除了实现方法authenticate还拥有2个自己重要的参数类:
        List providers; AuthenticationProvider(接口,认证实现者)的集合,AuthenticationProvider接口如果没有指定默认DaoAuthenticationProvider实现。
        AuthenticationManager parent。


          AuthenticationProvider的作用:可以处理一个特定的Authentication,实现身份验证。它有2个方法
         Authentication authenticate(Authentication authentication) throws AuthenticationException;(根据authentication信息实现身份验证)
         boolean supports(Class authentication); 用于判断该AnonymousAuthenticationProvider能够验证某种类型的Authentication。


         AuthenticationManager实现类的方法中会调用AuthenticationProvider实现类的authenticate来验证一个Authentication。
         如果该providers中如果有一个AuthenticationProvider的supports函数返回true,那么就会调用该AuthenticationProvider的authenticate函数认证,如果认证成功则整个认证过程结束。
         如果不成功,则继续使用下一个合适的AuthenticationProvider进行认证,只要有一个认证成功则为认证成功。


          默认方式中DaoAuthenticationProvider中会调用从父类AbstractUserDetailsAuthenticationProvider继承的authenticate方法方法来验证Authentication,
          authenticate方法中调用retrieveUser来调用UserDetailsService实现类中loadUserByUsername方法来获取一个loadedUser。我们可以定义一个类来实现UserDetailsService接口。
          随后调用check方法来检验账号状态,然后调用additionalAuthenticationChecks方法来进行密码验证,最后完成了单点登陆的简单验证。


         如果上述过程没有认证成功,且该ProviderManager的成员变量AuthenticationManager parent不为null,那么会使用该parent继续认证。一般不会用到该AuthenticationManager parent,稍微留意以下即可。


         随后回到最开始的doFilter中,如果成功则调用successfulAuthentication方法去调用SavedRequestAwareAuthenticationSuccessHandler方法onAuthenticationSuccess
        失败调用unsuccessfulAuthentication方法去调用onAuthenticationFailure方法去掉调用SimpleUrlAuthenticationFailureHandler中的onAuthenticationFailure。
        
        
说明:  Authentication(AnonymousAuthenticationToken,UsernamePasswordAuthenticationToken等实现类)可以拥有多种类型,
        不同的类型使用不同的AuthenticationProvider(DaoAuthenticationProvider,AnonymousAuthenticationProvider等实现类)。
        比如DaoAuthenticationProvider支持使用UsernamePasswordAuthenticationToken,AnonymousAuthenticationProvider支持AnonymousAuthenticationToken等。


       
        






       













你可能感兴趣的:(java)