Man*_*dan 3 spring-security bcrypt
我知道在 Spring Security 中会出现以下情况:
There was an unexpected error (type=Internal Server Error, status=500).
There is no PasswordEncoder mapped for the id "null"
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
Run Code Online (Sandbox Code Playgroud)
解决方案是定义一个PasswordEncoder. 为了简单起见,可以定义以下内容:
There was an unexpected error (type=Internal Server Error, status=500).
There is no PasswordEncoder mapped for the id "null"
java.lang.IllegalArgumentException: There is no PasswordEncoder mapped for the id "null"
Run Code Online (Sandbox Code Playgroud)
现在,该方法在幕后createDelegatingPasswordEncoder()是如何定义的(到目前为止,直到 Spring Security 5.4.2 为止)(有关更多详细信息,请参阅PasswordEncoderFactories类):
@Bean
PasswordEncoder encoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
Run Code Online (Sandbox Code Playgroud)
现在关于BCryptPasswordEncoder类,它使用一些默认值,例如:
$2a10如果声明以下内容会发生什么:
@SuppressWarnings("deprecation")
public static PasswordEncoder createDelegatingPasswordEncoder() {
String encodingId = "bcrypt";
Map<String, PasswordEncoder> encoders = new HashMap<>();
encoders.put(encodingId, new BCryptPasswordEncoder());
encoders.put("ldap", new org.springframework.security.crypto.password.LdapShaPasswordEncoder());
encoders.put("MD4", new org.springframework.security.crypto.password.Md4PasswordEncoder());
encoders.put("MD5", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("MD5"));
encoders.put("noop", org.springframework.security.crypto.password.NoOpPasswordEncoder.getInstance());
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
encoders.put("scrypt", new SCryptPasswordEncoder());
encoders.put("SHA-1", new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-1"));
encoders.put("SHA-256",
new org.springframework.security.crypto.password.MessageDigestPasswordEncoder("SHA-256"));
encoders.put("sha256", new org.springframework.security.crypto.password.StandardPasswordEncoder());
encoders.put("argon2", new Argon2PasswordEncoder());
return new DelegatingPasswordEncoder(encodingId, encoders);
}
Run Code Online (Sandbox Code Playgroud)
如何将自定义创建的默认值添加或覆盖到默认 BCryptPasswordEncoder设置中?我想保留所有其他默认值 BCryptPasswordEncoder
注意:在PasswordEncoderFactories类(对于该createDelegatingPasswordEncoder方法)中,DelegatingPasswordEncoder类在幕后使用。该类也不提供重写方法。
例如,如果您正在创建新的应用程序,您很可能不需要DelegatingPasswordEncoder而应该使用自适应单向功能密码编码器BCryptPasswordEncoder。
为此,您可以将 a 公开BCryptPasswordEncoder为 bean。
@Bean
PasswordEncoder bcryptEncoder() {
return new BCryptPasswordEncoder(BCryptVersion.$2Y, 12);
}
Run Code Online (Sandbox Code Playgroud)
然后,当用户注册时,您可以使用 对其密码进行编码,BCryptPasswordEncoder然后将其保存到数据存储中。例如:
UserDetails userDetails = User
.withUsername(username)
.password(bcryptEncoder.encode(password))
.roles("USER")
.build();
Run Code Online (Sandbox Code Playgroud)
如果您要迁移现有应用程序,这就是DelegatingPasswordEncoder有用的地方。
允许DelegatingPasswordEncoder验证多种格式的密码。它使用前缀 ID(例如{bcrypt})来查找PasswordEncoder应该使用哪个。
考虑使用明文密码的遗留应用程序。
要迁移应用程序,您可以在明文密码前添加前缀{noop}并使用DelegatingPasswordEncoder如下所示的密码:
@Bean
public PasswordEncoder delegatingPasswordEncoder() {
Map<String, PasswordEncoder> encoders = new HashMap<>();
encoders.put("bcrypt", new BCryptPasswordEncoder(BCryptVersion.$2Y, 12));
encoders.put("noop", NoOpPasswordEncoder.getInstance());
return new DelegatingPasswordEncoder("bcrypt", encoders);
}
Run Code Online (Sandbox Code Playgroud)
这DelegatingPasswordEncoder将使用 编码和验证任何新创建的密码BCryptPasswordEncoder,同时仍然能够使用 验证旧的明文密码NoOpPasswordEncoder。
Spring Security 提供了该PasswordEncoderFactories.createDelegatingPasswordEncoder()方法作为方便的默认方法,但您的应用程序不太可能使用那么多不同的密码编码。
更有可能的是,您的应用程序使用 2 种不同的编码,即传统编码(例如 noop)和现代编码(例如 bcrypt),在这种情况下您可以使用PasswordEncoder与上述类似的delegatingPasswordEncoder编码。
这些示例的要点是说,在大多数情况下,您不需要 中设置的默认值createDelegatingPasswordEncoder。但是,如果您仍然想使用 中的编码器(除了createDelegatingPasswordEncoder)bcrypt,您可以使用PasswordEncoder如下所示的 :
@Bean
public PasswordEncoder delegatingPasswordEncoder() {
Map<String, PasswordEncoder> encoders = new HashMap<>();
// Use this encoder for bcrypt
encoders.put("bcrypt", new BCryptPasswordEncoder(BCryptVersion.$2Y, 12));
DelegatingPasswordEncoder delegatingPasswordEncoder =
new DelegatingPasswordEncoder("bcrypt", encoders);
PasswordEncoder defaultDelegatingPasswordEncoder =
PasswordEncoderFactories.createDelegatingPasswordEncoder();
// If a password ID does not match "bcrypt", use defaultDelegatingPasswordEncoder
delegatingPasswordEncoder.setDefaultPasswordEncoderForMatches(defaultDelegatingPasswordEncoder);
return delegatingPasswordEncoder;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2280 次 |
| 最近记录: |