Toggle
在
Spring Security 5.7.0-M2
废弃了
WebSecurityConfigurerAdapter
,根据官方的说法,是希望用户使用基础组件来构建安全配置
在下面的例子中,我们按照官方提供的最佳实践方法使用
Spring Security lambda DSL
和
HttpSecurity#authorizeHttpRequests
方法来定义我们的授权规则
如果你对
Spring Security lambda DSL
有兴趣,可以阅读这篇文章:
文章地址
如果你想要知道为什么要选择
HttpSecurity#authorizeHttpRequests
,可以阅读这篇文章:
文章地址
1. Configuring HttpSecurity
在
5.4
版本中我们使用
HttpSecurity
来创建一个
SecurityFilterChain
Bean
下面是一个使用
WebSecurityConfigurerAdapter
配置示例
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
.authorizeHttpRequests((authz) -> authz
.anyRequest().authenticated()
.httpBasic(withDefaults());
接下来,在新版本中,官方推荐的写法是:
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.authorizeHttpRequests((authz) -> authz
.anyRequest().authenticated()
.httpBasic(withDefaults());
return http.build();
2. Configuring WebSecurity
在 Spring Security 5.4
版本中,使用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
来忽略请求,考虑使用permitAll
通过HttpSecurity#authorizeHttpRequests
来代替
3. LDAP Authentication
在 Spring Security 5.7
中,可以使用 EmbeddedLdapServerContextSourceFactoryBean
、 LdapBindAuthenticationManagerFactory
、LdapPasswordComparisonAuthenticationManagerFactory
来创建嵌入式LDAP
服务器和执行LDAP
身份验证的AuthenticationManager
下面是一个使用WebSecurityConfigurerAdapter
的配置示例,它创建了一个嵌入式LDAP
服务器和一个AuthenticationManager
, AuthenticationManager
使用绑定身份验证执行LDAP
身份验证:
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
.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();
4. JDBC Authentication
下面是一个使用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()
方法来提高可读性,并不推荐在生产环境中使用,比如你可以使用自定义的哈希密码
5. In-Memory Authentication
下面是一个使用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()
方法来提高可读性,并不推荐在生产环境中使用,比如你可以使用自定义的哈希密码
6. Global AuthenticationManager
只需将AuthenticationManager
注册为Bean
可以参考: LDAP Authentication
7. Local AuthenticationManager
在 Spring Security 5.6
版本中,我们使用 httpsecurity# authenticationManager
方法,覆盖SecurityFilterChain
默认的authenticationManager
:
@Configuration
public class SecurityConfiguration {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.authorizeHttpRequests((authz) -> authz
.anyRequest().authenticated()
.httpBasic(withDefaults())
.authenticationManager(new CustomAuthenticationManager());
return http.build();
9. Accessing the local AuthenticationManager
可以在自定义DSL中访问本地AuthenticationManager
, 这实际上就是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();
然后,在构建SecurityFilterChain
时可以应用自定义DSL
:
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// ...
http.apply(customDsl());
return http.build();
翻译来源文章:https://spring.io/blog/2022/02/21/spring-security-without-the-websecurityconfigureradapter
浏览量: 1,971