This is apparently a bug in the recently added OAuth2AutoConfiguration . In particular, it brings an OAuth2MethodSecurityConfiguration , which overrides the OAuth2MethodSecurityExpressionHandler using an OAuth2MethodSecurityExpressionHandler that does not have a BeanResolver set.
If you are not using OAuth2, the easiest solution is to remove Spring Security OAuth from your class path.
Alternatively, you can exclude OAuth2AutoConfiguration using the following if you use @SpringBootApplication :
@SpringBootApplication(exclude=OAuth2AutoConfiguration.class)
alternatively, you can use the following if you use @AutoConfiguration directly:
@AutoConfiguration(exclude=OAuth2AutoConfiguration.class)
UPDATE
You can also use something like this:
public class DelegatingMethodSecurityExpressionHandler implements MethodSecurityExpressionHandler { private final MethodSecurityExpressionHandler delegate; public DelegatingMethodSecurityExpressionHandler( MethodSecurityExpressionHandler delegate) { super(); this.delegate = delegate; } public Object filter(Object filterTarget, Expression filterExpression, EvaluationContext ctx) { return delegate.filter(filterTarget, filterExpression, ctx); } public ExpressionParser getExpressionParser() { return delegate.getExpressionParser(); } public EvaluationContext createEvaluationContext( Authentication authentication, MethodInvocation invocation) { return delegate.createEvaluationContext(authentication, invocation); } public void setReturnObject(Object returnObject, EvaluationContext ctx) { delegate.setReturnObject(returnObject, ctx); } }
Then in your configuration use:
@Autowired(required = false) List<AuthenticationTrustResolver> trustResolvers = new ArrayList<>(); @Autowired(required = false) List<PermissionEvaluator> permissionEvaluators = new ArrayList<>(); @Bean public MethodSecurityExpressionHandler securityExpressionHandler(ApplicationContext context) { OAuth2MethodSecurityExpressionHandler delegate = new OAuth2MethodSecurityExpressionHandler(); delegate.setApplicationContext(context); if(trustResolvers.size() == 1) { delegate.setTrustResolver(trustResolvers.get(0)); } if(permissionEvaluators.size() == 1) { delegate.setPermissionEvaluator(permissionEvaluators.get(0)); } return new DelegatingMethodSecurityExpressionHandler(delegate); }
We need to wrap it in a DelegatingMethodSecurityExpressionHandler because Spring AutoConfiguration boot will replace any subclass of DefaultMethodSecurityExpressionHandler broken configuration.