I'm trying to implement method security using Java Config, but I'm getting a error:-
org.springframework.expression.spel.SpelEvaluationException: EL1057E:(pos 1): No bean resolver registered in the context to resolve access to bean 'appPermissionEvaluator'
The method is:-
@PreAuthorize("@appPermissionEvaluator.hasSystemPermission()")
public String something() {
...
}
The Config class definition is (MethodSecurityConfig.java):-
@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MethodSecurityConfig extends GlobalMethodSecurityConfiguration {
@Bean
public AppPermissionEvaluator appPermissionEvaluator() {
return new AppPermissionEvaluator();
}
@Override
protected MethodSecurityExpressionHandler createExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler =
new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(appPermissionEvaluator());
return expressionHandler;
}
...
}
I checked that I'm able to autowire the bean in the same class, also I found the default hasPermission() methods are working as I've implemented them, the only problem is reading the bean from SpEL. I'm not sure what's wrong. Any Pointers?
I'm using Spring 4.1.5 and Spring security 3.2.7
You need to ensure that you set the ApplicationContext on the DefaultMethodSecurityExpresssionHandler. For example:
@Autowired
private ApplicationContext context;
// ...
@Override
protected MethodSecurityExpressionHandler expressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler =
new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(appPermissionEvaluator());
// !!!
expressionHandler.setApplicationContext(context);
return expressionHandler;
}
Alternatively and more concisely, if you define a single PermissionEvaluator as a Bean and Spring Security will automatically pick it up (no need to override expressionHandler()). For example:
@Bean
public PermissionEvaluator appPermissionEvaluator() {
...
}