我有一个使用 javax.annotation.security 中的 @RolesAllowed 注释的方法,该方法由现有方面使用。
我们正在向我们的服务层添加弹簧缓存支持。缓存工作得很好,但我们注意到方法上的任何 @Cach* 注释都不会被击中。
这是方法签名。
@Override
@RolesAllowed(Roles.VIEW_DATA)
@Cacheable(CacheConstants.DATATYPE_CACHENAME_PREFIX)
public List<Data> list(ListParams params)
这是我的缓存配置。我们正在使用 spring boot 1.5.14 AutoConfig。
@EnableAspectJAutoProxy(proxyTargetClass = true)
@EnableConfigurationProperties
@EnableCaching
@SpringBootApplication
public class Application {
我已经尝试使用 proxyTargetClass = true 和 mode = aspectJ 的 @EnableCaching。两者都没有工作。mode = aspectJ 导致 @RolesAllowed 注释再次起作用,但随后 @Cacheable 被忽略。
这是存在 @Cacheable 时不再受到影响的方面。
@Aspect
@Component
public class ApplicationSecurityMethodInterceptor {
@Autowired
private MethodSecurityMetadataSource methodSecurityMetadataSource;
@Autowired
private AccessDecisionManager methodAccessDecisionManager;
private static final Logger LOGGER = Logger.getLogger(ApplicationSecurityMethodInterceptor.class);
private static final String SCANNED_PACKAGE = "com.company.portal.service";
private static final String INTERCEPT_EXPRESSION = "within(" + SCANNED_PACKAGE + "..*)";
@Before(INTERCEPT_EXPRESSION)
public void intercept(JoinPoint joinPoint) {
if (joinPoint == null) return;
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
if (signature == null) return;
Method method = signature.getMethod();
if (method == null) return;
Object target = joinPoint.getTarget();
if (target == null) return;
Class targetClass = joinPoint.getTarget().getClass();
if (targetClass == null) return;
Collection<ConfigAttribute> attributes = methodSecurityMetadataSource.getAttributes(method, targetClass);
if (CollectionUtils.isEmpty(attributes)) return;
LOGGER.debug(String.format("Intercepting method:[%s.%s], attributes:[%s]",
targetClass.getName(), method.getName(), attributes));
MethodInvocation mi = new SimpleMethodInvocation(target, method, joinPoint.getArgs());
methodAccessDecisionManager.decide(SecurityContextHolder.getContext().getAuthentication(), mi, attributes);
}
}