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 ?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With