From eda346863d53ccf31667557de0c362bf46f9112f Mon Sep 17 00:00:00 2001 From: Marcus Da Coregio Date: Mon, 6 Dec 2021 15:12:37 -0300 Subject: [PATCH] Introduce AuthorizationManagerWebInvocationPrivilegeEvaluator Closes gh-10590 --- ...anagerWebInvocationPrivilegeEvaluator.java | 57 ++++++++++++++++ ...rWebInvocationPrivilegeEvaluatorTests.java | 68 +++++++++++++++++++ 2 files changed, 125 insertions(+) create mode 100644 web/src/main/java/org/springframework/security/web/access/AuthorizationManagerWebInvocationPrivilegeEvaluator.java create mode 100644 web/src/test/java/org/springframework/security/web/access/AuthorizationManagerWebInvocationPrivilegeEvaluatorTests.java diff --git a/web/src/main/java/org/springframework/security/web/access/AuthorizationManagerWebInvocationPrivilegeEvaluator.java b/web/src/main/java/org/springframework/security/web/access/AuthorizationManagerWebInvocationPrivilegeEvaluator.java new file mode 100644 index 00000000000..e5a6369eeb5 --- /dev/null +++ b/web/src/main/java/org/springframework/security/web/access/AuthorizationManagerWebInvocationPrivilegeEvaluator.java @@ -0,0 +1,57 @@ +/* + * Copyright 2002-2021 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.web.access; + +import jakarta.servlet.http.HttpServletRequest; + +import org.springframework.security.authorization.AuthorizationDecision; +import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.core.Authentication; +import org.springframework.security.web.FilterInvocation; +import org.springframework.util.Assert; + +/** + * An implementation of {@link WebInvocationPrivilegeEvaluator} which delegates the checks + * to an instance of {@link AuthorizationManager} + * + * @author Marcus Da Coregio + * @since 5.7 + */ +public final class AuthorizationManagerWebInvocationPrivilegeEvaluator implements WebInvocationPrivilegeEvaluator { + + private final AuthorizationManager authorizationManager; + + public AuthorizationManagerWebInvocationPrivilegeEvaluator( + AuthorizationManager authorizationManager) { + Assert.notNull(authorizationManager, "authorizationManager cannot be null"); + this.authorizationManager = authorizationManager; + } + + @Override + public boolean isAllowed(String uri, Authentication authentication) { + return isAllowed(null, uri, null, authentication); + } + + @Override + public boolean isAllowed(String contextPath, String uri, String method, Authentication authentication) { + FilterInvocation filterInvocation = new FilterInvocation(contextPath, uri, method); + AuthorizationDecision decision = this.authorizationManager.check(() -> authentication, + filterInvocation.getHttpRequest()); + return decision != null && decision.isGranted(); + } + +} diff --git a/web/src/test/java/org/springframework/security/web/access/AuthorizationManagerWebInvocationPrivilegeEvaluatorTests.java b/web/src/test/java/org/springframework/security/web/access/AuthorizationManagerWebInvocationPrivilegeEvaluatorTests.java new file mode 100644 index 00000000000..9e24dd490fe --- /dev/null +++ b/web/src/test/java/org/springframework/security/web/access/AuthorizationManagerWebInvocationPrivilegeEvaluatorTests.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002-2021 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.security.web.access; + +import jakarta.servlet.http.HttpServletRequest; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import org.springframework.security.authentication.TestAuthentication; +import org.springframework.security.authorization.AuthorizationDecision; +import org.springframework.security.authorization.AuthorizationManager; + +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.verify; + +@ExtendWith(MockitoExtension.class) +class AuthorizationManagerWebInvocationPrivilegeEvaluatorTests { + + @InjectMocks + private AuthorizationManagerWebInvocationPrivilegeEvaluator privilegeEvaluator; + + @Mock + private AuthorizationManager authorizationManager; + + @Test + void constructorWhenAuthorizationManagerNullThenIllegalArgument() { + assertThatIllegalArgumentException() + .isThrownBy(() -> new AuthorizationManagerWebInvocationPrivilegeEvaluator(null)) + .withMessage("authorizationManager cannot be null"); + } + + @Test + void isAllowedWhenAuthorizationManagerAllowsThenAllowedTrue() { + given(this.authorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(true)); + boolean allowed = this.privilegeEvaluator.isAllowed("/test", TestAuthentication.authenticatedUser()); + assertThat(allowed).isTrue(); + verify(this.authorizationManager).check(any(), any()); + } + + @Test + void isAllowedWhenAuthorizationManagerDeniesAllowedFalse() { + given(this.authorizationManager.check(any(), any())).willReturn(new AuthorizationDecision(false)); + boolean allowed = this.privilegeEvaluator.isAllowed("/test", TestAuthentication.authenticatedUser()); + assertThat(allowed).isFalse(); + } + +}