Spring Security的配置机制早就变了
2022-04-29 13:55:35

以前胖哥说过SecurityConfigurerAdapter会在即将发布的5.7版本作废,从Spring Security 5.4版本开始会提供一个原型范围的​​HttpSecurity​​​来帮助我们构建过滤器链​​SecurityFilterChain​​:

@Bean(HTTPSECURITY_BEAN_NAME)
@Scope("prototype")
HttpSecurity httpSecurity() throws Exception {
WebSecurityConfigurerAdapter.LazyPasswordEncoder passwordEncoder = new WebSecurityConfigurerAdapter.LazyPasswordEncoder(
this.context);
AuthenticationManagerBuilder authenticationBuilder = new WebSecurityConfigurerAdapter.DefaultPasswordEncoderAuthenticationManagerBuilder(
this.objectPostProcessor, passwordEncoder);
authenticationBuilder.parentAuthenticationManager(authenticationManager());
HttpSecurity http = new HttpSecurity(this.objectPostProcessor, authenticationBuilder, createSharedObjects());
// @formatter:off
http
.csrf(withDefaults())
.addFilter(new WebAsyncManagerIntegrationFilter())
.exceptionHandling(withDefaults())
.headers(withDefaults())
.sessionManagement(withDefaults())
.securityContext(withDefaults())
.requestCache(withDefaults())
.anonymous(withDefaults())
.servletApi(withDefaults())
.apply(new DefaultLoginPageConfigurer<>());
http.logout(withDefaults());
// @formatter:on
return http;
}

这里会构建基于原型的​​HttpSecurity​​Bean,并且初始化了一些默认配置供我们来使用。涉及Spring Security的日常开发都是围绕这个类进行的,所以这个类是学习Spring Security的重中之重。

基于原型(​​prototype​​)的Spring Bean的一个典型应用场景,


基本配置

日常我们使用的一些配置项如下:

方法

说明

requestMatchers()

为​​SecurityFilterChain​​​提供URL拦截策略,具体还提供了​​antMatcher​​​和​​mvcMathcer​

openidLogin()

用于基于 ​​OpenId​​ 的验证

headers()

将安全标头添加到响应,比如说简单的 XSS 保护

cors()

配置跨域资源共享( CORS )

sessionManagement()

配置会话管理

portMapper()

配置一个​​PortMapper(HttpSecurity#(getSharedObject(class)))​​​,其他提供​​SecurityConfigurer​​​的对象使用 ​​PortMapper​​​ 从 HTTP 重定向到 HTTPS 或者从 HTTPS 重定向到 HTTP。默认情况下,Spring Security使用一个​​PortMapperImpl​​映射 HTTP 端口8080到 HTTPS 端口8443,HTTP 端口80到 HTTPS 端口443

jee()

配置基于容器的预认证。在这种情况下,认证由Servlet容器管理

x509()

配置基于x509的预认证

rememberMe

配置“记住我”的验证

authorizeRequests()

基于使用​​HttpServletRequest​​限制访问

requestCache()

配置请求缓存

exceptionHandling()

配置错误处理

securityContext()

在​​HttpServletRequests​​​之间的​​SecurityContextHolder​​​上设置​​SecurityContext​​​的管理。当使用​​WebSecurityConfigurerAdapter​​时,这将自动应用

servletApi()

将​​HttpServletRequest​​​方法与在其上找到的值集成到​​SecurityContext​​​中。当使用​​WebSecurityConfigurerAdapter​​时,这将自动应用

csrf()

添加 CSRF 支持,使用​​WebSecurityConfigurerAdapter​​时,默认启用

logout()

添加退出登录支持。当使用​​WebSecurityConfigurerAdapter​​​时,这将自动应用。默认情况是,访问URL”/ logout”,使HTTP Session无效来清除用户,清除已配置的任何#rememberMe()身份验证,清除​​SecurityContextHolder​​​,然后重定向到​​/login?success​

anonymous()

配置匿名用户的表示方法。当与​​WebSecurityConfigurerAdapter​​​结合使用时,这将自动应用。默认情况下,匿名用户将使用​​org.springframework.security.authentication.AnonymousAuthenticationToken​​​表示,并包含角色 ​​ROLE_ANONYMOUS​

authenticationManager()

配置​​AuthenticationManager​

authenticationProvider()

添加​​AuthenticationProvider​

formLogin()

指定支持基于表单的身份验证。如果未指定​​FormLoginConfigurer#loginPage(String)​​,则将生成默认登录页面

oauth2Login()

根据外部OAuth 2.0或OpenID Connect 1.0提供程序配置身份验证

oauth2Client()

OAuth2.0 客户端相关的配置

oauth2ResourceServer()

OAuth2.0资源服务器相关的配置

requiresChannel()

配置通道安全。为了使该配置有用,必须提供至少一个到所需信道的映射

httpBasic()

配置 Http Basic 验证

addFilter()

添加一个已经在内置过滤器注册表注册过的过滤器实例或者子类

addFilterBefore()

在指定的Filter类之前添加过滤器

addFilterAt()

在指定的Filter类的位置添加过滤器

addFilterAfter()

在指定的Filter类的之后添加过滤器

and()

连接以上策略的连接器,用来组合安全策略。实际上就是”而且”的意思

高级玩法

新手建议先把上面的基本玩法有选择的弄明白,然后有精力的话去研究下​​HttpSecurity​​的高级玩法。

apply

这个方法用来把其它的一些配置合并到当前的配置中去,形成插件化,支持​​SecurityConfigurerAdapter​​​或者​​SecurityConfigurer​​​的实现。其实内置的一些配置都是以这种形式集成到​​HttpSecurity​​中去的。例如文章开头的配置中有默认登录页面相关的配置:

httpSecurity.apply(new DefaultLoginPageConfigurer<>());

胖哥就利用这个搞了一个支持小程序登录和验证码登录的扩展 

spring-security-login-extension


objectPostProcessor

配置一个自定义​​ObjectPostProcessor​​​。​​ObjectPostProcessor​​可以改变某些配置内部的机制,这些配置往往不直接对外提供操作接口。

获取、移除配置类

​getConfigurer​​​用来获取已经​​apply​​​的配置类;​​getConfigurers​​​用来获取已经​​apply​​某个类型的所有配置类。这个现在是我最喜欢的自定义的方式。

配置、获取SharedObject

​SharedObject​​​是在配置中进行共享的一些对象,HttpSecurity共享了一些非常有用的对象可以供各个配置之间共享,比如​​AuthenticationManager​​​。相关的方法有​​setSharedObject​​​、​​getSharedObject​​​、​​getSharedObjects​​。

获取SecurityFilterChain

​HttpSecurity​​​也提供了构建目标对象​​SecurityFilterChain​​​的实例的方法。你可以通过​​build()​​​来对配置进行初次构建;也可以通过​​getObject()​​​来获取已经构建的实例;甚至你可以使用​​getOrBuild()​​来进行直接获取实例或者构建实例。

所以新的配置都是这样的:

@Bean
SecurityFilterChain securityFilterChain (HttpSecurity http) {
http.cors();
return http.build();
}

记住每一个​​HttpSecurity​​只能被构建成功一次。


这一篇非常重要

本篇东西非常重要,不是马上就能掌握的,需要有些耐心,需要在使用和学习中总结和发现。

另外最近胖哥有很多成系列的内容输出:

  • OAuth2 系列教程

  • 开源了一个登录组件扩展spring-security-login-extension,降低对接配置成本。
  • 粉丝福利:正版IntelliJ IDEA 抽奖

有兴趣的可以看看。




本文摘自 :https://blog.51cto.com/u


更多科技新闻 ......