Skip to content

Commit 5eadcba

Browse files
evgeniychebanjzheaux
authored andcommitted
Add RoleHierarchy to AuthorityAuthorizationManager
Added roleHierarchy field to AuthorityAuthorizationManager that defaults to NullRoleHierarchy along with setter method to override. Closes gh-11304
1 parent b9acdd5 commit 5eadcba

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

core/src/main/java/org/springframework/security/authorization/AuthorityAuthorizationManager.java

+21-1
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@
1616

1717
package org.springframework.security.authorization;
1818

19+
import java.util.Collection;
1920
import java.util.List;
2021
import java.util.Set;
2122
import java.util.function.Supplier;
2223

24+
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
25+
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
2326
import org.springframework.security.core.Authentication;
2427
import org.springframework.security.core.GrantedAuthority;
2528
import org.springframework.security.core.authority.AuthorityUtils;
@@ -39,10 +42,23 @@ public final class AuthorityAuthorizationManager<T> implements AuthorizationMana
3942

4043
private final List<GrantedAuthority> authorities;
4144

45+
private RoleHierarchy roleHierarchy = new NullRoleHierarchy();
46+
4247
private AuthorityAuthorizationManager(String... authorities) {
4348
this.authorities = AuthorityUtils.createAuthorityList(authorities);
4449
}
4550

51+
/**
52+
* Sets the {@link RoleHierarchy} to be used. Default is {@link NullRoleHierarchy}.
53+
* Cannot be null.
54+
* @param roleHierarchy the {@link RoleHierarchy} to use
55+
* @since 5.8
56+
*/
57+
public void setRoleHierarchy(RoleHierarchy roleHierarchy) {
58+
Assert.notNull(roleHierarchy, "roleHierarchy cannot be null");
59+
this.roleHierarchy = roleHierarchy;
60+
}
61+
4662
/**
4763
* Creates an instance of {@link AuthorityAuthorizationManager} with the provided
4864
* authority.
@@ -133,14 +149,18 @@ private boolean isGranted(Authentication authentication) {
133149

134150
private boolean isAuthorized(Authentication authentication) {
135151
Set<String> authorities = AuthorityUtils.authorityListToSet(this.authorities);
136-
for (GrantedAuthority grantedAuthority : authentication.getAuthorities()) {
152+
for (GrantedAuthority grantedAuthority : getGrantedAuthorities(authentication)) {
137153
if (authorities.contains(grantedAuthority.getAuthority())) {
138154
return true;
139155
}
140156
}
141157
return false;
142158
}
143159

160+
private Collection<? extends GrantedAuthority> getGrantedAuthorities(Authentication authentication) {
161+
return this.roleHierarchy.getReachableGrantedAuthorities(authentication.getAuthorities());
162+
}
163+
144164
@Override
145165
public String toString() {
146166
return "AuthorityAuthorizationManager[authorities=" + this.authorities + "]";

core/src/test/java/org/springframework/security/authorization/AuthorityAuthorizationManagerTests.java

+37-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2022 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -21,6 +21,9 @@
2121

2222
import org.junit.jupiter.api.Test;
2323

24+
import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy;
25+
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
26+
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
2427
import org.springframework.security.authentication.TestingAuthenticationToken;
2528
import org.springframework.security.core.Authentication;
2629
import org.springframework.security.core.GrantedAuthority;
@@ -211,4 +214,37 @@ public void hasAnyAuthorityWhenUserHasNotAnyAuthorityThenDeniedDecision() {
211214
assertThat(manager.check(authentication, object).isGranted()).isFalse();
212215
}
213216

217+
@Test
218+
public void setRoleHierarchyWhenNullThenIllegalArgumentException() {
219+
AuthorityAuthorizationManager<Object> manager = AuthorityAuthorizationManager.hasRole("USER");
220+
assertThatIllegalArgumentException().isThrownBy(() -> manager.setRoleHierarchy(null))
221+
.withMessage("roleHierarchy cannot be null");
222+
}
223+
224+
@Test
225+
public void setRoleHierarchyWhenNotNullThenVerifyRoleHierarchy() {
226+
AuthorityAuthorizationManager<Object> manager = AuthorityAuthorizationManager.hasRole("USER");
227+
RoleHierarchy roleHierarchy = new RoleHierarchyImpl();
228+
manager.setRoleHierarchy(roleHierarchy);
229+
assertThat(manager).extracting("roleHierarchy").isEqualTo(roleHierarchy);
230+
}
231+
232+
@Test
233+
public void getRoleHierarchyWhenNotSetThenDefaultsToNullRoleHierarchy() {
234+
AuthorityAuthorizationManager<Object> manager = AuthorityAuthorizationManager.hasRole("USER");
235+
assertThat(manager).extracting("roleHierarchy").isInstanceOf(NullRoleHierarchy.class);
236+
}
237+
238+
@Test
239+
public void hasRoleWhenRoleHierarchySetThenGreaterRoleTakesPrecedence() {
240+
AuthorityAuthorizationManager<Object> manager = AuthorityAuthorizationManager.hasRole("USER");
241+
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
242+
roleHierarchy.setHierarchy("ROLE_ADMIN > ROLE_USER");
243+
manager.setRoleHierarchy(roleHierarchy);
244+
Supplier<Authentication> authentication = () -> new TestingAuthenticationToken("user", "password",
245+
"ROLE_ADMIN");
246+
Object object = new Object();
247+
assertThat(manager.check(authentication, object).isGranted()).isTrue();
248+
}
249+
214250
}

0 commit comments

Comments
 (0)