1
0
mirror of synced 2026-08-04 01:07:02 +00:00

Add AuthorizationResult support for AuthorizationManager

Closes gh-14843
This commit is contained in:
Max Batischev
2024-10-11 15:43:19 +03:00
committed by Josh Cummings
parent 702538ebce
commit e7644925f8
25 changed files with 134 additions and 34 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 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.
@@ -19,8 +19,8 @@ package org.springframework.security.web.access;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.authorization.AuthorizationResult;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.FilterInvocation;
import org.springframework.util.Assert;
@@ -57,7 +57,7 @@ public final class AuthorizationManagerWebInvocationPrivilegeEvaluator
public boolean isAllowed(String contextPath, String uri, String method, Authentication authentication) {
FilterInvocation filterInvocation = new FilterInvocation(contextPath, uri, method, this.servletContext);
HttpServletRequest httpRequest = this.requestTransformer.transform(filterInvocation.getHttpRequest());
AuthorizationDecision decision = this.authorizationManager.check(() -> authentication, httpRequest);
AuthorizationResult decision = this.authorizationManager.authorize(() -> authentication, httpRequest);
return decision == null || decision.isGranted();
}
@@ -93,7 +93,7 @@ public class AuthorizationFilter extends GenericFilterBean {
String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
try {
AuthorizationDecision decision = this.authorizationManager.check(this::getAuthentication, request);
AuthorizationResult decision = this.authorizationManager.authorize(this::getAuthentication, request);
this.eventPublisher.publishAuthorizationEvent(this::getAuthentication, request, decision);
if (decision != null && !decision.isGranted()) {
throw new AuthorizationDeniedException("Access Denied", decision);
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2024 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.
@@ -61,6 +61,7 @@ class AuthorizationManagerWebInvocationPrivilegeEvaluatorTests {
@Test
void isAllowedWhenAuthorizationManagerAllowsThenAllowedTrue() {
given(this.authorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(true));
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
boolean allowed = this.privilegeEvaluator.isAllowed("/test", TestAuthentication.authenticatedUser());
assertThat(allowed).isTrue();
verify(this.authorizationManager).check(any(), any());
@@ -69,6 +70,7 @@ class AuthorizationManagerWebInvocationPrivilegeEvaluatorTests {
@Test
void isAllowedWhenAuthorizationManagerDeniesAllowedFalse() {
given(this.authorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(false));
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
boolean allowed = this.privilegeEvaluator.isAllowed("/test", TestAuthentication.authenticatedUser());
assertThat(allowed).isFalse();
}
@@ -76,6 +78,7 @@ class AuthorizationManagerWebInvocationPrivilegeEvaluatorTests {
@Test
void isAllowedWhenAuthorizationManagerAbstainsThenAllowedTrue() {
given(this.authorizationManager.check(any(), any())).willReturn(null);
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
boolean allowed = this.privilegeEvaluator.isAllowed("/test", TestAuthentication.authenticatedUser());
assertThat(allowed).isTrue();
}
@@ -83,6 +86,7 @@ class AuthorizationManagerWebInvocationPrivilegeEvaluatorTests {
@Test
void isAllowedWhenServletContextExistsThenFilterInvocationHasServletContext() {
ServletContext servletContext = new MockServletContext();
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
this.privilegeEvaluator.setServletContext(servletContext);
this.privilegeEvaluator.isAllowed("/test", TestAuthentication.authenticatedUser());
ArgumentCaptor<HttpServletRequest> captor = ArgumentCaptor.forClass(HttpServletRequest.class);
@@ -99,6 +103,7 @@ class AuthorizationManagerWebInvocationPrivilegeEvaluatorTests {
void isAllowedWhenRequestTransformerThenUsesRequestTransformerResult() {
HttpServletRequest request = new MockHttpServletRequest();
given(this.requestTransformer.transform(any())).willReturn(request);
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
this.privilegeEvaluator.setRequestTransformer(this.requestTransformer);
this.privilegeEvaluator.isAllowed("/test", TestAuthentication.authenticatedUser());
@@ -93,6 +93,7 @@ public class AuthorizationFilterTests {
@Test
public void filterWhenAuthorizationManagerVerifyPassesThenNextFilter() throws Exception {
AuthorizationManager<HttpServletRequest> mockAuthorizationManager = mock(AuthorizationManager.class);
given(mockAuthorizationManager.authorize(any(), any())).willCallRealMethod();
given(mockAuthorizationManager.check(any(Supplier.class), any(HttpServletRequest.class)))
.willReturn(new AuthorizationDecision(true));
AuthorizationFilter filter = new AuthorizationFilter(mockAuthorizationManager);
@@ -120,6 +121,7 @@ public class AuthorizationFilterTests {
@Test
public void filterWhenAuthorizationManagerVerifyThrowsAccessDeniedExceptionThenStopFilterChain() {
AuthorizationManager<HttpServletRequest> mockAuthorizationManager = mock(AuthorizationManager.class);
given(mockAuthorizationManager.authorize(any(), any())).willCallRealMethod();
AuthorizationFilter filter = new AuthorizationFilter(mockAuthorizationManager);
TestingAuthenticationToken authenticationToken = new TestingAuthenticationToken("user", "password");
@@ -198,6 +200,7 @@ public class AuthorizationFilterTests {
@Test
public void doFilterWhenErrorThenDoFilter() throws Exception {
AuthorizationManager<HttpServletRequest> authorizationManager = mock(AuthorizationManager.class);
given(authorizationManager.authorize(any(), any())).willCallRealMethod();
AuthorizationFilter authorizationFilter = new AuthorizationFilter(authorizationManager);
MockHttpServletRequest mockRequest = new MockHttpServletRequest(null, "/path");
mockRequest.setDispatcherType(DispatcherType.ERROR);
@@ -234,6 +237,7 @@ public class AuthorizationFilterTests {
@Test
public void doFilterWhenObserveOncePerRequestTrueAndNotAppliedThenInvoked() throws ServletException, IOException {
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
this.filter.setObserveOncePerRequest(true);
this.filter.doFilter(this.request, this.response, this.chain);
verify(this.authorizationManager).check(any(), any());
@@ -242,6 +246,7 @@ public class AuthorizationFilterTests {
@Test
public void doFilterWhenObserveOncePerRequestFalseAndIsAppliedThenInvoked() throws ServletException, IOException {
setIsAppliedTrue();
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
this.filter.setObserveOncePerRequest(false);
this.filter.doFilter(this.request, this.response, this.chain);
verify(this.authorizationManager).check(any(), any());
@@ -249,6 +254,7 @@ public class AuthorizationFilterTests {
@Test
public void doFilterWhenObserveOncePerRequestFalseAndNotAppliedThenInvoked() throws ServletException, IOException {
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
this.filter.setObserveOncePerRequest(false);
this.filter.doFilter(this.request, this.response, this.chain);
verify(this.authorizationManager).check(any(), any());
@@ -264,6 +270,7 @@ public class AuthorizationFilterTests {
@Test
public void doFilterWhenFilterErrorDispatchTrueAndIsErrorThenInvoked() throws ServletException, IOException {
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
this.request.setDispatcherType(DispatcherType.ERROR);
this.filter.setFilterErrorDispatch(true);
this.filter.doFilter(this.request, this.response, this.chain);
@@ -287,6 +294,7 @@ public class AuthorizationFilterTests {
@Test
public void doFilterWhenFilterAsyncDispatchTrueAndIsAsyncThenInvoked() throws ServletException, IOException {
given(this.authorizationManager.authorize(any(), any())).willCallRealMethod();
this.request.setDispatcherType(DispatcherType.ASYNC);
this.filter.setFilterAsyncDispatch(true);
this.filter.doFilter(this.request, this.response, this.chain);