From 3a14745d92991379cf3be40ef33c91b67861f36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20L=C3=BCck?= Date: Tue, 13 Jan 2026 12:59:33 +0100 Subject: [PATCH 1/2] Delegate calls of hasAuthority to AuthorizationManager#hasAuthority MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes gh-18486 Signed-off-by: Michael Lück --- .../security/access/expression/SecurityExpressionRoot.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java index e0c35f7c2d..408d2a7797 100644 --- a/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java +++ b/core/src/main/java/org/springframework/security/access/expression/SecurityExpressionRoot.java @@ -116,7 +116,7 @@ public abstract class SecurityExpressionRoot impleme @Override public final boolean hasAuthority(String authority) { - return isGranted(this.authorizationManagerFactory.hasAnyAuthority(authority)); + return isGranted(this.authorizationManagerFactory.hasAuthority(authority)); } @Override From 1575610d49fe105ae2cdaf0bf7d463f22945fee7 Mon Sep 17 00:00:00 2001 From: Josh Cummings <3627351+jzheaux@users.noreply.github.com> Date: Thu, 26 Feb 2026 17:08:15 -0700 Subject: [PATCH 2/2] Add Tests Issue gh-18486 Signed-off-by: Josh Cummings <3627351+jzheaux@users.noreply.github.com> --- .../SecurityExpressionRootTests.java | 148 ++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/core/src/test/java/org/springframework/security/access/expression/SecurityExpressionRootTests.java b/core/src/test/java/org/springframework/security/access/expression/SecurityExpressionRootTests.java index 2710ba7b5b..6d482e9ed8 100644 --- a/core/src/test/java/org/springframework/security/access/expression/SecurityExpressionRootTests.java +++ b/core/src/test/java/org/springframework/security/access/expression/SecurityExpressionRootTests.java @@ -21,6 +21,9 @@ import org.junit.jupiter.api.Test; import org.springframework.security.authentication.AuthenticationTrustResolver; import org.springframework.security.authentication.TestingAuthenticationToken; +import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.authorization.AuthorizationManagerFactory; +import org.springframework.security.authorization.SingleResultAuthorizationManager; import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.AuthorityUtils; @@ -28,6 +31,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; /** * @author Luke Taylor @@ -174,4 +178,148 @@ public class SecurityExpressionRootTests { assertThat(this.root.isAuthenticated()).isTrue(); } + // gh-18486 + @Test + @SuppressWarnings("unchecked") + public void hasAuthorityDelegatesToAuthorizationManagerFactoryHasAuthority() { + AuthorizationManagerFactory factory = mock(AuthorizationManagerFactory.class); + AuthorizationManager manager = SingleResultAuthorizationManager.denyAll(); + given(factory.hasAuthority("CUSTOM_AUTHORITY")).willReturn(manager); + this.root.setAuthorizationManagerFactory(factory); + assertThat(this.root.hasAuthority("CUSTOM_AUTHORITY")).isFalse(); + verify(factory).hasAuthority("CUSTOM_AUTHORITY"); + } + + // gh-18486 + @Test + @SuppressWarnings("unchecked") + public void hasAnyAuthorityDelegatesToAuthorizationManagerFactoryHasAnyAuthority() { + AuthorizationManagerFactory factory = mock(AuthorizationManagerFactory.class); + AuthorizationManager manager = SingleResultAuthorizationManager.denyAll(); + given(factory.hasAnyAuthority("CUSTOM_AUTHORITY")).willReturn(manager); + this.root.setAuthorizationManagerFactory(factory); + assertThat(this.root.hasAnyAuthority("CUSTOM_AUTHORITY")).isFalse(); + verify(factory).hasAnyAuthority("CUSTOM_AUTHORITY"); + } + + // gh-18486 + @Test + @SuppressWarnings("unchecked") + public void hasAllAuthoritiesDelegatesToAuthorizationManagerFactoryHasAllAuthorities() { + AuthorizationManagerFactory factory = mock(AuthorizationManagerFactory.class); + AuthorizationManager manager = SingleResultAuthorizationManager.denyAll(); + given(factory.hasAllAuthorities("A", "B")).willReturn(manager); + this.root.setAuthorizationManagerFactory(factory); + assertThat(this.root.hasAllAuthorities("A", "B")).isFalse(); + verify(factory).hasAllAuthorities("A", "B"); + } + + // gh-18486 + @Test + @SuppressWarnings("unchecked") + public void hasRoleDelegatesToAuthorizationManagerFactoryHasRole() { + AuthorizationManagerFactory factory = mock(AuthorizationManagerFactory.class); + AuthorizationManager manager = SingleResultAuthorizationManager.denyAll(); + given(factory.hasRole("CUSTOM_ROLE")).willReturn(manager); + this.root.setAuthorizationManagerFactory(factory); + assertThat(this.root.hasRole("CUSTOM_ROLE")).isFalse(); + verify(factory).hasRole("CUSTOM_ROLE"); + } + + // gh-18486 + @Test + @SuppressWarnings("unchecked") + public void hasAnyRoleDelegatesToAuthorizationManagerFactoryHasAnyRole() { + AuthorizationManagerFactory factory = mock(AuthorizationManagerFactory.class); + AuthorizationManager manager = SingleResultAuthorizationManager.denyAll(); + given(factory.hasAnyRole("A", "B")).willReturn(manager); + this.root.setAuthorizationManagerFactory(factory); + assertThat(this.root.hasAnyRole("A", "B")).isFalse(); + verify(factory).hasAnyRole("A", "B"); + } + + // gh-18486 + @Test + @SuppressWarnings("unchecked") + public void hasAllRolesDelegatesToAuthorizationManagerFactoryHasAllRoles() { + AuthorizationManagerFactory factory = mock(AuthorizationManagerFactory.class); + AuthorizationManager manager = SingleResultAuthorizationManager.denyAll(); + given(factory.hasAllRoles("A", "B")).willReturn(manager); + this.root.setAuthorizationManagerFactory(factory); + assertThat(this.root.hasAllRoles("A", "B")).isFalse(); + verify(factory).hasAllRoles("A", "B"); + } + + // gh-18486 + @Test + @SuppressWarnings("unchecked") + public void permitAllDelegatesToAuthorizationManagerFactoryPermitAll() { + AuthorizationManagerFactory factory = mock(AuthorizationManagerFactory.class); + AuthorizationManager manager = SingleResultAuthorizationManager.denyAll(); + given(factory.permitAll()).willReturn(manager); + this.root.setAuthorizationManagerFactory(factory); + assertThat(this.root.permitAll()).isFalse(); + verify(factory).permitAll(); + } + + // gh-18486 + @Test + @SuppressWarnings("unchecked") + public void denyAllDelegatesToAuthorizationManagerFactoryDenyAll() { + AuthorizationManagerFactory factory = mock(AuthorizationManagerFactory.class); + AuthorizationManager manager = SingleResultAuthorizationManager.denyAll(); + given(factory.denyAll()).willReturn(manager); + this.root.setAuthorizationManagerFactory(factory); + assertThat(this.root.denyAll()).isFalse(); + verify(factory).denyAll(); + } + + // gh-18486 + @Test + @SuppressWarnings("unchecked") + public void isAnonymousDelegatesToAuthorizationManagerFactoryAnonymous() { + AuthorizationManagerFactory factory = mock(AuthorizationManagerFactory.class); + AuthorizationManager manager = SingleResultAuthorizationManager.denyAll(); + given(factory.anonymous()).willReturn(manager); + this.root.setAuthorizationManagerFactory(factory); + assertThat(this.root.isAnonymous()).isFalse(); + verify(factory).anonymous(); + } + + // gh-18486 + @Test + @SuppressWarnings("unchecked") + public void isAuthenticatedDelegatesToAuthorizationManagerFactoryAuthenticated() { + AuthorizationManagerFactory factory = mock(AuthorizationManagerFactory.class); + AuthorizationManager manager = SingleResultAuthorizationManager.denyAll(); + given(factory.authenticated()).willReturn(manager); + this.root.setAuthorizationManagerFactory(factory); + assertThat(this.root.isAuthenticated()).isFalse(); + verify(factory).authenticated(); + } + + // gh-18486 + @Test + @SuppressWarnings("unchecked") + public void isRememberMeDelegatesToAuthorizationManagerFactoryRememberMe() { + AuthorizationManagerFactory factory = mock(AuthorizationManagerFactory.class); + AuthorizationManager manager = SingleResultAuthorizationManager.denyAll(); + given(factory.rememberMe()).willReturn(manager); + this.root.setAuthorizationManagerFactory(factory); + assertThat(this.root.isRememberMe()).isFalse(); + verify(factory).rememberMe(); + } + + // gh-18486 + @Test + @SuppressWarnings("unchecked") + public void isFullyAuthenticatedDelegatesToAuthorizationManagerFactoryFullyAuthenticated() { + AuthorizationManagerFactory factory = mock(AuthorizationManagerFactory.class); + AuthorizationManager manager = SingleResultAuthorizationManager.denyAll(); + given(factory.fullyAuthenticated()).willReturn(manager); + this.root.setAuthorizationManagerFactory(factory); + assertThat(this.root.isFullyAuthenticated()).isFalse(); + verify(factory).fullyAuthenticated(); + } + }