在授权期间遇到缓存问题,我无法弄清楚。这样在授权期间每次不向数据库发出请求时,我都想缓存该方法。在缓存为空的第一个请求中,一切都很好,直到一段时间后缓存被删除。但是当缓存在那里时,我得到 401,因为 o.s.s.c.bcrypt.BCryptPasswordEncoder: Empty encoded password,密码每次都是空的。怎么会这样?
@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
出于安全原因,将在使用后清除其密码。
缓存是针对对象实例而不是原始数据完成的,因此它也会在缓存中被清除。
如果您使用的是 JPA,则最好使用 JPA 提供程序的二级缓存集成而不是外部缓存。
关于java - 在 UserDetailsService 中使用 @Cacheable 时清空编码密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65177102/