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
AuthorityReactiveAuthorizationManager compares GrantedAuthority instances using Object.equals instead of comparing the String value returned by getAuthority()
#10596
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
Describe the bug
When using custom implementations of GrantedAuthority with a custom AuthenticationManager, they will not be authorized, even though they contain the correct authority.
While debugging this behavior I found the following method implementation in AuthorityReactiveAuthorizationManager. I added some extra comments.
@OverridepublicMono<AuthorizationDecision> check(Mono<Authentication> authentication, Tobject) {
returnauthentication.filter((a) -> a.isAuthenticated())
// Flat mapping to Flux<? extends GrantedAuthority>
.flatMapIterable(Authentication::getAuthorities)
// Checking if this.authorities contains any value from the Flux.
.any(this.authorities::contains)
.map((granted) -> ((AuthorizationDecision) newAuthorityAuthorizationDecision(granted, this.authorities)))
.defaultIfEmpty(newAuthorityAuthorizationDecision(false, this.authorities));
}
The line .any(this.authorities::contains) actually uses Objects.equals() to compare the elements from the flux to the elements in this.authorities. Since GrantedAuthority is an interface the acutal behavior of equals() depends on the implementation. AuthorityReactiveAuthorizationManager uses SimpleGrantedAuthority as implementation for this.authorities, which implement equals() as follows and in a way that excludes other implementations of GrantedAuthority altogether.
@Overridepublicbooleanequals(Objectobj) {
if (this == obj) {
returntrue;
}
if (objinstanceofSimpleGrantedAuthority) {
returnthis.role.equals(((SimpleGrantedAuthority) obj).role);
}
returnfalse;
}
To Reproduce
Create own subclass of GrantedAuthority.
Implement getAuthority() method, returing a String value of e.g. "SOMETHING".
Implement custom AuthenticationManager that authenticates a request, returning an Authentication instance containing a GrantedAuthority with value "SOMETHING" and isAuthenticated() == true.
Configure ServerHttpSecurity to authorize requests on some path to be only allowed with authority "SOMETHING"
AuthorityReactiveAuthorizationManager should not compare instances of GrantedAuthority using Objects.equals by utilizing .any(this.authorities::contains), but instead compare the String values returned from getAuthority().
When using instances of SimpleGrantedAuthority for own authentications, the authorization works because of the specific implementation of equals() in that class.
Sample
None yet. If the description is not sufficient enough, I can provide a sample.
The text was updated successfully, but these errors were encountered:
Uh oh!
There was an error while loading. Please reload this page.
Describe the bug
When using custom implementations of GrantedAuthority with a custom AuthenticationManager, they will not be authorized, even though they contain the correct authority.
While debugging this behavior I found the following method implementation in
AuthorityReactiveAuthorizationManager
. I added some extra comments.The line
.any(this.authorities::contains)
actually usesObjects.equals()
to compare the elements from the flux to the elements inthis.authorities
. SinceGrantedAuthority
is an interface the acutal behavior ofequals()
depends on the implementation.AuthorityReactiveAuthorizationManager
usesSimpleGrantedAuthority
as implementation forthis.authorities
, which implementequals()
as follows and in a way that excludes other implementations ofGrantedAuthority
altogether.To Reproduce
GrantedAuthority
.getAuthority()
method, returing aString
value of e.g."SOMETHING"
.AuthenticationManager
that authenticates a request, returning anAuthentication
instance containing aGrantedAuthority
with value"SOMETHING"
andisAuthenticated() == true
.ServerHttpSecurity
to authorize requests on some path to be only allowed with authority"SOMETHING"
Expected behavior
Requested should be authorized.
AuthorityReactiveAuthorizationManager
should not compare instances ofGrantedAuthority
usingObjects.equals
by utilizing.any(this.authorities::contains)
, but instead compare theString
values returned fromgetAuthority()
.When using instances of
SimpleGrantedAuthority
for own authentications, the authorization works because of the specific implementation ofequals()
in that class.Sample
None yet. If the description is not sufficient enough, I can provide a sample.
The text was updated successfully, but these errors were encountered: