Add DefaultAuthorizationManagerFactory.additionalAuthorization
This commit is contained in:
		
						commit
						549569ea55
					
				|  | @ -134,6 +134,19 @@ public final class AllAuthoritiesAuthorizationManager<T> implements Authorizatio | ||||||
| 		return new AllAuthoritiesAuthorizationManager<>(authorities); | 		return new AllAuthoritiesAuthorizationManager<>(authorities); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Creates an instance of {@link AllAuthoritiesAuthorizationManager} with the provided | ||||||
|  | 	 * authorities. | ||||||
|  | 	 * @param authorities the authorities to check for | ||||||
|  | 	 * @param <T> the type of object being authorized | ||||||
|  | 	 * @return the new instance | ||||||
|  | 	 */ | ||||||
|  | 	public static <T> AllAuthoritiesAuthorizationManager<T> hasAllAuthorities(List<String> authorities) { | ||||||
|  | 		Assert.notEmpty(authorities, "authorities cannot be empty"); | ||||||
|  | 		Assert.noNullElements(authorities, "authorities cannot contain null values"); | ||||||
|  | 		return new AllAuthoritiesAuthorizationManager<>(authorities.toArray(new String[0])); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	private static String[] toNamedRolesArray(String rolePrefix, String[] roles) { | 	private static String[] toNamedRolesArray(String rolePrefix, String[] roles) { | ||||||
| 		String[] result = new String[roles.length]; | 		String[] result = new String[roles.length]; | ||||||
| 		for (int i = 0; i < roles.length; i++) { | 		for (int i = 0; i < roles.length; i++) { | ||||||
|  |  | ||||||
|  | @ -16,6 +16,9 @@ | ||||||
| 
 | 
 | ||||||
| package org.springframework.security.authorization; | package org.springframework.security.authorization; | ||||||
| 
 | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | import java.util.List; | ||||||
|  | 
 | ||||||
| import org.jspecify.annotations.Nullable; | import org.jspecify.annotations.Nullable; | ||||||
| 
 | 
 | ||||||
| import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy; | import org.springframework.security.access.hierarchicalroles.NullRoleHierarchy; | ||||||
|  | @ -23,12 +26,15 @@ import org.springframework.security.access.hierarchicalroles.RoleHierarchy; | ||||||
| import org.springframework.security.authentication.AuthenticationTrustResolver; | import org.springframework.security.authentication.AuthenticationTrustResolver; | ||||||
| import org.springframework.security.authentication.AuthenticationTrustResolverImpl; | import org.springframework.security.authentication.AuthenticationTrustResolverImpl; | ||||||
| import org.springframework.util.Assert; | import org.springframework.util.Assert; | ||||||
|  | import org.springframework.util.CollectionUtils; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * A factory for creating different kinds of {@link AuthorizationManager} instances. |  * A factory for creating different kinds of {@link AuthorizationManager} instances. | ||||||
|  * |  * | ||||||
|  * @param <T> the type of object that the authorization check is being done on |  * @param <T> the type of object that the authorization check is being done on | ||||||
|  * @author Steve Riesenberg |  * @author Steve Riesenberg | ||||||
|  |  * @author Andrey Litvitski | ||||||
|  |  * @author Rob Winch | ||||||
|  * @since 7.0 |  * @since 7.0 | ||||||
|  */ |  */ | ||||||
| public final class DefaultAuthorizationManagerFactory<T extends @Nullable Object> | public final class DefaultAuthorizationManagerFactory<T extends @Nullable Object> | ||||||
|  | @ -40,6 +46,8 @@ public final class DefaultAuthorizationManagerFactory<T extends @Nullable Object | ||||||
| 
 | 
 | ||||||
| 	private String rolePrefix = "ROLE_"; | 	private String rolePrefix = "ROLE_"; | ||||||
| 
 | 
 | ||||||
|  | 	private @Nullable AuthorizationManager<T> additionalAuthorization; | ||||||
|  | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Sets the {@link AuthenticationTrustResolver} used to check the user's | 	 * Sets the {@link AuthenticationTrustResolver} used to check the user's | ||||||
| 	 * authentication. | 	 * authentication. | ||||||
|  | @ -69,6 +77,32 @@ public final class DefaultAuthorizationManagerFactory<T extends @Nullable Object | ||||||
| 		this.rolePrefix = rolePrefix; | 		this.rolePrefix = rolePrefix; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Sets additional authorization to be applied to the returned | ||||||
|  | 	 * {@link AuthorizationManager} for the following methods: | ||||||
|  | 	 * | ||||||
|  | 	 * <ul> | ||||||
|  | 	 * <li>{@link #hasRole(String)}</li> | ||||||
|  | 	 * <li>{@link #hasAnyRole(String...)}</li> | ||||||
|  | 	 * <li>{@link #hasAllRoles(String...)}</li> | ||||||
|  | 	 * <li>{@link #hasAuthority(String)}</li> | ||||||
|  | 	 * <li>{@link #hasAnyAuthority(String...)}</li> | ||||||
|  | 	 * <li>{@link #hasAllAuthorities(String...)}</li> | ||||||
|  | 	 * <li>{@link #authenticated()}</li> | ||||||
|  | 	 * <li>{@link #fullyAuthenticated()}</li> | ||||||
|  | 	 * <li>{@link #rememberMe()}</li> | ||||||
|  | 	 * </ul> | ||||||
|  | 	 * | ||||||
|  | 	 * <p> | ||||||
|  | 	 * This does not affect {@code anonymous}, {@code permitAll}, or {@code denyAll}. | ||||||
|  | 	 * </p> | ||||||
|  | 	 * @param additionalAuthorization the {@link AuthorizationManager} to be applied. | ||||||
|  | 	 * Default is null (no additional authorization). | ||||||
|  | 	 */ | ||||||
|  | 	public void setAdditionalAuthorization(@Nullable AuthorizationManager<T> additionalAuthorization) { | ||||||
|  | 		this.additionalAuthorization = additionalAuthorization; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	public AuthorizationManager<T> hasRole(String role) { | 	public AuthorizationManager<T> hasRole(String role) { | ||||||
| 		return hasAnyRole(role); | 		return hasAnyRole(role); | ||||||
|  | @ -76,64 +110,140 @@ public final class DefaultAuthorizationManagerFactory<T extends @Nullable Object | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	public AuthorizationManager<T> hasAnyRole(String... roles) { | 	public AuthorizationManager<T> hasAnyRole(String... roles) { | ||||||
| 		return withRoleHierarchy(AuthorityAuthorizationManager.hasAnyRole(this.rolePrefix, roles)); | 		return createManager(AuthorityAuthorizationManager.hasAnyRole(this.rolePrefix, roles)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	public AuthorizationManager<T> hasAllRoles(String... roles) { | 	public AuthorizationManager<T> hasAllRoles(String... roles) { | ||||||
| 		return withRoleHierarchy(AllAuthoritiesAuthorizationManager.hasAllPrefixedAuthorities(this.rolePrefix, roles)); | 		return createManager(AllAuthoritiesAuthorizationManager.hasAllPrefixedAuthorities(this.rolePrefix, roles)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	public AuthorizationManager<T> hasAuthority(String authority) { | 	public AuthorizationManager<T> hasAuthority(String authority) { | ||||||
| 		return withRoleHierarchy(AuthorityAuthorizationManager.hasAuthority(authority)); | 		return createManager(AuthorityAuthorizationManager.hasAuthority(authority)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	public AuthorizationManager<T> hasAnyAuthority(String... authorities) { | 	public AuthorizationManager<T> hasAnyAuthority(String... authorities) { | ||||||
| 		return withRoleHierarchy(AuthorityAuthorizationManager.hasAnyAuthority(authorities)); | 		return createManager(AuthorityAuthorizationManager.hasAnyAuthority(authorities)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	public AuthorizationManager<T> hasAllAuthorities(String... authorities) { | 	public AuthorizationManager<T> hasAllAuthorities(String... authorities) { | ||||||
| 		return withRoleHierarchy(AllAuthoritiesAuthorizationManager.hasAllAuthorities(authorities)); | 		return createManager(AllAuthoritiesAuthorizationManager.hasAllAuthorities(authorities)); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	public AuthorizationManager<T> authenticated() { | 	public AuthorizationManager<T> authenticated() { | ||||||
| 		return withTrustResolver(AuthenticatedAuthorizationManager.authenticated()); | 		return createManager(AuthenticatedAuthorizationManager.authenticated()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	public AuthorizationManager<T> fullyAuthenticated() { | 	public AuthorizationManager<T> fullyAuthenticated() { | ||||||
| 		return withTrustResolver(AuthenticatedAuthorizationManager.fullyAuthenticated()); | 		return createManager(AuthenticatedAuthorizationManager.fullyAuthenticated()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	public AuthorizationManager<T> rememberMe() { | 	public AuthorizationManager<T> rememberMe() { | ||||||
| 		return withTrustResolver(AuthenticatedAuthorizationManager.rememberMe()); | 		return createManager(AuthenticatedAuthorizationManager.rememberMe()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	public AuthorizationManager<T> anonymous() { | 	public AuthorizationManager<T> anonymous() { | ||||||
| 		return withTrustResolver(AuthenticatedAuthorizationManager.anonymous()); | 		return createManager(AuthenticatedAuthorizationManager.anonymous()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private AuthorityAuthorizationManager<T> withRoleHierarchy(AuthorityAuthorizationManager<T> authorizationManager) { | 	/** | ||||||
|  | 	 * Creates a {@link Builder} that helps build an {@link AuthorizationManager} to set | ||||||
|  | 	 * on {@link #setAdditionalAuthorization(AuthorizationManager)} for common scenarios. | ||||||
|  | 	 * <p> | ||||||
|  | 	 * Does not affect {@code anonymous}, {@code permitAll}, or {@code denyAll}. | ||||||
|  | 	 * @param <T> the secured object type | ||||||
|  | 	 * @return a factory configured with the required authorities | ||||||
|  | 	 */ | ||||||
|  | 	public static <T> Builder<T> builder() { | ||||||
|  | 		return new Builder<>(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private AuthorizationManager<T> createManager(AuthorityAuthorizationManager<T> authorizationManager) { | ||||||
| 		authorizationManager.setRoleHierarchy(this.roleHierarchy); | 		authorizationManager.setRoleHierarchy(this.roleHierarchy); | ||||||
| 		return authorizationManager; | 		return withAdditionalAuthorization(authorizationManager); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private AllAuthoritiesAuthorizationManager<T> withRoleHierarchy( | 	private AuthorizationManager<T> createManager(AllAuthoritiesAuthorizationManager<T> authorizationManager) { | ||||||
| 			AllAuthoritiesAuthorizationManager<T> authorizationManager) { |  | ||||||
| 		authorizationManager.setRoleHierarchy(this.roleHierarchy); | 		authorizationManager.setRoleHierarchy(this.roleHierarchy); | ||||||
| 		return authorizationManager; | 		return withAdditionalAuthorization(authorizationManager); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	private AuthenticatedAuthorizationManager<T> withTrustResolver( | 	private AuthorizationManager<T> createManager(AuthenticatedAuthorizationManager<T> authorizationManager) { | ||||||
| 			AuthenticatedAuthorizationManager<T> authorizationManager) { |  | ||||||
| 		authorizationManager.setTrustResolver(this.trustResolver); | 		authorizationManager.setTrustResolver(this.trustResolver); | ||||||
| 		return authorizationManager; | 		return withAdditionalAuthorization(authorizationManager); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private AuthorizationManager<T> withAdditionalAuthorization(AuthorizationManager<T> manager) { | ||||||
|  | 		if (this.additionalAuthorization == null) { | ||||||
|  | 			return manager; | ||||||
|  | 		} | ||||||
|  | 		return AuthorizationManagers.allOf(new AuthorizationDecision(false), this.additionalAuthorization, manager); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * A builder that allows creating {@link DefaultAuthorizationManagerFactory} with | ||||||
|  | 	 * additional authorization for common scenarios. | ||||||
|  | 	 * | ||||||
|  | 	 * @param <T> the type for the {@link DefaultAuthorizationManagerFactory} | ||||||
|  | 	 * @author Rob Winch | ||||||
|  | 	 */ | ||||||
|  | 	public static final class Builder<T> { | ||||||
|  | 
 | ||||||
|  | 		private final List<String> additionalAuthorities = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  | 		private RoleHierarchy roleHierarchy = new NullRoleHierarchy(); | ||||||
|  | 
 | ||||||
|  | 		/** | ||||||
|  | 		 * Add additional authorities that will be required. | ||||||
|  | 		 * @param additionalAuthorities the additional authorities. | ||||||
|  | 		 * @return the {@link Builder} to further customize. | ||||||
|  | 		 */ | ||||||
|  | 		public Builder<T> requireAdditionalAuthorities(String... additionalAuthorities) { | ||||||
|  | 			Assert.notEmpty(additionalAuthorities, "additionalAuthorities cannot be empty"); | ||||||
|  | 			for (String additionalAuthority : additionalAuthorities) { | ||||||
|  | 				this.additionalAuthorities.add(additionalAuthority); | ||||||
|  | 			} | ||||||
|  | 			return this; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/** | ||||||
|  | 		 * The {@link RoleHierarchy} to use. | ||||||
|  | 		 * @param roleHierarchy the non-null {@link RoleHierarchy} to use. Default is | ||||||
|  | 		 * {@link NullRoleHierarchy}. | ||||||
|  | 		 * @return the Builder to further customize. | ||||||
|  | 		 */ | ||||||
|  | 		public Builder<T> roleHierarchy(RoleHierarchy roleHierarchy) { | ||||||
|  | 			Assert.notNull(roleHierarchy, "roleHierarchy cannot be null"); | ||||||
|  | 			this.roleHierarchy = roleHierarchy; | ||||||
|  | 			return this; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		/** | ||||||
|  | 		 * Builds a {@link DefaultAuthorizationManagerFactory} that has the | ||||||
|  | 		 * {@link #setAdditionalAuthorization(AuthorizationManager)} set. | ||||||
|  | 		 * @return the {@link DefaultAuthorizationManagerFactory}. | ||||||
|  | 		 */ | ||||||
|  | 		public DefaultAuthorizationManagerFactory<T> build() { | ||||||
|  | 			Assert.state(!CollectionUtils.isEmpty(this.additionalAuthorities), "additionalAuthorities cannot be empty"); | ||||||
|  | 			DefaultAuthorizationManagerFactory<T> result = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 			AllAuthoritiesAuthorizationManager<T> additionalChecks = AllAuthoritiesAuthorizationManager | ||||||
|  | 				.hasAllAuthorities(this.additionalAuthorities); | ||||||
|  | 			result.setRoleHierarchy(this.roleHierarchy); | ||||||
|  | 			additionalChecks.setRoleHierarchy(this.roleHierarchy); | ||||||
|  | 			result.setAdditionalAuthorization(additionalChecks); | ||||||
|  | 			return result; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		private Builder() { | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -16,9 +16,23 @@ | ||||||
| 
 | 
 | ||||||
| package org.springframework.security.authorization; | package org.springframework.security.authorization; | ||||||
| 
 | 
 | ||||||
|  | import java.util.Collection; | ||||||
|  | 
 | ||||||
| import org.junit.jupiter.api.Test; | import org.junit.jupiter.api.Test; | ||||||
| 
 | 
 | ||||||
|  | import org.springframework.security.access.hierarchicalroles.RoleHierarchy; | ||||||
|  | import org.springframework.security.authentication.TestAuthentication; | ||||||
|  | import org.springframework.security.core.authority.AuthorityUtils; | ||||||
|  | 
 | ||||||
| import static org.assertj.core.api.Assertions.assertThat; | import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  | import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; | ||||||
|  | import static org.assertj.core.api.Assertions.assertThatIllegalStateException; | ||||||
|  | import static org.mockito.ArgumentMatchers.any; | ||||||
|  | import static org.mockito.BDDMockito.given; | ||||||
|  | import static org.mockito.Mockito.mock; | ||||||
|  | import static org.mockito.Mockito.times; | ||||||
|  | import static org.mockito.Mockito.verify; | ||||||
|  | import static org.mockito.Mockito.verifyNoInteractions; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Tests for {@link AuthorizationManagerFactory}. |  * Tests for {@link AuthorizationManagerFactory}. | ||||||
|  | @ -111,4 +125,230 @@ public class AuthorizationManagerFactoryTests { | ||||||
| 		assertThat(authorizationManager).isInstanceOf(AuthenticatedAuthorizationManager.class); | 		assertThat(authorizationManager).isInstanceOf(AuthenticatedAuthorizationManager.class); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void anonymousWhenAdditionalAuthorizationThenNotInvoked() { | ||||||
|  | 		AuthorizationManager<String> additional = mock(AuthorizationManager.class); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 		factory.setAdditionalAuthorization(additional); | ||||||
|  | 
 | ||||||
|  | 		factory.anonymous(); | ||||||
|  | 
 | ||||||
|  | 		verifyNoInteractions(additional); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void permitAllWhenAdditionalAuthorizationThenNotInvoked() { | ||||||
|  | 		AuthorizationManager<String> additional = mock(AuthorizationManager.class); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 		factory.setAdditionalAuthorization(additional); | ||||||
|  | 
 | ||||||
|  | 		factory.permitAll(); | ||||||
|  | 
 | ||||||
|  | 		verifyNoInteractions(additional); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void denyAllAllWhenAdditionalAuthorizationThenNotInvoked() { | ||||||
|  | 		AuthorizationManager<String> additional = mock(AuthorizationManager.class); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 		factory.setAdditionalAuthorization(additional); | ||||||
|  | 
 | ||||||
|  | 		factory.permitAll(); | ||||||
|  | 
 | ||||||
|  | 		verifyNoInteractions(additional); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void hasRoleWhenAdditionalAuthorizationThenInvoked() { | ||||||
|  | 		AuthorizationManager<String> additional = mock(AuthorizationManager.class); | ||||||
|  | 		given(additional.authorize(any(), any())).willReturn(new AuthorizationDecision(true), | ||||||
|  | 				new AuthorizationDecision(false)); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 		factory.setAdditionalAuthorization(additional); | ||||||
|  | 
 | ||||||
|  | 		assertUserGranted(factory.hasRole("USER")); | ||||||
|  | 		assertUserDenied(factory.hasRole("USER")); | ||||||
|  | 
 | ||||||
|  | 		verify(additional, times(2)).authorize(any(), any()); | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void hasAnyRoleWhenAdditionalAuthorizationThenInvoked() { | ||||||
|  | 		AuthorizationManager<String> additional = mock(AuthorizationManager.class); | ||||||
|  | 		given(additional.authorize(any(), any())).willReturn(new AuthorizationDecision(true), | ||||||
|  | 				new AuthorizationDecision(false)); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 		factory.setAdditionalAuthorization(additional); | ||||||
|  | 
 | ||||||
|  | 		assertUserGranted(factory.hasAnyRole("USER")); | ||||||
|  | 		assertUserDenied(factory.hasAnyRole("USER")); | ||||||
|  | 
 | ||||||
|  | 		verify(additional, times(2)).authorize(any(), any()); | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void hasAllRolesWhenAdditionalAuthorizationThenInvoked() { | ||||||
|  | 		AuthorizationManager<String> additional = mock(AuthorizationManager.class); | ||||||
|  | 		given(additional.authorize(any(), any())).willReturn(new AuthorizationDecision(true), | ||||||
|  | 				new AuthorizationDecision(false)); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 		factory.setAdditionalAuthorization(additional); | ||||||
|  | 
 | ||||||
|  | 		assertUserGranted(factory.hasAllRoles("USER")); | ||||||
|  | 		assertUserDenied(factory.hasAllRoles("USER")); | ||||||
|  | 
 | ||||||
|  | 		verify(additional, times(2)).authorize(any(), any()); | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void hasAuthorityWhenAdditionalAuthorizationThenInvoked() { | ||||||
|  | 		AuthorizationManager<String> additional = mock(AuthorizationManager.class); | ||||||
|  | 		given(additional.authorize(any(), any())).willReturn(new AuthorizationDecision(true), | ||||||
|  | 				new AuthorizationDecision(false)); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 		factory.setAdditionalAuthorization(additional); | ||||||
|  | 
 | ||||||
|  | 		assertUserGranted(factory.hasAuthority("ROLE_USER")); | ||||||
|  | 		assertUserDenied(factory.hasAuthority("ROLE_USER")); | ||||||
|  | 
 | ||||||
|  | 		verify(additional, times(2)).authorize(any(), any()); | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void hasAnyAuthorityWhenAdditionalAuthorizationThenInvoked() { | ||||||
|  | 		AuthorizationManager<String> additional = mock(AuthorizationManager.class); | ||||||
|  | 		given(additional.authorize(any(), any())).willReturn(new AuthorizationDecision(true), | ||||||
|  | 				new AuthorizationDecision(false)); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 		factory.setAdditionalAuthorization(additional); | ||||||
|  | 
 | ||||||
|  | 		assertUserGranted(factory.hasAnyAuthority("ROLE_USER")); | ||||||
|  | 		assertUserDenied(factory.hasAnyAuthority("ROLE_USER")); | ||||||
|  | 
 | ||||||
|  | 		verify(additional, times(2)).authorize(any(), any()); | ||||||
|  | 
 | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void hasAllAuthoritiesWhenAdditionalAuthorizationThenInvoked() { | ||||||
|  | 		AuthorizationManager<String> additional = mock(AuthorizationManager.class); | ||||||
|  | 		given(additional.authorize(any(), any())).willReturn(new AuthorizationDecision(true), | ||||||
|  | 				new AuthorizationDecision(false)); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 		factory.setAdditionalAuthorization(additional); | ||||||
|  | 
 | ||||||
|  | 		assertUserGranted(factory.hasAllAuthorities("ROLE_USER")); | ||||||
|  | 		assertUserDenied(factory.hasAllAuthorities("ROLE_USER")); | ||||||
|  | 
 | ||||||
|  | 		verify(additional, times(2)).authorize(any(), any()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void authenticatedWhenAdditionalAuthorizationThenInvoked() { | ||||||
|  | 		AuthorizationManager<String> additional = mock(AuthorizationManager.class); | ||||||
|  | 		given(additional.authorize(any(), any())).willReturn(new AuthorizationDecision(true), | ||||||
|  | 				new AuthorizationDecision(false)); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 		factory.setAdditionalAuthorization(additional); | ||||||
|  | 
 | ||||||
|  | 		assertUserGranted(factory.authenticated()); | ||||||
|  | 		assertUserDenied(factory.authenticated()); | ||||||
|  | 
 | ||||||
|  | 		verify(additional, times(2)).authorize(any(), any()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void fullyAuthenticatedWhenAdditionalAuthorizationThenInvoked() { | ||||||
|  | 		AuthorizationManager<String> additional = mock(AuthorizationManager.class); | ||||||
|  | 		given(additional.authorize(any(), any())).willReturn(new AuthorizationDecision(true), | ||||||
|  | 				new AuthorizationDecision(false)); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 		factory.setAdditionalAuthorization(additional); | ||||||
|  | 
 | ||||||
|  | 		assertUserGranted(factory.fullyAuthenticated()); | ||||||
|  | 		assertUserDenied(factory.fullyAuthenticated()); | ||||||
|  | 
 | ||||||
|  | 		verify(additional, times(2)).authorize(any(), any()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void rememberMeWhenAdditionalAuthorizationThenInvoked() { | ||||||
|  | 		AuthorizationManager<String> additional = mock(AuthorizationManager.class); | ||||||
|  | 		given(additional.authorize(any(), any())).willReturn(new AuthorizationDecision(true), | ||||||
|  | 				new AuthorizationDecision(false)); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = new DefaultAuthorizationManagerFactory<>(); | ||||||
|  | 		factory.setAdditionalAuthorization(additional); | ||||||
|  | 
 | ||||||
|  | 		assertThat(factory.rememberMe().authorize(() -> TestAuthentication.rememberMeUser(), "").isGranted()).isTrue(); | ||||||
|  | 		assertThat(factory.rememberMe().authorize(() -> TestAuthentication.rememberMeUser(), "").isGranted()).isFalse(); | ||||||
|  | 
 | ||||||
|  | 		verify(additional, times(2)).authorize(any(), any()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void builderWhenEmptyAdditionalAuthoritiesThenIllegalStateException() { | ||||||
|  | 		DefaultAuthorizationManagerFactory.Builder<Object> builder = DefaultAuthorizationManagerFactory.builder(); | ||||||
|  | 		assertThatIllegalStateException().isThrownBy(() -> builder.build()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void builderWhenAdditionalAuthorityThenRequired() { | ||||||
|  | 		AuthorizationManagerFactory<String> factory = DefaultAuthorizationManagerFactory.<String>builder() | ||||||
|  | 			.requireAdditionalAuthorities("ROLE_ADMIN") | ||||||
|  | 			.build(); | ||||||
|  | 		assertUserDenied(factory.hasRole("USER")); | ||||||
|  | 		assertThat(factory.hasRole("USER").authorize(() -> TestAuthentication.authenticatedAdmin(), "").isGranted()) | ||||||
|  | 			.isTrue(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void builderWhenAdditionalAuthoritiesThenRequired() { | ||||||
|  | 		AuthorizationManagerFactory<String> factory = DefaultAuthorizationManagerFactory.<String>builder() | ||||||
|  | 			.requireAdditionalAuthorities("ROLE_ADMIN", "ROLE_USER") | ||||||
|  | 			.build(); | ||||||
|  | 		assertUserDenied(factory.hasRole("USER")); | ||||||
|  | 		assertThat(factory.hasRole("USER").authorize(() -> TestAuthentication.authenticatedAdmin(), "").isGranted()) | ||||||
|  | 			.isTrue(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void builderWhenNullRoleHierachyThenIllegalArgumentException() { | ||||||
|  | 		DefaultAuthorizationManagerFactory.Builder<Object> builder = DefaultAuthorizationManagerFactory.builder(); | ||||||
|  | 		assertThatIllegalArgumentException().isThrownBy(() -> builder.roleHierarchy(null)); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Test | ||||||
|  | 	public void builderWhenRoleHierarchyThenUsed() { | ||||||
|  | 
 | ||||||
|  | 		RoleHierarchy roleHierarchy = mock(RoleHierarchy.class); | ||||||
|  | 		String ROLE_HIERARCHY = "ROLE_HIERARCHY"; | ||||||
|  | 		Collection authorityHierarchy = AuthorityUtils.createAuthorityList(ROLE_HIERARCHY, "ROLE_USER"); | ||||||
|  | 		given(roleHierarchy.getReachableGrantedAuthorities(any())).willReturn(authorityHierarchy); | ||||||
|  | 		DefaultAuthorizationManagerFactory<String> factory = DefaultAuthorizationManagerFactory.<String>builder() | ||||||
|  | 			.requireAdditionalAuthorities(ROLE_HIERARCHY) | ||||||
|  | 			.roleHierarchy(roleHierarchy) | ||||||
|  | 			.build(); | ||||||
|  | 
 | ||||||
|  | 		// ROLE_USER is replaced with the RoleHierarchy (ROLE_USER, ROLE_HIERARCHY) | ||||||
|  | 		assertUserGranted(factory.hasAuthority("ROLE_USER")); | ||||||
|  | 		// ROLE_ADMIN is replaced with the RoleHierarchy (ROLE_USER, ROLE_HIERARCHY) | ||||||
|  | 		assertThat(factory.hasAuthority("ROLE_ADMIN") | ||||||
|  | 			.authorize(() -> TestAuthentication.authenticatedAdmin(), "") | ||||||
|  | 			.isGranted()).isFalse(); | ||||||
|  | 
 | ||||||
|  | 		verify(roleHierarchy, times(4)).getReachableGrantedAuthorities(any()); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private void assertUserGranted(AuthorizationManager<String> manager) { | ||||||
|  | 		assertThat(manager.authorize(() -> TestAuthentication.authenticatedUser(), "").isGranted()).isTrue(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	private void assertUserDenied(AuthorizationManager<String> manager) { | ||||||
|  | 		assertThat(manager.authorize(() -> TestAuthentication.authenticatedUser(), "").isGranted()).isFalse(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue