【问题标题】:Spring Data Rest user repository BCCrypt passwordSpring Data Rest 用户存储库 BCCrypt 密码
【发布时间】:2015-07-26 20:49:08
【问题描述】:

我有一个 spring data rest 自定义用户存储库,其中的密码需要使用 BCCrypt 进行加密。从我发送纯密码的 UI 中,我想知道在休眠在 DB 中创建用户之前将纯密码转换为 BCCrypt 哈希的位置。我应该在保存拦截器和散列密码之前使用吗?或者有什么办法可以告诉spring使用密码编码器?

【问题讨论】:

    标签: spring spring-boot spring-security spring-data-jpa spring-data-rest


    【解决方案1】:

    在 Spring Data Rest 中拦截插入的方法是使用事件处理程序。

    注意:此代码不适用于不包含密码字段的 PATCH 操作。

    @Component
    @RepositoryEventHandler(User.class)
    public class UserEventHandler {
    
      @Autowired 
      private BCryptPasswordEncoder passwordEncoder;
    
      @Autowired 
      private UserRepository userRepository;
    
      @HandleBeforeCreate     
      public void handleUserCreate(User user) {
        user.setPassword(passwordEncoder.encode(user.getPassword()));
      }
    
      @HandleBeforeSave
      public void handleUserUpdate(User user) {
        if (user.getPassword() == null || user.getPassword().equals("")) {
            //keeps the last password
            User storedUser = userRepository.getOne(user.getId());
            user.setPassword(storedUser.getPassword());
        }
        else {
            //password change request
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
      }
    }
    

    【讨论】:

    • 用户存在时怎么办,密码是否更新?
    • @DavidRiccitelli 然后你应该实现一个用“@HandleBeforeSave”注释的类似方法
    • HandleBeforeSave 仅通过更新(PATCH 和 PUT)而不是插入(POST)调用,因此您可以执行不同的实现。我用该方法的实现更新了我的回复。
    • 确实如此。我结束了总是使用 PUT,因为 Spring Data Rest PATCH 不是非常 RESTful 标准,而且我遇到了其他问题。顺便说一句,您可以在 PATCH 操作中始终发送一个空密码(密码更改请求除外),因此它不会从数据库中填充。
    • 很抱歉,但我认为这不能称为解决方案。您基本上是在禁止其他任何人使用您的 API。问题是不是 Spring Data REST,而是您提出的解决方案。您应该在密码字段上使用自定义 JsonDeserializer 并在反序列化 JSON 时加密传入的密码,请参阅stackoverflow.com/questions/30260582/…
    【解决方案2】:

    您需要在您的Registration-Service 中执行此操作,如下所示:

        @Autowired 
        private BCryptPasswordEncoder passwordEncoder;
        ...
        public void registerUser(final User user)
        {
            final String encodedPassword = passwordEncoder.encode(user.getPassword());
            user.setPassword(encodedPassword);
            userRepo.save(user);
        }
    

    我推荐给你的密码编码器是org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder,这个编码器会自动为你生成盐。

    【讨论】:

    • 如果你使用 Spring-Data-Rest 你不会碰到任何服务层?使用隐式 Spring-Data-Rest 控制器时,如何在存储库之前插入此服务?
    • @ManuZi 你能解决这个问题吗?我知道我可以实现一个服务层,对持久性工作进行编码并将其委托给存储库,但我正在寻找一种更优雅、更轻量级的解决方案,它只使用隐式 JPA 存储库。我们能以某种方式配置 JPA 来做到这一点吗?
    • 我认为没有其他“优雅”的方法可以解决这个问题。
    猜你喜欢
    • 2017-04-30
    • 1970-01-01
    • 2017-10-18
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-27
    相关资源
    最近更新 更多