9.2.1 使用基于内存的用户存储

因为我们的安全配置类扩展了 WebSecurityConfigurerAdapter,因此配置用户存储的最简单方式就是重载 configure() 方法,并以 AuthenticationManagerBuilder 作为传入参数。AuthenticationManagerBuilder 有多个方法可以用来配置 Spring Security 对认证的支持。通过 inMemoryAuthentication() 方法,我们可以启用、配置并任意填充基于内存的用户存储。

例如,在如程序清单 9.3 中,SecurityConfig 重载了 configure() 方法,并使用两个用户来配置内存用户存储。

程序清单 9.3 配置 Spring Security 使用内存用户存储
package spittr.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;

@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  
  @Override
  protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    auth
      .inMemoryAuthentication()
      .withUser("user").password("password").roles("USER");
  }
}

我们可以看到,configure() 方法中的 AuthenticationManagerBuilder 使用构造者风格的接口来构建认证配置。通过简单地调用 inMemoryAuthentication() 就能启用内存用户存储。但是我们还需要有一些用户,否则的话,这和没有用户并没有什么区别。

因此,我们需要调用 withUser() 方法为内存用户存储添加新的用户,这个方法的参数是 username。withUser() 方法返回的是UserDetailsManager-Configurer.UserDetailsBuilder,这个对象提供了多个进一步配置用户的方法,包括设置用户密码的 password() 方法以及为给定用户授予一个或多个角色权限的 roles() 方法。

在程序清单 9.3 中,我们添加了两个用户,“user”和“admin”,密码均为“password”。“user”用户具有 USER 角色,而“admin”用户具有 ADMIN 和 USER 两个角色。我们可以看到,and() 方法能够将多个用户的配置连接起来。

除了 password()、roles() 和 and() 方法以外,还有其他的几个方法可以用来配置内存用户存储中的用户信息。表 9.3 描述了 UserDetailsManager-Configurer.UserDetailsBuilder 对象所有可用的方法。

需要注意的是,roles() 方法是 authorities() 方法的简写形式。roles() 方法所给定的值都会添加一个“ROLE_”前缀,并将其作为权限授予给用户。实际上,如下的用户配置与程序清单 9.3 是等价的:

auth
  .inMemoryAuthentication()
  .withUser("user").password("password").authorities("ROLE_USER")
  .and()
  .withUser("admin").password("password").authorities("ROLE_USER", "ROLE_ADMIN");

对于调试和开发人员测试来讲,基于内存的用户存储是很有用的,但是对于生产级别的应用来讲,这就不是最理想的可选方案了。为了用于生产环境,通常最好将用户数据保存在某种类型的数据库之中。

Last updated