Spring security - why does RoleVoter supports all classes and WebExpressionVoter only supports subclasses of FilterInvocation?
spring, spring-3, spring-security
Solution
The `secured object` is an abstract representing whatever is secured. It may be a `MethodInvocation` in case of `@Secured`, `@RolesAllowed`, `@PreFilter` and `@PreAuthorize`, or a `FilterInvocation` in case of `<intercept-url />` or any other object if required.
The `@PreFilter` and `@PreAuthorize` annotations are handled by `PreInvocationAuthorizationAdviceVoter`. It uses the `MethodInvocation` to get the annotations and their attributes values, so it has:
public boolean supports(Class<?> clazz) {
return clazz.isAssignableFrom(MethodInvocation.class);
}
The `WebExpressionVoter` is web-invocation specific, because it matches the URL to the patterns from `<intercept-url />`, that's why it has:
public boolean supports(Class<?> clazz) {
return clazz.isAssignableFrom(FilterInvocation.class);
}
The `RoleVoter` only uses the `Authentication` object contents, so it does not depend on the `secured object`, and that's why it has:
public boolean supports(Class<?> clazz) {
return true;
}
Note, that You can have a separate `AccessDecisionManager` for URL level security and method level security. The first will use voters that support `FilterInvocation`, and the other the ones that support `MethodInvocation`. Also note that `RoleVoter` supports both so it can be used in both contexts.
Problem
In the `supports(Class clazz)` method of `RoleVoter`, it always returns true saying that This implementation supports any type of class, because it does not query the presented secure object. What is this "presented secure object". On the other hand, the `supports(Class clazz)` method of `WebExpressionVoter` returns true only if `clazz` is a subtype of `FilterInvocation`. Is `FilterInvocation` the "presented secure object" here and why does the voter has to support it ? If I use `@Secured` annotations over my methods and configure an access decision manager for global method security that has `WebExpressionVoter` as one of the voters, it presents an error AccessDecisionManager does not support secure object class: interface org.aopalliance.intercept.MethodInvocation This is because all voters of an access decision manager (when configured for method security) must support the above class, and while `RoleVoter` and others do, `WebExpressionVoter` needs a subtype of `FilterInvocation`. `SPEL` expressions in `@PreAuthorize` tag would also need `WebExpressionVoter`, and again it would be required to support `MethodInvocation` class, which it doesn't. But it does work. So what am I getting wrong here ?