You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I did not know whether to log this as a bug or an enhancement, but it feels more like a bug to me. Either in the migration documentation or in code. :-)
Describe the bug
Given 2 AuthorizationManagers/DecisionVoters:
AffirmativeBased way of working denies access when the first DecisionVoterabstains and the second denies.
AuthorizationManagers.anyOf(...) allows access when the first AuthorizationManagerabstains.
To Reproduce
I believe there is a small difference in the implementation between AffirmativeBased and AuthorizationManagers.anyOf().
More precisely in handling AccessDecisionVoter.ABSTAIN vs a null instance of AuthorizationDecision.
AffirmativeBased.java
public void decide(Authentication authentication, Object object, Collection<ConfigAttribute> configAttributes)
throws AccessDeniedException {
int deny = 0;
for (AccessDecisionVoter voter : getDecisionVoters()) {
int result = voter.vote(authentication, object, configAttributes);
switch (result) {
case AccessDecisionVoter.ACCESS_GRANTED:
return;
case AccessDecisionVoter.ACCESS_DENIED:
deny++;
break;
default:
break; // --> Continues the loop and checks all DecisionVoters.
}
}
if (deny > 0) {
throw new AccessDeniedException(
this.messages.getMessage("AbstractAccessDecisionManager.accessDenied", "Access is denied"));
}
// To get this far, every AccessDecisionVoter abstained
checkAllowIfAllAbstainDecisions();
}
AuthorizationManagers.java
public static <T> AuthorizationManager<T> anyOf(AuthorizationManager<T>... managers) {
return (authentication, object) -> {
List<AuthorizationDecision> decisions = new ArrayList<>();
for (AuthorizationManager<T> manager : managers) {
AuthorizationDecision decision = manager.check(authentication, object);
if (decision == null || decision.isGranted()) {
return decision; // --> Shortcuts the whole decision making process. Basically says ABSTAIN == GRANTED
}
decisions.add(decision);
}
return new CompositeAuthorizationDecision(false, decisions);
};
}
Expected behavior
The behavior should be the same, or the migration docs should state that the implementations are not equivalent.
The text was updated successfully, but these errors were encountered:
Hi, @KaVeKal. I agree that this is a bug in AuthorizationManagers#anyOf, but I also see a bug in the docs related to allOf. anyOf should return true only if any of the non-abstaining delegates return true. allOf should return true only if all of the non-abstaining delegates return true.
I'll update the code as well as the docs accordingly.
Also, I'm thinking that it would be good to introduce a configuration option to clarify what should be done when all delegates abstain. I've created #13085 to address that.
I did not know whether to log this as a bug or an enhancement, but it feels more like a bug to me. Either in the migration documentation or in code. :-)
Describe the bug
Given 2 AuthorizationManagers/DecisionVoters:
AffirmativeBased
way of working denies access when the firstDecisionVoter
abstains and the second denies.AuthorizationManagers.anyOf(...)
allows access when the firstAuthorizationManager
abstains.To Reproduce
I believe there is a small difference in the implementation between
AffirmativeBased
andAuthorizationManagers.anyOf()
.More precisely in handling
AccessDecisionVoter.ABSTAIN
vs anull
instance ofAuthorizationDecision
.AffirmativeBased.java
AuthorizationManagers.java
Expected behavior
The behavior should be the same, or the migration docs should state that the implementations are not equivalent.
The text was updated successfully, but these errors were encountered: