0

我再次面临与 Spring Security 相同的问题:“密码与存储值不匹配”。

我在我的图表中导入了 4 个帐户(我正在使用 SpringData/Neo4J)和我的自定义GraphPopulator类,并尝试使用一个(“fbiville”/“s3cret”)登录。

认证配置如下:

<beans:bean id="encoder" class="org.springframework.security.crypto.password.StandardPasswordEncoder">
    <beans:constructor-arg value="******" />
</beans:bean>

<beans:bean id="userService" class="com.lateralthoughts.devinlove.service.LoginService" />

<authentication-manager>
    <authentication-provider user-service-ref="userService">
        <password-encoder ref="encoder" />
    </authentication-provider>
</authentication-manager>

负责持久化帐户的类部分基于自定义的 SpringData 存储库实现:

class PersonRepositoryImpl implements PersonRepositoryCustom {

    private final PasswordEncoder passwordEncoder;
    private final Neo4jOperations template;

    @Autowired
    public PersonRepositoryImpl(PasswordEncoder passwordEncoder,
                            Neo4jOperations template) {

        this.passwordEncoder = passwordEncoder;
        this.template = template;
    }

    @Override
    @Transactional
    public void persist(Person person) {
        person.setPassword(passwordEncoder.encode(person.getPassword()));
        template.save(person);
    }
}

最后,登录流程配置如下:

<http auto-config='true' use-expressions='true' realm="devinlove: love is just another algorithm">
    <form-login   login-page="/login"
                  default-target-url="/"
                  authentication-failure-url="/login" />
    <intercept-url pattern="/login" access="isAnonymous()" />
    <intercept-url pattern="/**" access="hasRole('USER')" />
</http>

我在帐户创建和用户登录尝试时调试了 StandardPasswordEncoder,我注意到盐不匹配,这显然会导致身份验证错误。

如果您想重现问题,可以克隆存储库。

提前致谢 !

罗尔夫

4

1 回答 1

-1

您需要使用org.springframework.security.authentication.encoding.PasswordEncoder实现,而不是org.springframework.security.crypto.password.PasswordEncoder.

所以你可以简单地使用如下:

<authentication-manager>
    <authentication-provider user-service-ref="userService">
        <password-encoder hash="sha" base64="true">
            <!--Single salt - the very same as you are using in `encoder` instance-->
            <salt-source system-wide="********"/>
        </password-encoder>
    </authentication-provider>
</authentication-manager>

请注意,这将与@Autowired属性一起正常工作,尽管不应该存在@Qualifier并且 bean 必须只表示一次。

它公开了此类接口的实现:org.springframework.security.authentication.encoding.PasswordEncoderorg.springframework.security.authentication.dao.SaltSource.

因此,在您的特定情况下,它如下所示:

class PersonRepositoryImpl implements PersonRepositoryCustom {

    private final PasswordEncoder passwordEncoder;
    private final Neo4jOperations template;

    @Autowired
    public PersonRepositoryImpl(PasswordEncoder passwordEncoder,
                                SaltSource saltSource
                                Neo4jOperations template) {

        this.passwordEncoder = passwordEncoder;
        this.saltSource = saltSource;
        this.template = template;
    }

    @Override
    @Transactional
    public void persist(Person person) {
        person.setPassword(passwordEncoder.encode(person.getPassword(), saltSource));
        template.save(person);
    }
}
于 2013-04-01T09:42:08.603 回答