没有WebSecurityConfigurerAdapter的Spring Security

2024-06-28 1145阅读

没有WebSecurityConfigurerAdapter的Spring Security

最近一直在从springboot2.x向3.x学习迁移,付出了很大的学习成本,心得会不断分享。对于spring security来说,是该和WebSecurityConfigurerAdapter说再见了,因为在Spring Security 5.7.0-M2中WebSecurityConfigurerAdapter已经被弃用找不到了。搬来了官方的博文,翻译不好的地方可以看原文,链接如下:

没有WebSecurityConfigurerAdapter的Spring Security
(图片来源网络,侵删)

Spring Security without the WebSecurityConfigurerAdapter

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

为了帮助过渡到这种新的配置风格,我们编制了一份常见用例和建议替代方案的列表。

在下面的示例中,我们遵循最佳实践,使用Spring Security lambda DSL和方法httpsecurity# authorizeHttpRequests来定义授权规则。如果您是lambda DSL的新手,您可以在这篇博客文章中了解它。如果你想了解更多关于为什么我们选择使用httpsecurity# authorizeHttpRequests,你可以查看参考文档(Authorize HttpServletRequests :: Spring Security)。

配置HttpSecurity

在Spring Security 5.4中,我们引入了通过创建SecurityFilterChain bean来配置HttpSecurity的功能。

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

@Configuration

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override

    protected void configure(HttpSecurity http) throws Exception {

        http

            .authorizeHttpRequests((authz) -> authz

                .anyRequest().authenticated()

            )

            .httpBasic(withDefaults());

    }

}

接下来,推荐的方法是注册一个SecurityFilterChain bean:

@Configuration

public class SecurityConfiguration {

    @Bean

    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http

            .authorizeHttpRequests((authz) -> authz

                .anyRequest().authenticated()

            )

            .httpBasic(withDefaults());

        return http.build();

    }

}

配置WebSecurity

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

WebSecurityCustomizer是一个回调接口,可用于自定义WebSecurity。

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

@Configuration

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override

    public void configure(WebSecurity web) {

        web.ignoring().antMatchers("/ignore1", "/ignore2");

    }

}

接下来,推荐的方法是注册一个WebSecurityCustomizer bean:

@Configuration

public class SecurityConfiguration {

    @Bean

    public WebSecurityCustomizer webSecurityCustomizer() {

        return (web) -> web.ignoring().antMatchers("/ignore1", "/ignore2");

    }

}

警告:如果你将WebSecurity配置为忽略请求,请考虑通过httpsecurity# authorizeHttpRequests使用permitAll。有关其他详细信息,请参阅configure Javadoc。

LDAP身份验证

在Spring Security 5.7中,我们介绍了EmbeddedLdapServerContextSourceFactoryBean、LdapBindAuthenticationManagerFactory和LdapPasswordComparisonAuthenticationManagerFactory,它们可用于创建嵌入式LDAP服务器和执行LDAP身份验证的AuthenticationManager。

下面是一个使用WebSecurityConfigurerAdapter的配置示例,它创建了一个嵌入式LDAP服务器和一个使用绑定身份验证执行LDAP身份验证的AuthenticationManager:

@Configuration

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth

            .ldapAuthentication()

            .userDetailsContextMapper(new PersonContextMapper())

            .userDnPatterns("uid={0},ou=people")

            .contextSource()

            .port(0);

    }

}

接下来,推荐的方法是使用新的LDAP类:

@Configuration

public class SecurityConfiguration {

    @Bean

    public EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean() {

        EmbeddedLdapServerContextSourceFactoryBean contextSourceFactoryBean =

            EmbeddedLdapServerContextSourceFactoryBean.fromEmbeddedLdapServer();

        contextSourceFactoryBean.setPort(0);

        return contextSourceFactoryBean;

    }

    @Bean

    AuthenticationManager ldapAuthenticationManager(

            BaseLdapPathContextSource contextSource) {

        LdapBindAuthenticationManagerFactory factory =

            new LdapBindAuthenticationManagerFactory(contextSource);

        factory.setUserDnPatterns("uid={0},ou=people");

        factory.setUserDetailsContextMapper(new PersonContextMapper());

        return factory.createAuthenticationManager();

    }

}

JDBC身份验证

下面是一个使用WebSecurityConfigurerAdapter的配置示例,其中嵌入了一个用默认模式初始化的数据源,并且只有一个用户:

@Configuration

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean

    public DataSource dataSource() {

        return new EmbeddedDatabaseBuilder()

            .setType(EmbeddedDatabaseType.H2)

            .build();

    }

    @Override

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        UserDetails user = User.withDefaultPasswordEncoder()

            .username("user")

            .password("password")

            .roles("USER")

            .build();

        auth.jdbcAuthentication()

            .withDefaultSchema()

            .dataSource(dataSource())

            .withUser(user);

    }

}

推荐的方法是注册一个JdbcUserDetailsManager bean:

@Configuration

public class SecurityConfiguration {

    @Bean

    public DataSource dataSource() {

        return new EmbeddedDatabaseBuilder()

            .setType(EmbeddedDatabaseType.H2)

            .addScript(JdbcDaoImpl.DEFAULT_USER_SCHEMA_DDL_LOCATION)

            .build();

    }

    @Bean

    public UserDetailsManager users(DataSource dataSource) {

        UserDetails user = User.withDefaultPasswordEncoder()

            .username("user")

            .password("password")

            .roles("USER")

            .build();

        JdbcUserDetailsManager users = new JdbcUserDetailsManager(dataSource);

        users.createUser(user);

        return users;

    }

}

注意:在这些示例中,为了提高可读性,我们使用了User.withDefaultPasswordEncoder()方法。它不是用于生产环境的,相反,我们建议在外部散列您的密码。一种方法是使用参考文档中描述的Spring Boot CLI。

内存中的身份验证

下面是一个使用WebSecurityConfigurerAdapter的配置示例,它用单个用户配置内存中的用户存储:

@Configuration

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        UserDetails user = User.withDefaultPasswordEncoder()

            .username("user")

            .password("password")

            .roles("USER")

            .build();

        auth.inMemoryAuthentication()

            .withUser(user);

    }

}

推荐的方法是注册一个InMemoryUserDetailsManager bean:

@Configuration

public class SecurityConfiguration {

    @Bean

    public InMemoryUserDetailsManager userDetailsService() {

        UserDetails user = User.withDefaultPasswordEncoder()

            .username("user")

            .password("password")

            .roles("USER")

            .build();

        return new InMemoryUserDetailsManager(user);

    }

}

注意:在这些示例中,为了提高可读性,我们使用了User.withDefaultPasswordEncoder()方法。它不是用于生产环境的,相反,我们建议在外部散列您的密码。一种方法是使用参考文档中描述的Spring Boot CLI。

全局AuthenticationManager

要创建一个对整个应用程序可用的AuthenticationManager,只需将AuthenticationManager注册为@Bean即可。

在上面的LDAP身份验证示例中显示了这种类型的配置。

https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter#ldap-authentication

本地AuthenticationManager

在Spring Security 5.6中,我们引入了httpsecurity# authenticationManager方法,它覆盖了特定SecurityFilterChain的默认authenticationManager。下面是一个将自定义AuthenticationManager设置为默认值的示例配置:

@Configuration

public class SecurityConfiguration {

    @Bean

    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

        http

            .authorizeHttpRequests((authz) -> authz

                .anyRequest().authenticated()

            )

            .httpBasic(withDefaults())

            .authenticationManager(new CustomAuthenticationManager());

        return http.build();

    }

}

访问本地AuthenticationManager

本地AuthenticationManager可以在自定义DSL中访问。这实际上是Spring Security内部实现HttpSecurity.authorizeRequests()等方法的方式。

public class MyCustomDsl extends AbstractHttpConfigurer {

    @Override

    public void configure(HttpSecurity http) throws Exception {

        AuthenticationManager authenticationManager = http.getSharedObject(AuthenticationManager.class);

        http.addFilter(new CustomFilter(authenticationManager));

    }

    public static MyCustomDsl customDsl() {

        return new MyCustomDsl();

    }

}

自定义DSL可以在构建SecurityFilterChain时应用:

@Bean

public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {

    // ...

    http.apply(customDsl());

    return http.build();

}

VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]