Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么春天';s MessageDigestPasswordEncoder将`{}`放入盐中?javadoc中的示例似乎不起作用_Java_Spring_Spring Security - Fatal编程技术网

为什么春天';s MessageDigestPasswordEncoder将`{}`放入盐中?javadoc中的示例似乎不起作用

为什么春天';s MessageDigestPasswordEncoder将`{}`放入盐中?javadoc中的示例似乎不起作用,java,spring,spring-security,Java,Spring,Spring Security,我正在从SpringSecurity 4.x升级到5.x Spring 4中的ReflectionSaltSource允许我们配置自定义salt。但这在春季安全5中被删除。然后我发现我应该使用MessageDigestPasswordEncoder。它有一个很长很详细的java文档,但不幸的是,该文档是一个没有传递任何结构化信息的单词包(我尝试了多次;如果我不知道的话,我的坏消息) 无论如何,基于我有限的理解,我认为我应该做以下事情 带有4.x-myEncodedPassword和mySalt的

我正在从SpringSecurity 4.x升级到5.x

Spring 4中的
ReflectionSaltSource
允许我们配置自定义salt。但这在春季安全5中被删除。然后我发现我应该使用
MessageDigestPasswordEncoder
。它有一个很长很详细的java文档,但不幸的是,该文档是一个没有传递任何结构化信息的单词包(我尝试了多次;如果我不知道的话,我的坏消息)

无论如何,基于我有限的理解,我认为我应该做以下事情

带有4.x-
myEncodedPassword
mySalt
的旧系统分别传递给编码器

带有5.x的新系统-将一个值为
{mySalt}myEncodedPassword
的字段传递给
MessageDigestPasswordEncoder

然而,这并不奏效问题是当
MessageDigestPasswordEncoder
看到
{mySalt}encodedPassword
时,它使用
{mySalt}
(带{})作为盐,而不是使用
mySalt
作为盐。我很困惑

下面是一个编码示例。我用Groovy来减少噪音

@Grab(group='org.springframework.security', module='spring-security-core', version='5.1.4.RELEASE')
import org.springframework.security.crypto.password.MessageDigestPasswordEncoder

String password = 'myPassword'
String salt_1 = 'mySalt'
String salt_2 = '{mySalt}'
// http://www.lorem-ipsum.co.uk/hasher.php generated below hashes
String encodedPasswordWithSalt_1 = '57bc828628811a10496215e217b7ae9b714c859fc7a8b1c678c9a0cc40aac422'
String encodedPasswordWithSalt_2 = 'a18b53fc58843def1e08e00a718f40d6f8eda0b97ef97824b5078c1fad93c0c5'

MessageDigestPasswordEncoder encoder = new MessageDigestPasswordEncoder('SHA-256')
println "expected=true, actual=" + encoder.matches(password, "{${salt_1}}${encodedPasswordWithSalt_1}") // <--- expected to match but did not
println "expected=false, actual=" + encoder.matches(password, "{${salt_1}}${encodedPasswordWithSalt_2}") // <--- why does this match?
我希望找到一种方法来支持SHA256,为每个用户密码提供自定义和单独的salt



如果有人感兴趣,我在GitHub上创建了一个票证-。目前还没有解决办法。如果有任何更新,我会在这里更新。所以这仍然是一个未回答的问题。

我猜问题出在
org.springframework.security.crypto.password.MessageDigestPasswordEncoder
类中

通过在方法
private String extractSalt(String prefixEncodedPassword)
中调试,他们试图通过返回
prefixEncodedPassword.substring(start,end+1)来提取salt
其中
start
是前缀
{
的索引,end是后缀
}
的索引,它停在匹配的第一个后缀,那么代码中会发生什么

发生这种情况:

MessageDigestPasswordEncoder encoder = new MessageDigestPasswordEncoder('SHA-256')
println "expected=true, actual=" + encoder.matches(password, "{${salt_1}}${encodedPasswordWithSalt_1}") //It's not matched because the extracted salt will be {mySalt} and not mySalt
println "expected=false, actual=" + encoder.matches(password, "{${salt_1}}${encodedPasswordWithSalt_2}") //It's matched because the extracted salt will be {mySalt} and not mySalt
我声明我不知道它是否是一个bug,在您的场景中,它应该足以正确地调查和修改该方法

private String extractSalt(String prefixEncodedPassword) {
        int start = prefixEncodedPassword.indexOf(PREFIX);
        if (start != 0) {
            return "";
        }
        int end = prefixEncodedPassword.indexOf(SUFFIX, start);
        if (end < 0) {
            return "";
        }
        return prefixEncodedPassword.substring(start, end + 1);
    }
private String extractSalt(字符串前缀incoded密码){
int start=prefixEncodedPassword.indexOf(前缀);
如果(开始!=0){
返回“”;
}
int end=prefixEncodedPassword.indexOf(后缀,开始);
如果(结束<0){
返回“”;
}
返回prefixEncodedPassword.substring(开始、结束+1);
}
此方法位于
org.springframework.security.crypto.password.MessageDigestPasswordEncoder
类中

我希望它有用


Angelo

在github上被问到(@phani我看到它是你创建的,为其他回答者写的):是的,谢谢你的评论。我认为可能会有更多的关注。您可以创建自己的密码编码器,实现org.springframework.security.crypto.password.PasswordEncoder接口。我们在我们的项目中做到了这一点。或者,您可以修复MessageDigestPasswordEncoder中的extractSalt方法,并将其推入spring安全项目:)@AnatolySamoylenko yep。谢谢你的澄清。谢谢你的澄清。我觉得很傻,我拒绝相信这是一个错误。由于我对
spring security
和相关主题不熟悉,我认为我做错了什么。
private String extractSalt(String prefixEncodedPassword) {
        int start = prefixEncodedPassword.indexOf(PREFIX);
        if (start != 0) {
            return "";
        }
        int end = prefixEncodedPassword.indexOf(SUFFIX, start);
        if (end < 0) {
            return "";
        }
        return prefixEncodedPassword.substring(start, end + 1);
    }