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); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * 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) { | ||||
| 		String[] result = new String[roles.length]; | ||||
| 		for (int i = 0; i < roles.length; i++) { | ||||
|  |  | |||
|  | @ -16,6 +16,9 @@ | |||
| 
 | ||||
| package org.springframework.security.authorization; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| import org.jspecify.annotations.Nullable; | ||||
| 
 | ||||
| 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.AuthenticationTrustResolverImpl; | ||||
| import org.springframework.util.Assert; | ||||
| import org.springframework.util.CollectionUtils; | ||||
| 
 | ||||
| /** | ||||
|  * A factory for creating different kinds of {@link AuthorizationManager} instances. | ||||
|  * | ||||
|  * @param <T> the type of object that the authorization check is being done on | ||||
|  * @author Steve Riesenberg | ||||
|  * @author Andrey Litvitski | ||||
|  * @author Rob Winch | ||||
|  * @since 7.0 | ||||
|  */ | ||||
| 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 @Nullable AuthorizationManager<T> additionalAuthorization; | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Sets the {@link AuthenticationTrustResolver} used to check the user's | ||||
| 	 * authentication. | ||||
|  | @ -69,6 +77,32 @@ public final class DefaultAuthorizationManagerFactory<T extends @Nullable Object | |||
| 		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 | ||||
| 	public AuthorizationManager<T> hasRole(String role) { | ||||
| 		return hasAnyRole(role); | ||||
|  | @ -76,64 +110,140 @@ public final class DefaultAuthorizationManagerFactory<T extends @Nullable Object | |||
| 
 | ||||
| 	@Override | ||||
| 	public AuthorizationManager<T> hasAnyRole(String... roles) { | ||||
| 		return withRoleHierarchy(AuthorityAuthorizationManager.hasAnyRole(this.rolePrefix, roles)); | ||||
| 		return createManager(AuthorityAuthorizationManager.hasAnyRole(this.rolePrefix, roles)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public AuthorizationManager<T> hasAllRoles(String... roles) { | ||||
| 		return withRoleHierarchy(AllAuthoritiesAuthorizationManager.hasAllPrefixedAuthorities(this.rolePrefix, roles)); | ||||
| 		return createManager(AllAuthoritiesAuthorizationManager.hasAllPrefixedAuthorities(this.rolePrefix, roles)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public AuthorizationManager<T> hasAuthority(String authority) { | ||||
| 		return withRoleHierarchy(AuthorityAuthorizationManager.hasAuthority(authority)); | ||||
| 		return createManager(AuthorityAuthorizationManager.hasAuthority(authority)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public AuthorizationManager<T> hasAnyAuthority(String... authorities) { | ||||
| 		return withRoleHierarchy(AuthorityAuthorizationManager.hasAnyAuthority(authorities)); | ||||
| 		return createManager(AuthorityAuthorizationManager.hasAnyAuthority(authorities)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public AuthorizationManager<T> hasAllAuthorities(String... authorities) { | ||||
| 		return withRoleHierarchy(AllAuthoritiesAuthorizationManager.hasAllAuthorities(authorities)); | ||||
| 		return createManager(AllAuthoritiesAuthorizationManager.hasAllAuthorities(authorities)); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public AuthorizationManager<T> authenticated() { | ||||
| 		return withTrustResolver(AuthenticatedAuthorizationManager.authenticated()); | ||||
| 		return createManager(AuthenticatedAuthorizationManager.authenticated()); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public AuthorizationManager<T> fullyAuthenticated() { | ||||
| 		return withTrustResolver(AuthenticatedAuthorizationManager.fullyAuthenticated()); | ||||
| 		return createManager(AuthenticatedAuthorizationManager.fullyAuthenticated()); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	public AuthorizationManager<T> rememberMe() { | ||||
| 		return withTrustResolver(AuthenticatedAuthorizationManager.rememberMe()); | ||||
| 		return createManager(AuthenticatedAuthorizationManager.rememberMe()); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	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); | ||||
| 		return authorizationManager; | ||||
| 		return withAdditionalAuthorization(authorizationManager); | ||||
| 	} | ||||
| 
 | ||||
| 	private AllAuthoritiesAuthorizationManager<T> withRoleHierarchy( | ||||
| 			AllAuthoritiesAuthorizationManager<T> authorizationManager) { | ||||
| 	private AuthorizationManager<T> createManager(AllAuthoritiesAuthorizationManager<T> authorizationManager) { | ||||
| 		authorizationManager.setRoleHierarchy(this.roleHierarchy); | ||||
| 		return authorizationManager; | ||||
| 		return withAdditionalAuthorization(authorizationManager); | ||||
| 	} | ||||
| 
 | ||||
| 	private AuthenticatedAuthorizationManager<T> withTrustResolver( | ||||
| 			AuthenticatedAuthorizationManager<T> authorizationManager) { | ||||
| 	private AuthorizationManager<T> createManager(AuthenticatedAuthorizationManager<T> authorizationManager) { | ||||
| 		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; | ||||
| 
 | ||||
| import java.util.Collection; | ||||
| 
 | ||||
| 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.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}. | ||||
|  | @ -111,4 +125,230 @@ public class AuthorizationManagerFactoryTests { | |||
| 		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