Revert AuthorizationManager Method Security

This commit is contained in:
Josh Cummings
2021-04-12 15:46:38 -06:00
parent b352c8f1da
commit 163b5943ca
38 changed files with 5 additions and 3790 deletions

View File

@@ -1,416 +0,0 @@
/*
* 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.config.annotation.method.configuration;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Supplier;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.JdkRegexpMethodPointcut;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.access.annotation.BusinessService;
import org.springframework.security.access.annotation.ExpressionProtectedBusinessServiceImpl;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.authorization.method.AuthorizationManagerBeforeMethodInterceptor;
import org.springframework.security.authorization.method.AuthorizationMethodInterceptor;
import org.springframework.security.config.test.SpringTestRule;
import org.springframework.security.core.Authentication;
import org.springframework.security.test.context.annotation.SecurityTestExecutionListeners;
import org.springframework.security.test.context.support.WithAnonymousUser;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link MethodSecurityConfiguration}.
*
* @author Evgeniy Cheban
*/
@RunWith(SpringRunner.class)
@SecurityTestExecutionListeners
public class MethodSecurityConfigurationTests {
@Rule
public final SpringTestRule spring = new SpringTestRule();
@Autowired(required = false)
MethodSecurityService methodSecurityService;
@Autowired(required = false)
BusinessService businessService;
@WithMockUser(roles = "ADMIN")
@Test
public void preAuthorizeWhenRoleAdminThenAccessDeniedException() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.methodSecurityService::preAuthorize)
.withMessage("Access Denied");
}
@WithAnonymousUser
@Test
public void preAuthorizePermitAllWhenRoleAnonymousThenPasses() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
String result = this.methodSecurityService.preAuthorizePermitAll();
assertThat(result).isNull();
}
@WithAnonymousUser
@Test
public void preAuthorizeNotAnonymousWhenRoleAnonymousThenAccessDeniedException() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
assertThatExceptionOfType(AccessDeniedException.class)
.isThrownBy(this.methodSecurityService::preAuthorizeNotAnonymous).withMessage("Access Denied");
}
@WithMockUser
@Test
public void preAuthorizeNotAnonymousWhenRoleUserThenPasses() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
this.methodSecurityService.preAuthorizeNotAnonymous();
}
@WithMockUser
@Test
public void securedWhenRoleUserThenAccessDeniedException() {
this.spring.register(MethodSecurityServiceEnabledConfig.class).autowire();
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.methodSecurityService::secured)
.withMessage("Access Denied");
}
@WithMockUser(roles = "ADMIN")
@Test
public void securedWhenRoleAdminThenPasses() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
String result = this.methodSecurityService.secured();
assertThat(result).isNull();
}
@WithMockUser(roles = "ADMIN")
@Test
public void securedUserWhenRoleAdminThenAccessDeniedException() {
this.spring.register(MethodSecurityServiceEnabledConfig.class).autowire();
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.methodSecurityService::securedUser)
.withMessage("Access Denied");
}
@WithMockUser
@Test
public void securedUserWhenRoleUserThenPasses() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
String result = this.methodSecurityService.securedUser();
assertThat(result).isNull();
}
@WithMockUser
@Test
public void preAuthorizeAdminWhenRoleUserThenAccessDeniedException() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.methodSecurityService::preAuthorizeAdmin)
.withMessage("Access Denied");
}
@WithMockUser(roles = "ADMIN")
@Test
public void preAuthorizeAdminWhenRoleAdminThenPasses() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
this.methodSecurityService.preAuthorizeAdmin();
}
@WithMockUser
@Test
public void postHasPermissionWhenParameterIsNotGrantThenAccessDeniedException() {
this.spring.register(CustomPermissionEvaluatorConfig.class, MethodSecurityServiceConfig.class).autowire();
assertThatExceptionOfType(AccessDeniedException.class)
.isThrownBy(() -> this.methodSecurityService.postHasPermission("deny")).withMessage("Access Denied");
}
@WithMockUser
@Test
public void postHasPermissionWhenParameterIsGrantThenPasses() {
this.spring.register(CustomPermissionEvaluatorConfig.class, MethodSecurityServiceConfig.class).autowire();
String result = this.methodSecurityService.postHasPermission("grant");
assertThat(result).isNull();
}
@WithMockUser
@Test
public void postAnnotationWhenParameterIsNotGrantThenAccessDeniedException() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
assertThatExceptionOfType(AccessDeniedException.class)
.isThrownBy(() -> this.methodSecurityService.postAnnotation("deny")).withMessage("Access Denied");
}
@WithMockUser
@Test
public void postAnnotationWhenParameterIsGrantThenPasses() {
this.spring.register(MethodSecurityServiceConfig.class).autowire();
String result = this.methodSecurityService.postAnnotation("grant");
assertThat(result).isNull();
}
@WithMockUser("bob")
@Test
public void methodReturningAListWhenPrePostFiltersConfiguredThenFiltersList() {
this.spring.register(BusinessServiceConfig.class).autowire();
List<String> names = new ArrayList<>();
names.add("bob");
names.add("joe");
names.add("sam");
List<?> result = this.businessService.methodReturningAList(names);
assertThat(result).hasSize(1);
assertThat(result.get(0)).isEqualTo("bob");
}
@WithMockUser("bob")
@Test
public void methodReturningAnArrayWhenPostFilterConfiguredThenFiltersArray() {
this.spring.register(BusinessServiceConfig.class).autowire();
List<String> names = new ArrayList<>();
names.add("bob");
names.add("joe");
names.add("sam");
Object[] result = this.businessService.methodReturningAnArray(names.toArray());
assertThat(result).hasSize(1);
assertThat(result[0]).isEqualTo("bob");
}
@WithMockUser("bob")
@Test
public void securedUserWhenCustomBeforeAdviceConfiguredAndNameBobThenPasses() {
this.spring.register(CustomAuthorizationManagerBeforeAdviceConfig.class, MethodSecurityServiceConfig.class)
.autowire();
String result = this.methodSecurityService.securedUser();
assertThat(result).isNull();
}
@WithMockUser("joe")
@Test
public void securedUserWhenCustomBeforeAdviceConfiguredAndNameNotBobThenAccessDeniedException() {
this.spring.register(CustomAuthorizationManagerBeforeAdviceConfig.class, MethodSecurityServiceConfig.class)
.autowire();
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.methodSecurityService::securedUser)
.withMessage("Access Denied");
}
@WithMockUser("bob")
@Test
public void securedUserWhenCustomAfterAdviceConfiguredAndNameBobThenGranted() {
this.spring.register(CustomAuthorizationManagerAfterAdviceConfig.class, MethodSecurityServiceConfig.class)
.autowire();
String result = this.methodSecurityService.securedUser();
assertThat(result).isEqualTo("granted");
}
@WithMockUser("joe")
@Test
public void securedUserWhenCustomAfterAdviceConfiguredAndNameNotBobThenAccessDeniedException() {
this.spring.register(CustomAuthorizationManagerAfterAdviceConfig.class, MethodSecurityServiceConfig.class)
.autowire();
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.methodSecurityService::securedUser)
.withMessage("Access Denied for User 'joe'");
}
@WithMockUser(roles = "ADMIN")
@Test
public void jsr250WhenRoleAdminThenAccessDeniedException() {
this.spring.register(MethodSecurityServiceEnabledConfig.class).autowire();
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.methodSecurityService::jsr250)
.withMessage("Access Denied");
}
@WithAnonymousUser
@Test
public void jsr250PermitAllWhenRoleAnonymousThenPasses() {
this.spring.register(MethodSecurityServiceEnabledConfig.class).autowire();
String result = this.methodSecurityService.jsr250PermitAll();
assertThat(result).isNull();
}
@WithMockUser(roles = "ADMIN")
@Test
public void rolesAllowedUserWhenRoleAdminThenAccessDeniedException() {
this.spring.register(BusinessServiceConfig.class).autowire();
assertThatExceptionOfType(AccessDeniedException.class).isThrownBy(this.businessService::rolesAllowedUser)
.withMessage("Access Denied");
}
@WithMockUser
@Test
public void rolesAllowedUserWhenRoleUserThenPasses() {
this.spring.register(BusinessServiceConfig.class).autowire();
this.businessService.rolesAllowedUser();
}
@WithMockUser(roles = { "ADMIN", "USER" })
@Test
public void manyAnnotationsWhenMeetsConditionsThenReturnsFilteredList() throws Exception {
List<String> names = Arrays.asList("harold", "jonathan", "pete", "bo");
this.spring.register(MethodSecurityServiceEnabledConfig.class).autowire();
List<String> filtered = this.methodSecurityService.manyAnnotations(new ArrayList<>(names));
assertThat(filtered).hasSize(2);
assertThat(filtered).containsExactly("harold", "jonathan");
}
@WithMockUser
@Test
public void manyAnnotationsWhenUserThenFails() {
List<String> names = Arrays.asList("harold", "jonathan", "pete", "bo");
this.spring.register(MethodSecurityServiceEnabledConfig.class).autowire();
assertThatExceptionOfType(AccessDeniedException.class)
.isThrownBy(() -> this.methodSecurityService.manyAnnotations(new ArrayList<>(names)));
}
@WithMockUser
@Test
public void manyAnnotationsWhenShortListThenFails() {
List<String> names = Arrays.asList("harold", "jonathan", "pete");
this.spring.register(MethodSecurityServiceEnabledConfig.class).autowire();
assertThatExceptionOfType(AccessDeniedException.class)
.isThrownBy(() -> this.methodSecurityService.manyAnnotations(new ArrayList<>(names)));
}
@WithMockUser(roles = "ADMIN")
@Test
public void manyAnnotationsWhenAdminThenFails() {
List<String> names = Arrays.asList("harold", "jonathan", "pete", "bo");
this.spring.register(MethodSecurityServiceEnabledConfig.class).autowire();
assertThatExceptionOfType(AccessDeniedException.class)
.isThrownBy(() -> this.methodSecurityService.manyAnnotations(new ArrayList<>(names)));
}
@Test
public void configureWhenCustomAdviceAndSecureEnabledThenException() {
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(() -> this.spring
.register(CustomAuthorizationManagerBeforeAdviceConfig.class, MethodSecurityServiceEnabledConfig.class)
.autowire());
}
@EnableMethodSecurity
static class MethodSecurityServiceConfig {
@Bean
MethodSecurityService methodSecurityService() {
return new MethodSecurityServiceImpl();
}
}
@EnableMethodSecurity(jsr250Enabled = true)
static class BusinessServiceConfig {
@Bean
BusinessService businessService() {
return new ExpressionProtectedBusinessServiceImpl();
}
}
@EnableMethodSecurity(securedEnabled = true, jsr250Enabled = true)
static class MethodSecurityServiceEnabledConfig {
@Bean
MethodSecurityService methodSecurityService() {
return new MethodSecurityServiceImpl();
}
}
@EnableMethodSecurity
static class CustomPermissionEvaluatorConfig {
@Bean
MethodSecurityExpressionHandler methodSecurityExpressionHandler() {
DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
expressionHandler.setPermissionEvaluator(new PermissionEvaluator() {
@Override
public boolean hasPermission(Authentication authentication, Object targetDomainObject,
Object permission) {
return "grant".equals(targetDomainObject);
}
@Override
public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType,
Object permission) {
throw new UnsupportedOperationException();
}
});
return expressionHandler;
}
}
@EnableMethodSecurity
static class CustomAuthorizationManagerBeforeAdviceConfig {
@Bean
AuthorizationMethodInterceptor customBeforeAdvice() {
JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
pointcut.setPattern(".*MethodSecurityServiceImpl.*securedUser");
AuthorizationManager<MethodInvocation> authorizationManager = (a,
o) -> new AuthorizationDecision("bob".equals(a.get().getName()));
return new AuthorizationManagerBeforeMethodInterceptor(pointcut, authorizationManager);
}
}
@EnableMethodSecurity
static class CustomAuthorizationManagerAfterAdviceConfig {
@Bean
AuthorizationMethodInterceptor customAfterAdvice() {
JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
pointcut.setPattern(".*MethodSecurityServiceImpl.*securedUser");
AuthorizationMethodInterceptor interceptor = new AuthorizationMethodInterceptor() {
@Override
public Pointcut getPointcut() {
return pointcut;
}
@Override
public Object invoke(Supplier<Authentication> authentication, MethodInvocation mi) {
Authentication auth = authentication.get();
if ("bob".equals(auth.getName())) {
return "granted";
}
throw new AccessDeniedException("Access Denied for User '" + auth.getName() + "'");
}
};
return interceptor;
}
}
}

View File

@@ -16,16 +16,12 @@
package org.springframework.security.config.annotation.method.configuration;
import java.util.List;
import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.access.prepost.PreFilter;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.parameters.P;
@@ -73,11 +69,4 @@ public interface MethodSecurityService {
@PostAuthorize("#o?.contains('grant')")
String postAnnotation(@P("o") String object);
@PreFilter("filterObject.length > 3")
@PreAuthorize("hasRole('ADMIN')")
@Secured("ROLE_USER")
@PostFilter("filterObject.length > 5")
@PostAuthorize("returnObject.size > 1")
List<String> manyAnnotations(List<String> array);
}

View File

@@ -16,8 +16,6 @@
package org.springframework.security.config.annotation.method.configuration;
import java.util.List;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
@@ -88,9 +86,4 @@ public class MethodSecurityServiceImpl implements MethodSecurityService {
return null;
}
@Override
public List<String> manyAnnotations(List<String> object) {
return object;
}
}