在 UserDetailsS​​ervice 中使用 @Cacheable 时编码密码为空

2024-02-24

在授权期间遇到缓存问题,我无法弄清楚。因此,在授权期间,每次不向数据库发出请求时,我都想缓存该方法。在第一次请求时缓存为空,一切都很好,直到缓存在一段时间后被删除。但是当缓存存在时,我得到 401,因为 o.s.s.c.bcrypt.BCryptPasswordEncoder:空编码密码,密码每次都是空的。遇到这样的情况怎么办?

   @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 SecurityUser https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/userdetails/User.html as the UserDetails执行。这实现了CredentialsContainer https://docs.spring.io/spring-security/site/docs/current/api/org/springframework/security/core/CredentialsContainer.html出于安全原因,使用后密码将被清除。

缓存是针对对象实例而不是原始数据进行的,因此它也会在缓存中被清除。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 UserDetailsS​​ervice 中使用 @Cacheable 时编码密码为空 的相关文章

随机推荐