java - 在 UserDetailsS​​ervice 中使用 @Cacheable 时清空编码密码

标签 java spring-boot spring-security

在授权期间遇到缓存问题,我无法弄清楚。这样在授权期间每次不向数据库发出请求时,我都想缓存该方法。在缓存为空的第一个请求中,一切都很好,直到一段时间后缓存被删除。但是当缓存在那里时,我得到 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());
    }
}

enter image description here

最佳答案

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

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

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

关于java - 在 UserDetailsS​​ervice 中使用 @Cacheable 时清空编码密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65177102/

相关文章:

java - 为什么我会收到 InvocationTargetException?安卓2D游戏

java - 数组似乎在 Java 中通过引用传递,这怎么可能?

java - 使用 Spring JPA 加载更多功能

javascript - 如何防止表单的只读字段数据?

java - com.fasterxml.jackson.core.util.InternCache.intern() 高负载下死锁

java - 单击textview时编辑SQLite数据

java - Spring Boot 1.5.2.RELEASE 数据库支持的 session

java - 在 spring 中将值从 Controller 传递到 html

spring-security - Spring Security SAML 与 Spring session

spring - 使用 Spring security 配置 Spring MVC 应用程序的好习惯是什么?