mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	SecuredAuthorizationManager should allow customizing underlying authorization manager
Closes gh-12233
This commit is contained in:
		
							parent
							
								
									d84b8d2d12
								
							
						
					
					
						commit
						782b792e7b
					
				| @ -17,6 +17,7 @@ | ||||
| package org.springframework.security.authorization.method; | ||||
| 
 | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.Collection; | ||||
| import java.util.Collections; | ||||
| import java.util.Map; | ||||
| import java.util.Set; | ||||
| @ -32,6 +33,7 @@ import org.springframework.security.authorization.AuthoritiesAuthorizationManage | ||||
| import org.springframework.security.authorization.AuthorizationDecision; | ||||
| import org.springframework.security.authorization.AuthorizationManager; | ||||
| import org.springframework.security.core.Authentication; | ||||
| import org.springframework.util.Assert; | ||||
| 
 | ||||
| /** | ||||
|  * An {@link AuthorizationManager} which can determine if an {@link Authentication} may | ||||
| @ -43,10 +45,23 @@ import org.springframework.security.core.Authentication; | ||||
|  */ | ||||
| public final class SecuredAuthorizationManager implements AuthorizationManager<MethodInvocation> { | ||||
| 
 | ||||
| 	private final AuthoritiesAuthorizationManager delegate = new AuthoritiesAuthorizationManager(); | ||||
| 	private AuthorizationManager<Collection<String>> authoritiesAuthorizationManager = new AuthoritiesAuthorizationManager(); | ||||
| 
 | ||||
| 	private final Map<MethodClassKey, Set<String>> cachedAuthorities = new ConcurrentHashMap<>(); | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Sets an {@link AuthorizationManager} that accepts a collection of authority | ||||
| 	 * strings. | ||||
| 	 * @param authoritiesAuthorizationManager the {@link AuthorizationManager} that | ||||
| 	 * accepts a collection of authority strings to use | ||||
| 	 * @since 6.1 | ||||
| 	 */ | ||||
| 	public void setAuthoritiesAuthorizationManager( | ||||
| 			AuthorizationManager<Collection<String>> authoritiesAuthorizationManager) { | ||||
| 		Assert.notNull(authoritiesAuthorizationManager, "authoritiesAuthorizationManager cannot be null"); | ||||
| 		this.authoritiesAuthorizationManager = authoritiesAuthorizationManager; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Determine if an {@link Authentication} has access to a method by evaluating the | ||||
| 	 * {@link Secured} annotation that {@link MethodInvocation} specifies. | ||||
| @ -58,7 +73,7 @@ public final class SecuredAuthorizationManager implements AuthorizationManager<M | ||||
| 	@Override | ||||
| 	public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocation mi) { | ||||
| 		Set<String> authorities = getAuthorities(mi); | ||||
| 		return authorities.isEmpty() ? null : this.delegate.check(authentication, authorities); | ||||
| 		return authorities.isEmpty() ? null : this.authoritiesAuthorizationManager.check(authentication, authorities); | ||||
| 	} | ||||
| 
 | ||||
| 	private Set<String> getAuthorities(MethodInvocation methodInvocation) { | ||||
|  | ||||
| @ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * Copyright 2002-2021 the original author or authors. | ||||
|  * Copyright 2002-2023 the original author or authors. | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
| @ -18,6 +18,8 @@ package org.springframework.security.authorization.method; | ||||
| 
 | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.util.Collection; | ||||
| import java.util.Set; | ||||
| import java.util.function.Supplier; | ||||
| 
 | ||||
| import org.junit.jupiter.api.Test; | ||||
| @ -29,10 +31,14 @@ import org.springframework.security.access.intercept.method.MockMethodInvocation | ||||
| import org.springframework.security.authentication.TestAuthentication; | ||||
| import org.springframework.security.authentication.TestingAuthenticationToken; | ||||
| import org.springframework.security.authorization.AuthorizationDecision; | ||||
| import org.springframework.security.authorization.AuthorizationManager; | ||||
| import org.springframework.security.core.Authentication; | ||||
| 
 | ||||
| import static org.assertj.core.api.Assertions.assertThat; | ||||
| import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||||
| import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; | ||||
| import static org.mockito.Mockito.mock; | ||||
| import static org.mockito.Mockito.verify; | ||||
| 
 | ||||
| /** | ||||
|  * Tests for {@link SecuredAuthorizationManager}. | ||||
| @ -41,6 +47,26 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; | ||||
|  */ | ||||
| public class SecuredAuthorizationManagerTests { | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void setAuthoritiesAuthorizationManagerWhenNullThenException() { | ||||
| 		SecuredAuthorizationManager manager = new SecuredAuthorizationManager(); | ||||
| 		assertThatIllegalArgumentException().isThrownBy(() -> manager.setAuthoritiesAuthorizationManager(null)) | ||||
| 				.withMessage("authoritiesAuthorizationManager cannot be null"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void setAuthoritiesAuthorizationManagerWhenNotNullThenVerifyUsage() throws Exception { | ||||
| 		AuthorizationManager<Collection<String>> authoritiesAuthorizationManager = mock(AuthorizationManager.class); | ||||
| 		SecuredAuthorizationManager manager = new SecuredAuthorizationManager(); | ||||
| 		manager.setAuthoritiesAuthorizationManager(authoritiesAuthorizationManager); | ||||
| 		MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class, | ||||
| 				"securedUserOrAdmin"); | ||||
| 		Supplier<Authentication> authentication = TestAuthentication::authenticatedUser; | ||||
| 		AuthorizationDecision decision = manager.check(authentication, methodInvocation); | ||||
| 		assertThat(decision).isNull(); | ||||
| 		verify(authoritiesAuthorizationManager).check(authentication, Set.of("ROLE_USER", "ROLE_ADMIN")); | ||||
| 	} | ||||
| 
 | ||||
| 	@Test | ||||
| 	public void checkDoSomethingWhenNoSecuredAnnotationThenNullDecision() throws Exception { | ||||
| 		MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class, | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user