gpt4 book ai didi

spring-security - 如何覆盖通过 PasswordEncoderFactories 创建的默认 BCryptPasswordEncoder?

转载 作者:行者123 更新时间:2023-12-05 09:35:30 26 4
gpt4 key购买 nike

我知道在 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"

解决方案是定义一个PasswordEncoder。为简单起见,可以定义以下内容:

@Bean
PasswordEncoder encoder() {
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}

现在,createDelegatingPasswordEncoder() 方法在幕后是如何定义的(到目前为止,它目前适用于 Spring Security 5.4.2)(有关更多详细信息,请参阅 PasswordEncoderFactories 类):

@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);
}

现在关于 BCryptPasswordEncoder类,它适用于一些默认值,例如:

  • 版本:$2a
  • 强度:10

如果声明以下内容会发生什么:

@Bean
PasswordEncoder bcryptEncoder() {
return new BCryptPasswordEncoder(BCryptVersion.$2Y, 12);
}

如何将使用自定义 BCryptPasswordEncoder 创建的default BCryptPasswordEncoder 添加或覆盖到默认设置中?我想保留所有其他默认值

注意:在PasswordEncoderFactories类(对于 createDelegatingPasswordEncoder 方法),DelegatingPasswordEncoder类在幕后使用。该类也没有提供覆盖方法。

最佳答案

如果您正在创建一个新应用,您很可能不需要DelegatingPasswordEncoder,而是应该使用自适应单向函数密码编码器,例如 BCryptPasswordEncoder.

为此,您可以将 BCryptPasswordEncoder 作为 bean 公开。

@Bean
PasswordEncoder bcryptEncoder() {
return new BCryptPasswordEncoder(BCryptVersion.$2Y, 12);
}

然后,当用户注册时,您可以在将其保存到数据存储之前使用 BCryptPasswordEncoder 对其密码进行编码。例如:

UserDetails userDetails = User
.withUsername(username)
.password(bcryptEncoder.encode(password))
.roles("USER")
.build();

如果您正在迁移一个现有的应用程序,这就是 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);
}

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;
}

关于spring-security - 如何覆盖通过 PasswordEncoderFactories 创建的默认 BCryptPasswordEncoder?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65796088/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com