The DefaultMethodSecurityExpressionHandler.createEvaluationContext method calls private access createSecurityExpressionRoot instead of protected one. Classes extending DefaultMethodSecurityExpressionHandler always create MethodSecurityExpressionRoot instead of provided custom implementation in the overriden protected createSecurityExpressionRoot method. MethodSecurityEvaluationContext has package access which makes it even harder to extend DefaultMethodSecurityExpressionHandlerlogic:
@Override
public EvaluationContext createEvaluationContext(Supplier<Authentication> authentication, MethodInvocation mi) {
MethodSecurityExpressionOperations root = createSecurityExpressionRoot(authentication, mi); //<- private method call
MethodSecurityEvaluationContext ctx = new MethodSecurityEvaluationContext(root, mi,
getParameterNameDiscoverer());
ctx.setBeanResolver(getBeanResolver());
return ctx;
}
/**
* Creates the root object for expression evaluation.
*/
@Override //<- this method is never called when overriden in subclass
protected MethodSecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication,
MethodInvocation invocation) {
return createSecurityExpressionRoot(() -> authentication, invocation);
}
private MethodSecurityExpressionOperations createSecurityExpressionRoot(Supplier<Authentication> authentication,
MethodInvocation invocation) {
MethodSecurityExpressionRoot root = new MethodSecurityExpressionRoot(authentication);
root.setThis(invocation.getThis());
root.setPermissionEvaluator(getPermissionEvaluator());
root.setTrustResolver(getTrustResolver());
root.setRoleHierarchy(getRoleHierarchy());
root.setDefaultRolePrefix(getDefaultRolePrefix());
return root;
}
Comment From: jzheaux
Closing as a duplicate of https://github.com/spring-projects/spring-security/issues/12331