此版本仍在开发中,尚未被视为稳定版本。对于最新的稳定版本,请使用 Spring Security 6.4.1! |
内存中身份验证
Spring Security 的InMemoryUserDetailsManager
实现 UserDetailsService 以支持存储在内存中的基于用户名/密码的身份验证。InMemoryUserDetailsManager
提供UserDetails
通过实现UserDetailsManager
接口。UserDetails
当 Spring Security 配置为接受用户名和密码进行身份验证时,将使用基于的身份验证。
在以下示例中,我们使用 Spring Boot CLI 对 password 值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)
}
没有简单的使用User.withDefaultPasswordEncoder
使用基于 XML 的配置。
对于演示或刚入门,您可以选择在密码前加上{noop}
指示不应使用编码:
<用户服务>
{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>