从安全上下文中获取当前经过身份验证的用户作为Spring Cache的密钥



我有一个没有参数的方法,我想缓存返回值。作为缓存密钥,我想使用来自安全上下文的当前已验证用户

@Cacheable(value = "resultCache", key="#userPrincipal.id")
public result getResult() {}

有可能吗?或者我的想法错了。

您有四个选项可以实现这一点:

  1. Authentication对象作为方法参数发送:

    @Cacheable(value = "resultCache", key="#authentication.name")
    public Result getResult(Authentication authentication) {}
    
  2. 创建自定义KeyGenerator并在@Cacheable注释中使用

    public class CustomKeyGenerator implements KeyGenerator {
    @Override
    public Object generate(Object target, Method method, Object... params) {
    return SecurityContextHolder.getContext().getAuthentication().getName();
    }
    }
    @Configuration
    @EnableCaching
    public class CacheConfiguration {
    @Bean("customKeyGenerator")
    public KeyGenerator customKeyGenerator() {
    return new CustomKeyGenerator();
    }
    }
    @Cacheable(value = "resultCache", keyGenerator="customKeyGenerator")
    public Result getResult() {}
    
  3. 创建一个bean,该bean为您提供密钥并通过key属性中的SPeL引用它。我建议您采用这种方法,因为它可以让您稍后更容易地更改值。

    @Component
    public class CacheKeyProvider {
    public String getUsernameKey() {
    return SecurityContextHolder.getContext().getAuthentication().getName();
    }
    }
    @Cacheable(value = "resultCache", key="@cacheKeyProvider.getUsernameKey()")
    public Result getResult() {}
    
  4. 使用Type SpEL表达式

    @Cacheable(value = "resultCache", key="T(org.springframework.security.core.context.SecurityContextHolder.getContext()?.authentication?.name)")
    public Result getResult() {}
    

请注意,我在示例中使用了Principal中的name属性。但是,如果您有一个自定义的Principal对象,您可以强制转换它并返回您想要的任何属性。

最新更新