0


没有WebSecurityConfigurerAdapter的Spring Security

没有WebSecurityConfigurerAdapter的Spring Security

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

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<MyCustomDsl, HttpSecurity> {

@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();

}

标签: spring java 后端

本文转载自: https://blog.csdn.net/Kwoky/article/details/139243151
版权归原作者 Kwoky 所有, 如有侵权,请联系我们删除。

“没有WebSecurityConfigurerAdapter的Spring Security”的评论:

还没有评论