• Security源码学习


    链接:https://www.bilibili.com/video/BV1gU4y117qx

    第一节

    主要讲解了SpringSecurity的顶层脉络以及几个核心的类:

    • SecurityBuilder —— 构建一个对象
    • HttpSecurity —— 属于SecurityBuilder,用来构建SecurityFilterChain
    • WebSecurity —— 属于SecurityBuilder,用来构建Filter(FilterChainProxy)
    • SecurityFilterChain —— 维护了许多的Filter
    • FilterChainProxy —— WebSecurity构建的Filter对象
      SpringSecurity进入流程:
      FilterChainProxy -> 根据请求决定一个 SecurityFilterChain -> 执行SecurityFilterChain中的一系列过滤器

    第二节

    主要讲解下面三个类:

    • HttpSecurity 内幕 —— 属于SecurityBuilder,最终构建为SecurityFilterChain,维护了RequestMatcher请求匹配器来匹配请求,以及一组Filter,当请求匹配器匹配到请求后,由该组Filter处理这个请求
    • SecurityConfigurer —— 用来配置SecurityBuilder,而一个SecurityBuilder中会维护一系列的SecurityConfigurer,它们再SecurityBuilder构建目标对象的过程中,完成对目标对象的配置
    • AbstractConfiguredSecurityBuilder —— 维护了一堆的SecurityConfigurer配置器,sharedObjects共享对象(key为Class类型),和一个ObjectPostProcessor对象后置处理器(它除了SecurityBuilder本身可以调用这个后置处理器的后置处理方法;这个对象还会在apply(应用,即添加)具体的SecurityConfiguerr配置器时,被添加到SecurityConfigurerAdapter配置适配器中,由该配置适配器对对象作后置处理)
      在实际的doBuild过程中,
      (状态:默认BuildState.UNBUILT未构建)
      ——> beforeInit() ——> init() 回调SecurityConfigurer#init(),并且中途可以添加SecurityConfigurer,但不可二次添加 ——>
      (状态:默认BuildState.CONFIGURING配置中)
      ——>beforeConfigure()——>configure() 回调SecurityConfigurer#configure()来往这个Builder中添加过滤器——>
      (状态:默认BuildState.BUILDING构建中)
      ——>performBuild() 真正的build()要构建最终的目标对象了——>
      (状态:默认BuildState.BUILT构建完成)

    SecurityBuilder用来构建安全对象,安全对象包括:HttpSecurity、FilterChainProxy、AuthenticationManager
    SecurityConfigurer用来配置安全对象构建器(SecurityBuilder),典型的有:FormLoginConfigurer、CsrfConfigurer等

    第三节

    主要讲解下面四个类:

    • Authentication —— 认证主体对象,当发起认证请求时,传入Authentication对象(比如里面的credentials属性可以是密码组成,也可能是小程序的code码,是个抽象概念、比如里面的principal属性可以是用户名或者任何能代表当前认证请求对象的数据),交给认证管理器去对该对象做认证,如果认证通过,会返回一个填充好属性(比如授权信息、是否已认证)的认证主体对象回来
    • AuthenticationManager —— 认证管理器,传入一个Authentication对象,对该认证对象认证成功后,返回一个Authentication对象,如果认证不成功,应当要抛出异常
    • AuthenticationManagerBuilder —— 属于SecurityBuilder,和HttpSecurity、WebSecurity一样,都可以添加SecurityConfigurer配置器,最终是为了构建出ProviderManager对象(这个对象实现了AuthenticationManager接口)
    • ProviderManager—— 它里面维护了一组的AuthenticationProvider和一个父AuthenticationManager(security中的默认实现也是一个ProviderManager),并且它是AuthenticationManagerBuilder最终要构建出来的对象
    • AuthenticationProvider—— 能够判断是否支持当前的Authentication,来决定是否使用该认证提供器对当前的Authentication作认证,属性典型的策略模式,与SpringMvc的处理器适配器处理类似

    Authentication存放认证信息,它需要被AuthenticationManager来认证,而AuthenticationManager管理着一堆的AuthenticationProvider
    实际真正干活的就是AuthenticationProvider;ProviderManager是AuthenticationManager的主要实现。

    第四节

    主要讲解下面五个类:

    • UserDetailsService
      • 能根据用户名获取UserDetails(它里面包含用户名、密码、授权、账号禁用/锁定/过期等 属性),它本身并没有实现Authentication接口,但是它包含的东西又正是Authentication所需要的,所以它返回的UserDetails由它的调用者决定如何使用。如果根据用户名找不到用户,建议抛出UsernameNotFoundException。
    • DaoAuthenticationProvider
      • 作为上节中的AuthenticationProvider的一种实现,它委托给了UserDetailsService去实现返回UserDetails,而它就抽取返回的UserDetails中的授权、密码、用户名等封装成UsernamePasswordAuthenticationToken作为Authentication返回。同时这个类也是作为AbstractUserDetailsAuthenticationProvider抽象类的实现。
    • AbstractUserDetailsAuthenticationProvider
      • 仅支持UsernamePasswordAuthenticationToken类型的Authentication对象的认证,并且委托给子类根据用户名查询UserDetails,校验子类返回的UserDetails用户是否被锁定、禁用、过期,然后使用PasswordEncoder校验认证请求提交的密码是否正确,如果校验成功,则将此UserDetails封装成UsernamePasswordAuthenticationToken作为Authentication返回
    • UsernamePasswordAuthenticationFilter
      • 它继承自抽象AbstractAuthenticationProcessingFilter类,这个抽象类判断当前过滤器是否需要对当前请求进行认证,如果需要认证,则把认证的工作交给UsernamePasswordAuthenticationFilter去做,并且如果认证成功作一些工作(比如设置Authentication到SecurityContext上下文中),或者认证失败做一些工作。
      • 获取认证请求提交的用户名和密码,将它们封装成UsernamePasswordAuthenticationToken对象,交给authenticationManager属性(其实就是ProviderManager)进行认证
    • FormLoginConfigurer
      • 用来配置UsernamePassowrdAuthenticationFilter,当HttpSecurity应用(apply)此配置器时,这个配置器在它的configure(B)方法被回调时,将会把配置好的这个过滤器添加给HttpSecurity,最终HttpSecurity构建SecurityFilterChain时,就会把这个过滤器添加到这个SecurityFilterChain中

    用户名密码登录的真谛就是DaoAuthenticationProvider

    - WebSecurityConfigurerAdapter
    
            - 子类
    	- 自定义WebSecurityConfigurerAdapter        security基本应用
    	- AuthorizationServerSecurityConfiguration  授权服务
    	- ResourceServerConfiguration                     资源服务
    	- OAuth2SsoDefaultConfiguration                单点登录
    
            - 作用
    	- setApplicationContext(由@Autowierd触发)
    	     	- 设置authenticationBuilder属性(创建DefaultPasswordEncoderAuthenticationManagerBuilder- 设置localConfigureAuthenticationBldr属性(创建DefaultPasswordEncoderAuthenticationManagerBuilder- setAuthenticationConfiguration(由@Autowierd触发)
    	     	- 设置authenticationConfiguration属性
    	
    	- init
    		- 获取HttpSecurity
    			- 确定 authenticationManager 是由 localConfigureAuthenticationBldr 创建,还是从 authenticationConfiguration 获取
    				- 将得到的 authenticationManager 设置到 authenticationBuilder 的 parentAuthenticationManager 属性中
    			- 获取 sharedObjects
    				- localConfigureAuthenticationBldr.getSharedObjects()
    				- UserDetailsService.class> userDetailsService()返回的UserDetailsServiceDelegator
    					- 优先获取localConfigureAuthenticationBldr的defaultUserDetailsService属性,如果为null,走其次
    					- 其次从容器中获取 AuthenticationManagerBuilder 的bean的defaultUserDetailsService属性
    					- 该方法可被子类重写
    				- ApplicationContext.class> applicationContext上下文
    				- 从容器中获取的 ContentNegotiationStrategy
    				- 从容器中获取的 AuthenticationTrustResolver
    			- 创建httpSecurity
    				- 传入objectPostProcessor,authenticationBuilder,sharedObjects,并将 authenticationBuilder 也放入 sharedObjects
    				- 对httpSecurity做默认配置(可关闭)
    				- 给子类一个机会去继续配置httpSecurity(configure(httpSecurity)-HttpSecurity作为SecurityBuilder(用来创建SecurityFilterChain),添加到WebSecurity的securityFilterChainBuilders属性中
    	- configure
    		- 默认空实现
    
    - WebSecurityConfiguration
    
             - setFilterChainProxySecurityConfigurer()(由@Autowierd触发)
             	- 使用AutowiredWebSecurityConfigurersIgnoreParents注入容器中所有的WebSecurityConfigurer,并对它们排序
             	- new了一个WebSecurity,应用(即添加)这些WebSecurityConfigurer
    
             - springSecurityFilterChain()(由@Bean触发)
    	- 如果容器中一个WebSecurityConfigurer都没有,就会创建一个WebSecurityConfigurer,来保证至少有一个
    	- 触发WebSecurity#build(),来构建FilterChainProxy
             
    
    
             
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
  • 相关阅读:
    单例模式(饿汉式单例 VS 懒汉式单例)
    PGL图学习之图神经网络GNN模型GCN、GAT[系列六]
    前端开发(layuimini使用)
    阿里云网络
    装饰器模式
    烟雾、空气质量、温湿度…自己徒手做个环境检测设备
    ssh连接腾讯云服务器
    前端进击笔记第三节 CSS:页面布局的基本规则和方式
    PHP超级全局变量:功能、应用及最佳实践
    如何评价GPT-4o?
  • 原文地址:https://blog.csdn.net/qq_16992475/article/details/126372912