如何在没有密码编码的情况下使用Spring安全性?

我目前正在尝试学习Spring安全性。我曾经在保存到数据库

代码之前对用户密码进行编码:BCryptPasswordEncoder

@Override
    public void saveUser(User user) {
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        user.setActive(1);
        Role userRole = roleRepository.findByRole("ADMIN");
        user.setRoles(new HashSet<Role>(Arrays.asList(userRole)));
        userRepository.save(user);
    }

然后在身份验证期间也使用它,并且用户按预期进行身份验证。

@Override
    protected void configure(AuthenticationManagerBuilder auth)
            throws Exception {
        auth.
            jdbcAuthentication()
                .usersByUsernameQuery(usersQuery)
                .authoritiesByUsernameQuery(rolesQuery)
                .dataSource(dataSource).passwordEncoder(bCryptPasswordEncoder);
    }

然后我从方法中删除,仍然具有编码密码的用户成功进行身份验证。.passwordEncoder(bCryptPasswordEncoder);configure()

然后我从和方法中删除了密码编码器,并将一个保存到数据库中(即没有密码编码),并尝试访问经过身份验证的页面,但我得到了,但是即使我从方法中删除,

具有编码密码的用户仍然会进行身份验证。为什么会发生这种情况?

默认情况下,弹簧安全在身份验证期间是否使用密码编码器?

如果是这样,如何在没有密码编码的情况下使用弹簧安全性?saveUser()configure()UserAccessedDeniedExceptionpasswordEncoder()configure()


答案 1

也许你可以实现这个简单的代码来规避弹簧编码器

public class PasswordEnconderTest implements PasswordEncoder {
    @Override
    public String encode(CharSequence charSequence) {
        return charSequence.toString();
    }

    @Override
    public boolean matches(CharSequence charSequence, String s) {
        return charSequence.toString().equals(s);
    }
}

并添加到您的网络安全配置中:

@Bean
public PasswordEncoder passwordEncoder(){
    return new PasswordEnconderTest();
}

不建议这样做,但您可以实现


答案 2

使用Spring Security 5,始终启用密码加密。默认使用的加密为 。关于Spring Security 5的巧妙之处在于,它实际上允许您在密码中指定用于创建had的加密。bcrypt

为此,请参阅Spring安全参考指南中的密码存储格式。简而言之,它允许您为算法的众所周知的密钥添加密码前缀。存储格式为 。{<encryption>}<your-password-hash>

当不使用任何东西时,它会变成(这将使用并且将使用.有几种开箱即用的算法受支持,但您也可以定义自己的算法。{noop}your-passwordNoOpPasswordEncoder{bcrypt}$a2......BcryptPasswordEncoder

要定义您自己的,请创建您自己的,并在一个键下注册它,并使用 .PasswordEncoderDelegatingPasswordEncoder


推荐