記憶體驗證

Spring Security 的 InMemoryUserDetailsManager 實作了 UserDetailsService,以提供基於使用者名稱/密碼的驗證支援,並儲存在記憶體中。InMemoryUserDetailsManager 透過實作 UserDetailsManager 介面來提供 UserDetails 的管理。當 Spring Security 組態為接受使用者名稱和密碼以進行驗證時,會使用基於 UserDetails 的驗證。

在以下範例中,我們使用 Spring Boot CLI 來編碼密碼值 password,並取得編碼後的密碼 {bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW

InMemoryUserDetailsManager Java 組態
  • Java

  • XML

  • Kotlin

@Bean
public UserDetailsService users() {
	UserDetails user = User.builder()
		.username("user")
		.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
		.roles("USER")
		.build();
	UserDetails admin = User.builder()
		.username("admin")
		.password("{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
		.roles("USER", "ADMIN")
		.build();
	return new InMemoryUserDetailsManager(user, admin);
}
<user-service>
	<user name="user"
		password="{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW"
		authorities="ROLE_USER" />
	<user name="admin"
		password="{bcrypt}$2a$10$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW"
		authorities="ROLE_USER,ROLE_ADMIN" />
</user-service>
@Bean
fun users(): UserDetailsService {
    val user = User.builder()
        .username("user")
        .password("{bcrypt}$2a$10\$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
        .roles("USER")
        .build()
    val admin = User.builder()
        .username("admin")
        .password("{bcrypt}$2a$10\$GRLdNijSQMUvl/au9ofL.eDwmoohzzS7.rmNSJZ.0FxO/BTk76klW")
        .roles("USER", "ADMIN")
        .build()
    return InMemoryUserDetailsManager(user, admin)
}

先前的範例以安全格式儲存密碼,但在入門體驗方面仍有許多不足之處。

在以下範例中,我們使用 User.withDefaultPasswordEncoder 來確保儲存在記憶體中的密碼受到保護。但是,它無法防止透過反編譯原始碼來取得密碼。因此,User.withDefaultPasswordEncoder 僅應在「入門」時使用,不適用於生產環境。

使用 User.withDefaultPasswordEncoder 的 InMemoryUserDetailsManager
  • Java

  • Kotlin

@Bean
public UserDetailsService users() {
	// The builder will ensure the passwords are encoded before saving in memory
	UserBuilder users = User.withDefaultPasswordEncoder();
	UserDetails user = users
		.username("user")
		.password("password")
		.roles("USER")
		.build();
	UserDetails admin = users
		.username("admin")
		.password("password")
		.roles("USER", "ADMIN")
		.build();
	return new InMemoryUserDetailsManager(user, admin);
}
@Bean
fun users(): UserDetailsService {
    // The builder will ensure the passwords are encoded before saving in memory
    val users = User.withDefaultPasswordEncoder()
    val user = users
        .username("user")
        .password("password")
        .roles("USER")
        .build()
    val admin = users
        .username("admin")
        .password("password")
        .roles("USER", "ADMIN")
        .build()
    return InMemoryUserDetailsManager(user, admin)
}

使用基於 XML 的組態,沒有簡單的方法可以使用 User.withDefaultPasswordEncoder。對於演示或剛開始入門,您可以選擇在密碼前加上 {noop},以指示不應使用編碼

<user-service> {noop} XML 組態
<user-service>
	<user name="user"
		password="{noop}password"
		authorities="ROLE_USER" />
	<user name="admin"
		password="{noop}password"
		authorities="ROLE_USER,ROLE_ADMIN" />
</user-service>