@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;
}
这里会构建基于原型的HttpSecurityBean,并且初始化了一些默认配置供我们来使用。涉及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某个类型的所有配置类。这个现在是我最喜欢的自定义的方式。
配置、获取SharedObjectShared
Object是在配置中进行共享的一些对象,HttpSecurity共享了一些非常有用的对象可以供各个配置之间共享,比如AuthenticationManager。相关的方法有setSharedObject、getSharedObject、getSharedObjects。
获取SecurityFilterChainHttpSecurity也提供了构建目标对象SecurityFilterChain的实例的方法。你可以通过build()来对配置进行初次构建;也可以通过getObject()来获取已经构建的实例;甚至你可以使用getOrBuild()来进行直接获取实例或者构建实例。
所以新的配置都是这样的:
@Bean
SecurityFilterChain securityFilterChain (HttpSecurity http) {
http.cors();
return http.build();
}
记住每一个HttpSecurity只能被构建成功一次。
这一篇非常重要本篇东西非常重要,不是马上就能掌握的,需要有些耐心,需要在使用和学习中总结和发现。