Add default AuthorizationManager

Closes gh-11963
This commit is contained in:
Josh Cummings 2022-10-05 21:36:34 -06:00
parent dce1c30522
commit 4ddec07d0e
No known key found for this signature in database
GPG Key ID: A306A51F43B8E5A5
2 changed files with 40 additions and 2 deletions

View File

@ -49,6 +49,8 @@ public final class RequestMatcherDelegatingAuthorizationManager implements Autho
private final List<RequestMatcherEntry<AuthorizationManager<RequestAuthorizationContext>>> mappings;
private AuthorizationManager<RequestAuthorizationContext> defaultManager = (authentication, request) -> null;
private RequestMatcherDelegatingAuthorizationManager(
List<RequestMatcherEntry<AuthorizationManager<RequestAuthorizationContext>>> mappings) {
Assert.notEmpty(mappings, "mappings cannot be empty");
@ -82,8 +84,10 @@ public final class RequestMatcherDelegatingAuthorizationManager implements Autho
new RequestAuthorizationContext(request, matchResult.getVariables()));
}
}
this.logger.trace("Abstaining since did not find matching RequestMatcher");
return null;
if (this.logger.isTraceEnabled()) {
this.logger.trace(LogMessage.format("Checking authorization on %s using %s", request, this.defaultManager));
}
return this.defaultManager.check(authentication, new RequestAuthorizationContext(request));
}
/**
@ -94,6 +98,21 @@ public final class RequestMatcherDelegatingAuthorizationManager implements Autho
return new Builder();
}
/**
* Use this {@link AuthorizationManager} if the request fails to match any other
* configured {@link AuthorizationManager}.
*
* <p>
* This is specifically handy when considering whether to accept or deny requests by
* default. The default is to abstain from deciding on requests that don't match
* configuration.
* @param authorizationManager the {@link AuthorizationManager} to use
* @since 5.8
*/
public void setDefaultAuthorizationManager(AuthorizationManager<RequestAuthorizationContext> authorizationManager) {
this.defaultManager = authorizationManager;
}
/**
* A builder for {@link RequestMatcherDelegatingAuthorizationManager}.
*/

View File

@ -24,6 +24,7 @@ import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.authorization.AuthorityAuthorizationManager;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.servlet.util.matcher.MvcRequestMatcher;
import org.springframework.security.web.util.matcher.AnyRequestMatcher;
@ -31,6 +32,10 @@ import org.springframework.security.web.util.matcher.RequestMatcherEntry;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link RequestMatcherDelegatingAuthorizationManager}.
@ -115,6 +120,20 @@ public class RequestMatcherDelegatingAuthorizationManagerTests {
assertThat(unmapped.isGranted()).isFalse();
}
@Test
public void checkWhenNoMatchesThenUsesDefaultAuthorizationManager() {
RequestMatcherDelegatingAuthorizationManager manager = RequestMatcherDelegatingAuthorizationManager.builder()
.add((request) -> false, (authentication, context) -> new AuthorizationDecision(false)).build();
AuthorizationManager<RequestAuthorizationContext> defaultManager = mock(AuthorizationManager.class);
given(defaultManager.check(any(), any())).willReturn(new AuthorizationDecision(true));
manager.setDefaultAuthorizationManager(defaultManager);
Supplier<Authentication> authentication = () -> new TestingAuthenticationToken("user", "password");
AuthorizationDecision decision = manager.check(authentication, new MockHttpServletRequest(null, "/endpoint"));
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
verify(defaultManager).check(any(), any());
}
@Test
public void addWhenMappingsConsumerNullThenException() {
assertThatIllegalArgumentException()