原文链接:Spring Security without the WebSecurityConfigurerAdapter

作者:ELEFTHERIA STEIN-KOUSATHANA

发表日期:2022年2月21日

在Spring Security 5.7.0-M2,我们弃用了WebSecurityConfigurerAdapter,因为我们鼓励用户转向使用基于组件的安全配置。

为了帮助大家熟悉这种新的配置风格,我们编制了一份常见用例表和推荐的新写法。

在下面的例子中,我们遵循最佳实践——使用Spring Security lambda领域专用语言(DSL)和HttpSecurity#authorizeHttpRequests方法来定义我们的授权规则。如果你对lambda领域专用语言(DSL)不熟悉,你可以在这篇博客了解它。如果你想知道为什么我们选择选择使用HttpSecurity#authorizeHttpRequests,你可以看这篇参考文档

配置HttpSecurity

在Spring Security 5.4,我们引入了创建一个SecurityFilterChian bean来配置HttpSecurity的功能。

下面是一个使用WebSecurityConfigurerAdapter和HTTP Basic保护所有端点的示例配置:

 1 @Configuration
2 public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
3
4 @Override
5 protected void configure(HttpSecurity http) throws Exception {
6 http
7 .authorizeHttpRequests((authz) -> authz
8 .anyRequest().authenticated()
9 )
10 .httpBasic(withDefaults());
11 }
12
13 }

往后,我们建议注册一个SecurityFilterChain bean来做这件事:

 1 @Configuration
2 public class SecurityConfiguration {
3
4 @Bean
5 public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
6 http
7 .authorizeHttpRequests((authz) -> authz
8 .anyRequest().authenticated()
9 )
10 .httpBasic(withDefaults());
11 return http.build();
12 }
13
14 }

配置WebSecurity

在Spring Security 5.4中,我们还引入WebSecurityCustomizer

WebSecurityCustomizer是一个回调接口,可以用来定制WebSecurity

下面是一个使用WebSecurityConfigurerAdapter忽略匹配/ignore1/ignore2的请求的示例配置:

1 @Configuration
2 public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
3
4 @Override
5 public void configure(WebSecurity web) {
6 web.ignoring().antMatchers("/ignore1", "/ignore2");
7 }
8
9 }

往后,我们建议注册一个WebSecurityCustomizer bean来做这件事:

1 @Configuration
2 public class SecurityConfiguration {
3
4 @Bean
5 public WebSecurityCustomizer webSecurityCustomizer() {
6 return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");
7 }
8
9 }

警告:如果你正在配置WebSecurity来忽略请求,建议你改为在HttpSecurity#authorizeHttpRequests内使用permitAll。想了解更多请参考configure Javadoc

LDAP认证

在Spring Security 5.7,我们引入EmbeddedLdapServerContextSourceFactoryBeanLdapBindAuthenticationManagerFactoryLdapPasswordComparisonAuthenticationManagerFactory,这些类都可以用来创建一个嵌入式的LDAP服务器;并且我们还引入一个AuthenticationManager类,它可以用来执行LDAP认证。

下面是一个使用是一个使用绑定验证的示例配置,它使用了WebSecurityConfugurerAdapter创建嵌入式LDAP服务器并且使用AuthenticationManager执行LDAP认证(Below is an example configuration using WebSecurityConfigurerAdappter the that creates an embedded LDAP server and an AuthenticationManager that performs LDAP authentication using bingd authentication):

 1 @Configuration
2 public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
3
4 @Override
5 protected void configure(AuthenticationManagerBuilder auth) throws Exception {
6 auth
7 .ldapAuthentication()
8 .userDetailsContextMapper(new PersonContextMapper())
9 .userDnPatterns("uid={0},ou=people")
10 .contextSource()
11 .port(0);
12 }
13
14 }

往后,我们建议使用新的LDAP类来做这件事:

 1 @Configuration
2 public class SecurityConfiguration {
3 @Bean
4 public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {
5 EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean =
6 EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();
7 contextSourceFactoryBean.setPort(0);
8 return contextSourceFactoryBean;
9 }
10
11 @Bean
12 AuthenticationManager ldapAuthenticationManager(
13 BaseLdapPathContextSource contextSource) {
14 LdapBindAuthenticationManagerFactory factory =
15 new LdapBindAuthenticationManagerFactory(contextSource);
16 factory.setUserDnPatterns("uid={0},ou=people");
17 factory.setUserDetailsContextMapper(new PersonContextMapper());
18 return factory.createAuthenticationManager();
19 }
20 }

JDBC认证

下面是一个示例配置,它在WebSecurityConfigurerAdapter内创建了一个使用默认模式初始化并且只有一个用户的内嵌DataSource

 1 @Configuration
2 public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
3 @Bean
4 public DataSource dataSource() {
5 return new EmbeddedDatabaseBuilder()
6 .setType(EmbeddedDatabaseType.H2)
7 .build();
8 }
9
10 @Override
11 protected void configure(AuthenticationManagerBuilder auth) throws Exception {
12 UserDetails user = User.withDefaultPasswordEncoder()
13 .username("user")
14 .password("password")
15 .roles("USER")
16 .build();
17 auth.jdbcAuthentication()
18 .withDefaultSchema()
19 .dataSource(dataSource())
20 .withUser(user);
21 }
22 }

推荐的做法是创建一个JdbcUserDetailsManager bean来做这件事:

 1 @Configuration
2 public class SecurityConfiguration {
3 @Bean
4 public DataSource dataSource() {
5 return new EmbeddedDatabaseBuilder()
6 .setType(EmbeddedDatabaseType.H2)
7 .addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)
8 .build();
9 }
10
11 @Bean
12 public UserDetailsManager users(DataSource dataSource) {
13 UserDetails user = User.withDefaultPasswordEncoder()
14 .username("user")
15 .password("password")
16 .roles("USER")
17 .build();
18 JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource);
19 users.createUser(user);
20 return users;
21 }
22 }

注意:在这些例子中,我们为了可读性使用了User.withDefaultPasswrdEncoder()。这不适合生产项目,我们建议在生产项目中使用散列密码。请按照参考文档所说的用Spring Boot命令行工具来做。

内存内认证

下面是一个示例配置,它在WebSecurityConfugurerAdapter配置了一个只存有一个用户的内存内用户:

 1 @Configuration
2 public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
3 @Override
4 protected void configure(AuthenticationManagerBuilder auth) throws Exception {
5 UserDetails user = User.withDefaultPasswordEncoder()
6 .username("user")
7 .password("password")
8 .roles("USER")
9 .build();
10 auth.inMemoryAuthentication()
11 .withUser(user);
12 }
13 }

我们建议注册一个InMemoryUserDetailsManager bean来做这件事:

 1 @Configuration
2 public class SecurityConfiguration {
3 @Bean
4 public InMemoryUserDetailsManager userDetailsService() {
5 UserDetails user = User.withDefaultPasswordEncoder()
6 .username("user")
7 .password("password")
8 .roles("USER")
9 .build();
10 return new InMemoryUserDetailsManager(user);
11 }
12 }

注意:在这些例子中,我们为了可读性使用了User.withDefaultPasswrdEncoder()。这不适合生产项目,我们建议在生产项目中使用散列密码。请按照参考文档所说的用Spring Boot命令行工具来做。

全局AuthenticationManager

要创建一个整个应用都可以使用的AuthenticationManager,只需要使用@Bean将AuthenticationManager注册为bean就可以了。

这种配置已经在上面的LDAP认证示例展示过了。

局部AuthenticationManager

在Spring Security 5.6中,我们引入HttpSecurity#authenticationManager方法,这个方法可以为特定的SecurityFilterChain覆盖默认的AuthenticationManager

下面是一个示例配置,它设置了一个自定义的AuthenticationManager

 1 @Configuration
2 public class SecurityConfiguration {
3
4 @Bean
5 public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
6 http
7 .authorizeHttpRequests((authz) -> authz
8 .anyRequest().authenticated()
9 )
10 .httpBasic(withDefaults())
11 .authenticationManager(new CustomAuthenticationManager());
12 return http.build();
13 }
14
15 }

访问局部AuthenticationManager

可以使用自定义领域专用语言(DSL)访问局部AuthenticationManager。这实际上是Spring Security内部实现HttpSecurity.authorizeRequests()等方法的方式。

 1 public class MyCustomDsl extends AbstractHttpConfigurer<MyCustomDsl, HttpSecurity> {
2 @Override
3 public void configure(HttpSecurity http) throws Exception {
4 AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);
5 http.addFilter(new CustomFilter(authenticationManager));
6 }
7
8 public static MyCustomDsl customDsl() {
9 return new MyCustomDsl();
10 }
11 }

然后,在构建SecurityFilterchain时可以应用自定义领域专用语言(DSL):

1 @Bean
2 public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
3 // ...
4 http.apply(customDsl());
5 return http.build();
6 }

欢迎加入

我们很高兴与您分享这些更新,我们期待通过您的反馈进一步增强Spring安全性!如果你有兴趣贡献,你可以在GitHub上找到我们。

【翻译】Spring Security抛弃了WebSecurityConfigurerAdapter的更多相关文章

  1. 【翻译】Spring Security - 如何解决WebSecurityConfigurerAdapter类已被弃用的问题?

    原文链接:Spring Security - How to Fix WebSecurityConfigurerAdapter Deprecated 原文作者:Nam Ha Minh 原文发表日期:20 ...

  2. SpringBoot第二十三篇:安全性之Spring Security

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11350255.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言   系统的安全 ...

  3. Spring Security 自定义 登陆 权限验证

    转载于:https://www.jianshu.com/p/6b8fb59b614b 项目简介 基于Spring Cloud 的项目,Spring Cloud是在Spring Boot上搭建的所以按照 ...

  4. 【微服务】 数据库案例理解Spring Security OAuth

    突然被问,你是做技术的怎么不走技术路线呢?是啊~仔细想想至今做了这么多年的技术,研发过的系统&产品五花八门,涉及到的领域各行各业:政府.军队.公安.国安.石油&石化.金融.教育.华为等 ...

  5. Spring Security 5.0.x 参考手册 【翻译自官方GIT-2018.06.12】

    源码请移步至:https://github.com/aquariuspj/spring-security/tree/translator/docs/manual/src/docs/asciidoc 版 ...

  6. Spring Security(一):官网向导翻译

    原文出自  https://spring.io/guides/topicals/spring-security-architecture Spring Security Architecture   ...

  7. spring security 继承 WebSecurityConfigurerAdapter 的重写方法configure() 参数 HttpSecurity 常用方法及说明

    HttpSecurity 常用方法及说明 方法 说明 openidLogin() 用于基于 OpenId 的验证 headers() 将安全标头添加到响应 cors() 配置跨域资源共享( CORS ...

  8. Spring Security即将弃用WebSecurityConfigurerAdapter配置类

    用过WebSecurityConfigurerAdapter的都知道对Spring Security十分重要,总管Spring Security的配置体系.但是马上这个类要废了,你没有看错,这个类将在 ...

  9. 【翻译】Thymeleaf – Spring Security集成模块

    原文链接:Thymeleaf - Spring Security integration modules 来源:thymeleaf/thymeleaf-extras-springsecurity自述文 ...

随机推荐

  1. 1.7_CSS基础

    层叠样式表 (Cascading Style Sheets) CSS产生缘由 HTML 标签原本被设计为用于定义文档内容.通过使用 <h1>.<p>.<table> ...

  2. OpenJudge1.5.17 菲波那契数列

    17:菲波那契数列 总时间限制: 1000ms 内存限制: 65536kB 描述 菲波那契数列是指这样的数列: 数列的第一个和第二个数都为1,接下来每个数都等于前面2个数之和. 给出一个正整数k,要求 ...

  3. .NET 7 性能改进 -- 至今为止最快的.NET平台

    2022年8月31日 Stephen Toub 发布的关于 .NET 7 性能改进的博客, 核心主题是 .NET 7 速度很快. 这篇博客非常的长,我尝试将它拷贝到Word 里,拷贝的时间都花了几分钟 ...

  4. VM虚拟机安装

    VM虚拟机安装 1.安装vm虚拟机软件 1.1 双击打开虚拟机文件 1.2 根据向导安装 下一步 安装好了 不要着急点完成在 安装目录中有许可证. 1.3激活操作 2.虚拟机原理简介 3. 新建虚拟机 ...

  5. KingbaseES R3 集群删除test库导致主备无法切换问题

    案例说明: 在KingbaseES R3集群中,kingbasecluster进程会通过test库访问,连接后台数据库服务测试:如果删除test数据库,导致后台数据库服务访问失败,在集群主备切换时,无 ...

  6. 深度学习库 SynapseML for .NET 发布0.1 版本

    2021年11月 微软开源一款简单的.多语言的.大规模并行的机器学习库 SynapseML(以前称为 MMLSpark),以帮助开发人员简化机器学习管道的创建.具体参见[1]微软深度学习库 Synap ...

  7. 04-MyBatisPlus条件构造器

    一.wapper介绍 Wrapper : 条件构造抽象类,最顶端父类 AbstractWrapper : 用于查询条件封装,生成 sql 的 where 条件 QueryWrapper : Entit ...

  8. Java SE 6、super关键字,包

    1.super关键字 super代表父类的引用,用于访问父类的属性,方法,构造器 super可以访问父类的属性,但不能访问父类的 private 属性 super.属性名; 可以访问父类的方法,不能访 ...

  9. 【gRPC】C++异步服务端优化版,多服务接口样例

    官方的C++异步服务端API样例可读性并不好,理解起来非常的费劲,各种状态机也并不明了,整个运行过程也容易读不懂,因此此处参考网上的博客进行了重写,以求顺利读懂. C++异步服务端实例,详细注释版 g ...

  10. 工厂想采购一套信息化生产执行系统mes,不知道用哪家比较好?

    好的信息化生产执行系统MES多的是,但是否适用于贵工厂那就不得而知了,要知道,不同行业.不同产品.不同规模的工厂用同一套系统效果呈现出来都不一样的,所以匹配很重要,个性化差异化.变化性等决定了一个工厂 ...