Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get current authenticated user from security context as key for Spring Cache

I have method without parameters and I want to cache return value. As cache key I want to use current authenticated user from security context

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

Is it possible or my idea is wrong.

like image 931
Png Avatar asked Oct 19 '25 13:10

Png


1 Answers

You have four options to achieve this:

  1. Send the Authentication object as a method parameter:

    @Cacheable(value = "resultCache", key="#authentication.name")
    public Result getResult(Authentication authentication) {}
    
  2. Create a custom KeyGenerator and use it in your @Cacheable annotation

    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. Create a bean that provides you the key and references it via SPeL in the key property. I would recommend you going for this approach since it allows you to change the value later more easily.

    @Component
    public class CacheKeyProvider {
    
        public String getUsernameKey() {
            return SecurityContextHolder.getContext().getAuthentication().getName();
        }
    }
    
    @Cacheable(value = "resultCache", key="@cacheKeyProvider.getUsernameKey()")
    public Result getResult() {}
    
  4. Use the Type SpEL expression

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

Note that I used the name property from the Principal in the examples. But if you have a custom Principal object you can cast it and return any property you want.

like image 186
Marcus Hert da Coregio Avatar answered Oct 22 '25 02:10

Marcus Hert da Coregio



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!