在 Spring 中使用 Bcrypt

Using Bcrypt in Spring

我正在本地登录,我知道我的密码以纯文本形式存储在 h2 数据库中。

我想在 spring 中使用 Bcrypt,但我在启动应用程序时遇到此错误:

Field bCryptPasswordEncoder in com.alert.interservices.uaa.Bootstrap required a bean of type 'org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder' that could not be found.

要使用Bcrypt,我只在我的控制器中自动装配它并加密密码。 填充数据库时,我在 Bootstrap 上做了同样的事情:

控制器:

@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;

/**
 * 
 * @param user the user that is trying to access
 * @return the user if it is successfull or a bad request if not
 */
@RequestMapping(value = "/authenticate", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Object authenticate(@RequestBody UserEntity user) {

    logger.debug("Begin request UAAController.authenticate()");

    String encriptedPasswd=bCryptPasswordEncoder.encode(user.getPassword().getPassword());

    UserEntity usr = authenticationService.authenticate(user.getName(), encriptedPasswd);

    (...)

Bootstrap:

@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;

@GetMapping("/test")
public void fillDatabse() {


    String encodedPw=bCryptPasswordEncoder.encode("test");
    Password p = new Password(encodedPw);

我做错了什么?

BCryptPasswordEncoder 不是 bean,不能自动装配它。

使用:

Password p = new Password(new BCryptPasswordEncoder().encode(encodedPw));

而不是

String encodedPw=bCryptPasswordEncoder.encode("test");
Password p = new Password(encodedPw);

并删除

@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;

同时在您的控制器中进行这些更改

你可以提供一个 BCryptPasswordEncoder 的 bean,方法是将以下代码放入任何扫描的 类 包中,并用 @SpringBootApplication@Configuration...[= 注释16=]

@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
    return new BCryptPasswordEncoder();
}

另外,请注意方法签名可能是

public PasswordEncoder myPasswordEncoder()(其余同理)

See an example in a working project.

您的问题源于您尝试注入密码编码器的方式(从您收到的错误消息中可以看出)。

您不能简单地尝试注入 PasswordEncoder 接口的实现,在本例中 BCryptPasswordEncoder 这种方式。如果你想让它随时可用并在 Spring 上下文中(因此可以在需要时进行注入),你需要采用不同的方法。

在某处手动实例化一个 bean,并使用 bean 注释将其引入上下文。然后在需要时注入它。一个简单的例子你是下面的:

1) 创建一个名为 PasswordService 的服务,如下所示:

@Service
public final class PasswordService {

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

}

如上所述,这会将密码编码器的实例带入上下文。

然后在需要的时候这样使用它:

@Autowired
private PasswordEncoder passwordEncoder

您将有效地避免每次都手动实例化编码器。

简单地说,您可以在@SpringBootApplication 或任何class 中提供一个bean

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

然后在服务中您可以自动装配 Bcript 并像下面的示例一样使用

@Autowired
private PasswordEncoder passwordEncoder;

public Users createUser(@RequestBody Users userEntity) {    
    userEntity.setPassword(passwordEncoder.encode(userEntity.getPassword()));
    return userRepo.save(userEntity);
}