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

Posted

技术标签:

【中文标题】从安全上下文中获取当前经过身份验证的用户作为 Spring Cache 的密钥【英文标题】:Get current authenticated user from security context as key for Spring Cache 【发布时间】:2021-08-16 16:57:33 【问题描述】:

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

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

有可能还是我的想法错了。

【问题讨论】:

【参考方案1】:

您有四种选择来实现这一目标:

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

    @Cacheable(value = "resultCache", key="#authentication.name")
    public Result getResult(Authentication authentication) 
    

    创建一个自定义 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() 
    

    创建一个 bean,为您提供密钥并通过 key 属性中的 SPeL 引用它。我建议您采用这种方法,因为它可以让您以后更轻松地更改值。

    @Component
    public class CacheKeyProvider 
    
        public String getUsernameKey() 
            return SecurityContextHolder.getContext().getAuthentication().getName();
        
    
    
    @Cacheable(value = "resultCache", key="@cacheKeyProvider.getUsernameKey()")
    public Result getResult() 
    

    使用Type SpEL expression

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

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

【讨论】:

非常感谢。最后一个解决方案是我一直在寻找的,因为我不想更改我的方法签名。

以上是关于从安全上下文中获取当前经过身份验证的用户作为 Spring Cache 的密钥的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Vuejs 和 Laravel 获取当前经过身份验证的用户 ID?

从 Symfony3 中经过身份验证的用户 (HWIOAuth) 获取 Angular2 中的 JWT 令牌

Spring-Security:优化获取当前经过身份验证的用户...

如何在 Node.js 中从请求参数获取经过身份验证的用户到 socket.io

如何从 FormRequest 类方法中访问当前经过身份验证的用户

从 Blazor 应用中的中间件类获取经过身份验证的用户