在 UserDetailsS​​ervice 中使用 @Cacheable 时清空编码密码 [英] Empty encoded password when using @Cacheable in UserDetailsService

查看:22
本文介绍了在 UserDetailsS​​ervice 中使用 @Cacheable 时清空编码密码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在授权过程中遇到缓存问题,我想不通.因此,在授权期间,每次不对数据库发出请求时,我都想缓存该方法.在第一个缓存为空的请求时,一切都很好,直到缓存在一段时间后被删除.但是当缓存在那里时,我得到 401,因为 o.s.s.c.bcrypt.BCryptPasswordEncoder:空编码密码,每次密码都是空的.怎么会遇到这种情况?

Faced a problem with caching during authorization, I can't figure it out. So that during authorization every time a request is not made to the database, I want to cache the method. At the first request with an empty cache, everything is fine and until the cache is deleted after a time. But while the cache is there, I get 401, because o.s.s.c.bcrypt.BCryptPasswordEncoder: Empty encoded password, the password is empty every time. How to be in such a situation?

   @Override
    @Transactional
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        log.debug("Load user {}", username);
        return userService.findUserDetailsByName(username).orElseThrow(() -> new UsernameNotFoundException(username));
    }
 
    @Cacheable(cacheNames = Caches.USER_DETAILS_CACHE)
    public Optional<UserDetails> findUserDetailsByName(String username) {
            Optional<UserDetails> userDetailsOpt =
                    userRepository.findOne(QUser.user.userName.eq(username)).map(UserService::createFrom);
            return userDetailsOpt.map(u -> withUserDetails(u).build());
    }
 
@Configuration(proxyBeanMethods = false)
@EnableCaching
@RequiredArgsConstructor
public class CacheConfiguration {
    @Bean
    public CacheManager cacheManager(Ticker ticker, @Value("${app.cache.user.ttl}") Duration userTtl) {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        List<CaffeineCache> caches = new ArrayList<>();
        caches.add(buildCache(Caches.USER_DETAILS_CACHE, ticker, userTtl, 1));
        cacheManager.setCaches(caches);
        return cacheManager;
    }
 
    @Bean
    public Ticker ticker() {
        return Ticker.systemTicker();
    }
 
    private static CaffeineCache buildCache(String name, Ticker ticker, Duration ttl, int size) {
        return new CaffeineCache(name, Caffeine.newBuilder()
                .expireAfterWrite(ttl)
                .ticker(ticker)
                .maximumSize(size)
                .build());
    }
}

推荐答案

假设您使用的是默认的 Spring Security User 作为 UserDetails 实现.这实现了 CredentialsContainer 出于安全原因,使用后将清除其密码.

Assuming you are using the default Spring Security User as the UserDetails implementation. This implements CredentialsContainer which will have its password cleared after use for security reasons.

缓存是为对象实例而不是原始数据完成的,因此它也会在缓存中被清除.

The caching is done for the object instance instead of raw data and thus it will be cleared in the cache as well.

如果您使用 JPA,则最好使用 JPA 提供程序的二级缓存集成,而不是外部缓存.

If you are using JPA you better use the 2nd level caching integration of your JPA provider instead of external caching.

这篇关于在 UserDetailsS​​ervice 中使用 @Cacheable 时清空编码密码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆