@Autowired in Spring PermissionEvaluator

spring, spring-aop, spring-boot, spring-security

Solution

Nothing can be autowired into an object that is created with `new ...()` (unless you are using `@Configurable` and AspectJ). So you almost certainly need to pull your `PermissionEvaluator` out into a `@Bean`. If you need to make it a lazy proxy as well (because of the ordering sensitivity of Spring Security initialization), then you should add `@Lazy @Scope(proxyMode=INTERFACES)` (or `TARGET_CLASS` if that suits you better).

Problem

First off I have googled this extensively and while it appears that there is supposedly a fix in place I cannot successfully reference an injected `@Bean` inside of a `PermissionEvaluator`: https://jira.springsource.org/browse/SEC-2136?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel In that issue's comments section Rob Winch provides a work around suggestion to work around this issue, you can proxy your permissionEvaluator using LazyInitTargetSource That being said, I am having trouble implementing the annotation-based JavaConfig version of the posted XML. I am using Spring Boot 1.0.0.BUILD-SNAPSHOT and spring-boot-starter-security. I have a class to configure method security as follows: ``` @Configuration @EnableGlobalMethodSecurity(prePostEnabled = true) public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration { @Override protected MethodSecurityExpressionHandler createExpressionHandler() { DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler(); expressionHandler.setPermissionEvaluator(new MyPermissionEvaluator()); expressionHandler.setParameterNameDiscoverer(new SimpleParameterDiscoverer()); return expressionHandler; } } ``` And the start of a `PermissionEvaluator`: ``` public class MyPermissionEvaluator implements PermissionEvaluator { private static final Logger LOG = LoggerFactory.getLogger(MyPermissionEvaluator.class); @Autowired private UserRepository userRepo; @Override public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) { if (authentication == null || !authentication.isAuthenticated()) { return false; } if (permission instanceof String) { switch((String) permission) { case "findUser": return handleUserPermission(authentication, targetDomainObject); default: LOG.error("No permission handler found for permission: " + permission); } } return false; } @Override public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) { throw new RuntimeException("Id-based permission evaluation not currently supported."); } private boolean handleUserPermission(Authentication auth, Object targetDomainObject) { if (targetDomainObject instanceof Long) { boolean hasPermission = userRepo.canFind((Long) targetDomainObject); return hasPermission; } return false; } } ``` What needs to be done so that I can get a reference to my `UserRepository` from inside the `PremissionEvaluator`? I've attempted various workarounds w/ no success. It seems that nothing can be `@Autowired` into the `PermissionEvaluator`...

Original source