链接: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