Use Interceptors instead of Advice

- Interceptor is a more descriptive term for what
method security is doing
- This also allows the code to follow a delegate
pattern that unifies both before-method and after-
method authorization

Issue gh-9289
This commit is contained in:
Josh Cummings
2021-04-08 14:31:36 -06:00
parent 122346bd27
commit df8abcfae7
37 changed files with 1010 additions and 1244 deletions

View File

@@ -27,42 +27,44 @@ import org.springframework.security.core.Authentication;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link AuthorizationManagerMethodAfterAdvice}.
* Tests for {@link AuthorizationManagerAfterMethodInterceptor}.
*
* @author Evgeniy Cheban
*/
public class AuthorizationManagerMethodAfterAdviceTests {
public class AuthorizationManagerAfterMethodInterceptorTests {
@Test
public void instantiateWhenMethodMatcherNullThenException() {
AfterMethodAuthorizationManager<MethodInvocation> mockAuthorizationManager = mock(
AfterMethodAuthorizationManager.class);
assertThatIllegalArgumentException()
.isThrownBy(() -> new AuthorizationManagerMethodAfterAdvice<>(null, mockAuthorizationManager))
.isThrownBy(() -> new AuthorizationManagerAfterMethodInterceptor(null, mockAuthorizationManager))
.withMessage("pointcut cannot be null");
}
@Test
public void instantiateWhenAuthorizationManagerNullThenException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new AuthorizationManagerMethodAfterAdvice<>(mock(Pointcut.class), null))
.isThrownBy(() -> new AuthorizationManagerAfterMethodInterceptor(mock(Pointcut.class), null))
.withMessage("authorizationManager cannot be null");
}
@Test
public void beforeWhenMockAuthorizationManagerThenVerifyAndReturnedObject() {
public void beforeWhenMockAuthorizationManagerThenVerifyAndReturnedObject() throws Throwable {
Supplier<Authentication> authentication = TestAuthentication::authenticatedUser;
MethodInvocation mockMethodInvocation = mock(MethodInvocation.class);
Object returnedObject = new Object();
given(mockMethodInvocation.proceed()).willReturn(returnedObject);
AfterMethodAuthorizationManager<MethodInvocation> mockAuthorizationManager = mock(
AfterMethodAuthorizationManager.class);
AuthorizationManagerMethodAfterAdvice<MethodInvocation> advice = new AuthorizationManagerMethodAfterAdvice<>(
mock(Pointcut.class), mockAuthorizationManager);
Object result = advice.after(authentication, mockMethodInvocation, returnedObject);
AuthorizationManagerAfterMethodInterceptor advice = new AuthorizationManagerAfterMethodInterceptor(
Pointcut.TRUE, mockAuthorizationManager);
Object result = advice.invoke(authentication, mockMethodInvocation);
assertThat(result).isEqualTo(returnedObject);
verify(mockAuthorizationManager).verify(authentication, mockMethodInvocation, returnedObject);
}

View File

@@ -31,34 +31,35 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link AuthorizationManagerMethodBeforeAdvice}.
* Tests for {@link AuthorizationManagerBeforeMethodInterceptor}.
*
* @author Evgeniy Cheban
*/
public class AuthorizationManagerMethodBeforeAdviceTests {
public class AuthorizationManagerBeforeMethodInterceptorTests {
@Test
public void instantiateWhenMethodMatcherNullThenException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new AuthorizationManagerMethodBeforeAdvice<>(null, mock(AuthorizationManager.class)))
.isThrownBy(
() -> new AuthorizationManagerBeforeMethodInterceptor(null, mock(AuthorizationManager.class)))
.withMessage("pointcut cannot be null");
}
@Test
public void instantiateWhenAuthorizationManagerNullThenException() {
assertThatIllegalArgumentException()
.isThrownBy(() -> new AuthorizationManagerMethodBeforeAdvice<>(mock(Pointcut.class), null))
.isThrownBy(() -> new AuthorizationManagerBeforeMethodInterceptor(mock(Pointcut.class), null))
.withMessage("authorizationManager cannot be null");
}
@Test
public void beforeWhenMockAuthorizationManagerThenVerify() {
public void beforeWhenMockAuthorizationManagerThenVerify() throws Throwable {
Supplier<Authentication> authentication = TestAuthentication::authenticatedUser;
MethodInvocation mockMethodInvocation = mock(MethodInvocation.class);
AuthorizationManager<MethodInvocation> mockAuthorizationManager = mock(AuthorizationManager.class);
AuthorizationManagerMethodBeforeAdvice<MethodInvocation> advice = new AuthorizationManagerMethodBeforeAdvice<>(
mock(Pointcut.class), mockAuthorizationManager);
advice.before(authentication, mockMethodInvocation);
AuthorizationManagerBeforeMethodInterceptor advice = new AuthorizationManagerBeforeMethodInterceptor(
Pointcut.TRUE, mockAuthorizationManager);
advice.invoke(authentication, mockMethodInvocation);
verify(mockAuthorizationManager).verify(authentication, mockMethodInvocation);
}

View File

@@ -0,0 +1,167 @@
/*
* 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.authorization.method;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.Test;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.AopUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link AuthorizationMethodPointcuts}
*/
public class AuthorizationMethodPointcutsTests {
@Test
public void forAnnotationsWhenAnnotationThenClassBasedAnnotationPointcut() {
Pointcut preAuthorize = AuthorizationMethodPointcuts.forAnnotations(PreAuthorize.class);
assertThat(AopUtils.canApply(preAuthorize, ClassController.class)).isTrue();
assertThat(AopUtils.canApply(preAuthorize, NoController.class)).isFalse();
}
@Test
public void forAnnotationsWhenAnnotationThenMethodBasedAnnotationPointcut() {
Pointcut preAuthorize = AuthorizationMethodPointcuts.forAnnotations(PreAuthorize.class);
assertThat(AopUtils.canApply(preAuthorize, MethodController.class)).isTrue();
}
@Test
public void forAnnotationsWhenAnnotationThenClassInheritancePointcut() {
Pointcut preAuthorize = AuthorizationMethodPointcuts.forAnnotations(PreAuthorize.class);
assertThat(AopUtils.canApply(preAuthorize, InterfacedClassController.class)).isTrue();
}
@Test
public void forAnnotationsWhenAnnotationThenMethodInheritancePointcut() {
Pointcut preAuthorize = AuthorizationMethodPointcuts.forAnnotations(PreAuthorize.class);
assertThat(AopUtils.canApply(preAuthorize, InterfacedMethodController.class)).isTrue();
}
@Test
public void forAnnotationsWhenAnnotationThenAnnotationClassInheritancePointcut() {
Pointcut preAuthorize = AuthorizationMethodPointcuts.forAnnotations(PreAuthorize.class);
assertThat(AopUtils.canApply(preAuthorize, InterfacedAnnotationClassController.class)).isTrue();
}
@Test
public void forAnnotationsWhenAnnotationThenAnnotationMethodInheritancePointcut() {
Pointcut preAuthorize = AuthorizationMethodPointcuts.forAnnotations(PreAuthorize.class);
assertThat(AopUtils.canApply(preAuthorize, InterfacedAnnotationMethodController.class)).isTrue();
}
@PreAuthorize("hasAuthority('APP')")
public static class ClassController {
String methodOne(String paramOne) {
return "value";
}
}
public static class MethodController {
@PreAuthorize("hasAuthority('APP')")
String methodOne(String paramOne) {
return "value";
}
}
public static class NoController {
String methodOne(String paramOne) {
return "value";
}
}
@PreAuthorize("hasAuthority('APP')")
public interface ClassControllerInterface {
String methodOne(String paramOne);
}
public static class InterfacedClassController implements ClassControllerInterface {
public String methodOne(String paramOne) {
return "value";
}
}
public interface MethodControllerInterface {
@PreAuthorize("hasAuthority('APP')")
String methodOne(String paramOne);
}
public static class InterfacedMethodController implements MethodControllerInterface {
public String methodOne(String paramOne) {
return "value";
}
}
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@PreAuthorize("hasAuthority('APP')")
@interface MyAnnotation {
}
@MyAnnotation
public interface ClassAnnotationControllerInterface {
String methodOne(String paramOne);
}
public static class InterfacedAnnotationClassController implements ClassAnnotationControllerInterface {
public String methodOne(String paramOne) {
return "value";
}
}
public interface MethodAnnotationControllerInterface {
@MyAnnotation
String methodOne(String paramOne);
}
public static class InterfacedAnnotationMethodController implements MethodAnnotationControllerInterface {
public String methodOne(String paramOne) {
return "value";
}
}
}

View File

@@ -1,165 +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.authorization.method;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;
import org.junit.Test;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.core.Authentication;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link DelegatingAuthorizationMethodAfterAdvice}.
*
* @author Evgeniy Cheban
*/
public class DelegatingAuthorizationMethodAfterAdviceTests {
@Test
public void methodMatcherWhenNoneMatchesThenNotMatches() throws Exception {
List<AuthorizationMethodAfterAdvice<MethodAuthorizationContext>> delegates = new ArrayList<>();
delegates.add(new AuthorizationMethodAfterAdvice<MethodAuthorizationContext>() {
@Override
public Object after(Supplier<Authentication> authentication, MethodAuthorizationContext object,
Object returnedObject) {
return returnedObject;
}
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return false;
}
};
}
});
delegates.add(new AuthorizationMethodAfterAdvice<MethodAuthorizationContext>() {
@Override
public Object after(Supplier<Authentication> authentication, MethodAuthorizationContext object,
Object returnedObject) {
return returnedObject;
}
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return false;
}
};
}
});
DelegatingAuthorizationMethodAfterAdvice advice = new DelegatingAuthorizationMethodAfterAdvice(delegates);
MethodMatcher methodMatcher = advice.getPointcut().getMethodMatcher();
assertThat(methodMatcher.matches(TestClass.class.getMethod("doSomething"), TestClass.class)).isFalse();
}
@Test
public void methodMatcherWhenAnyMatchesThenMatches() throws Exception {
List<AuthorizationMethodAfterAdvice<MethodAuthorizationContext>> delegates = new ArrayList<>();
delegates.add(new AuthorizationMethodAfterAdvice<MethodAuthorizationContext>() {
@Override
public Object after(Supplier<Authentication> authentication, MethodAuthorizationContext object,
Object returnedObject) {
return returnedObject;
}
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return false;
}
};
}
});
delegates.add(new AuthorizationMethodAfterAdvice<MethodAuthorizationContext>() {
@Override
public Object after(Supplier<Authentication> authentication, MethodAuthorizationContext object,
Object returnedObject) {
return returnedObject;
}
@Override
public Pointcut getPointcut() {
return Pointcut.TRUE;
}
});
DelegatingAuthorizationMethodAfterAdvice advice = new DelegatingAuthorizationMethodAfterAdvice(delegates);
MethodMatcher methodMatcher = advice.getPointcut().getMethodMatcher();
assertThat(methodMatcher.matches(TestClass.class.getMethod("doSomething"), TestClass.class)).isTrue();
}
@Test
public void checkWhenDelegatingAdviceModifiesReturnedObjectThenModifiedReturnedObject() throws Exception {
List<AuthorizationMethodAfterAdvice<MethodAuthorizationContext>> delegates = new ArrayList<>();
delegates.add(new AuthorizationMethodAfterAdvice<MethodAuthorizationContext>() {
@Override
public Object after(Supplier<Authentication> authentication, MethodAuthorizationContext object,
Object returnedObject) {
return returnedObject + "b";
}
@Override
public Pointcut getPointcut() {
return Pointcut.TRUE;
}
});
delegates.add(new AuthorizationMethodAfterAdvice<MethodAuthorizationContext>() {
@Override
public Object after(Supplier<Authentication> authentication, MethodAuthorizationContext object,
Object returnedObject) {
return returnedObject + "c";
}
@Override
public Pointcut getPointcut() {
return Pointcut.TRUE;
}
});
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomething");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
DelegatingAuthorizationMethodAfterAdvice advice = new DelegatingAuthorizationMethodAfterAdvice(delegates);
Object result = advice.after(TestAuthentication::authenticatedUser, methodAuthorizationContext, "a");
assertThat(result).isEqualTo("abc");
}
public static class TestClass {
public String doSomething() {
return null;
}
}
}

View File

@@ -1,164 +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.authorization.method;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Supplier;
import org.junit.Test;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.intercept.method.MockMethodInvocation;
import org.springframework.security.authentication.TestAuthentication;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.core.Authentication;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link DelegatingAuthorizationMethodBeforeAdvice}.
*
* @author Evgeniy Cheban
*/
public class DelegatingAuthorizationMethodBeforeAdviceTests {
@Test
public void methodMatcherWhenNoneMatchesThenNotMatches() throws Exception {
List<AuthorizationMethodBeforeAdvice<MethodAuthorizationContext>> delegates = new ArrayList<>();
delegates.add(new AuthorizationMethodBeforeAdvice<MethodAuthorizationContext>() {
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return false;
}
};
}
@Override
public void before(Supplier<Authentication> authentication, MethodAuthorizationContext object) {
}
});
delegates.add(new AuthorizationMethodBeforeAdvice<MethodAuthorizationContext>() {
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return false;
}
};
}
@Override
public void before(Supplier<Authentication> authentication, MethodAuthorizationContext object) {
}
});
DelegatingAuthorizationMethodBeforeAdvice advice = new DelegatingAuthorizationMethodBeforeAdvice(delegates);
MethodMatcher methodMatcher = advice.getPointcut().getMethodMatcher();
assertThat(methodMatcher.matches(TestClass.class.getMethod("doSomething"), TestClass.class)).isFalse();
}
@Test
public void methodMatcherWhenAnyMatchesThenMatches() throws Exception {
List<AuthorizationMethodBeforeAdvice<MethodAuthorizationContext>> delegates = new ArrayList<>();
delegates.add(new AuthorizationMethodBeforeAdvice<MethodAuthorizationContext>() {
@Override
public Pointcut getPointcut() {
return new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return false;
}
};
}
@Override
public void before(Supplier<Authentication> authentication, MethodAuthorizationContext object) {
}
});
delegates.add(new AuthorizationMethodBeforeAdvice<MethodAuthorizationContext>() {
@Override
public Pointcut getPointcut() {
return Pointcut.TRUE;
}
@Override
public void before(Supplier<Authentication> authentication, MethodAuthorizationContext object) {
}
});
DelegatingAuthorizationMethodBeforeAdvice advice = new DelegatingAuthorizationMethodBeforeAdvice(delegates);
MethodMatcher methodMatcher = advice.getPointcut().getMethodMatcher();
assertThat(methodMatcher.matches(TestClass.class.getMethod("doSomething"), TestClass.class)).isTrue();
}
@Test
public void checkWhenAllGrantsOrAbstainsThenPasses() throws Exception {
List<AuthorizationMethodBeforeAdvice<MethodAuthorizationContext>> delegates = new ArrayList<>();
delegates.add(new AuthorizationManagerMethodBeforeAdvice<>(Pointcut.TRUE, (a, o) -> null));
delegates.add(
new AuthorizationManagerMethodBeforeAdvice<>(Pointcut.TRUE, (a, o) -> new AuthorizationDecision(true)));
delegates.add(new AuthorizationManagerMethodBeforeAdvice<>(Pointcut.TRUE, (a, o) -> null));
DelegatingAuthorizationMethodBeforeAdvice advice = new DelegatingAuthorizationMethodBeforeAdvice(delegates);
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomething");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
advice.before(TestAuthentication::authenticatedUser, methodAuthorizationContext);
}
@Test
public void checkWhenAnyDeniesThenAccessDeniedException() throws Exception {
List<AuthorizationMethodBeforeAdvice<MethodAuthorizationContext>> delegates = new ArrayList<>();
delegates.add(new AuthorizationManagerMethodBeforeAdvice<>(Pointcut.TRUE, (a, o) -> null));
delegates.add(
new AuthorizationManagerMethodBeforeAdvice<>(Pointcut.TRUE, (a, o) -> new AuthorizationDecision(true)));
delegates.add(new AuthorizationManagerMethodBeforeAdvice<>(Pointcut.TRUE,
(a, o) -> new AuthorizationDecision(false)));
DelegatingAuthorizationMethodBeforeAdvice advice = new DelegatingAuthorizationMethodBeforeAdvice(delegates);
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomething");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
assertThatExceptionOfType(AccessDeniedException.class)
.isThrownBy(() -> advice.before(TestAuthentication::authenticatedUser, methodAuthorizationContext))
.withMessage("Access Denied");
}
@Test
public void checkWhenDelegatesEmptyThenFails() {
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> new DelegatingAuthorizationMethodBeforeAdvice(Collections.emptyList()));
}
public static class TestClass {
public void doSomething() {
}
}
}

View File

@@ -16,8 +16,10 @@
package org.springframework.security.authorization.method;
import java.util.Arrays;
import java.util.function.Supplier;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.After;
import org.junit.Test;
@@ -32,18 +34,17 @@ import org.springframework.security.core.context.SecurityContextImpl;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoInteractions;
/**
* Tests for {@link AuthorizationMethodInterceptor}.
* Tests for {@link DelegatingAuthorizationMethodInterceptor}.
*
* @author Evgeniy Cheban
*/
public class AuthorizationMethodInterceptorTests {
public class DelegatingAuthorizationMethodInterceptorTests {
@After
public void tearDown() {
@@ -56,41 +57,39 @@ public class AuthorizationMethodInterceptorTests {
SecurityContextHolder.setContext(new SecurityContextImpl(authentication));
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingString");
AuthorizationMethodBeforeAdvice<MethodAuthorizationContext> mockBeforeAdvice = mock(
AuthorizationMethodBeforeAdvice.class);
AuthorizationMethodAfterAdvice<MethodAuthorizationContext> mockAfterAdvice = mock(
AuthorizationMethodAfterAdvice.class);
given(mockAfterAdvice.after(any(), any(MethodAuthorizationContext.class), eq(null))).willReturn("abc");
AuthorizationMethodInterceptor interceptor = new AuthorizationMethodInterceptor(mockBeforeAdvice,
mockAfterAdvice);
Object result = interceptor.invoke(mockMethodInvocation);
AuthorizationMethodInterceptor interceptor = mock(AuthorizationMethodInterceptor.class);
given(interceptor.getPointcut()).willReturn(Pointcut.TRUE);
given(interceptor.invoke(any(), any(AuthorizationMethodInvocation.class))).willReturn("abc");
DelegatingAuthorizationMethodInterceptor chain = new DelegatingAuthorizationMethodInterceptor(
Arrays.asList(interceptor));
Object result = chain.invoke(mockMethodInvocation);
assertThat(result).isEqualTo("abc");
verify(mockAfterAdvice).after(any(), any(MethodAuthorizationContext.class), eq(null));
verify(interceptor).invoke(any(), any(AuthorizationMethodInvocation.class));
}
@Test
public void invokeWhenNotAuthenticatedThenAuthenticationCredentialsNotFoundException() throws Exception {
public void invokeWhenNotAuthenticatedThenAuthenticationCredentialsNotFoundException() throws Throwable {
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingString");
AuthorizationMethodBeforeAdvice<MethodAuthorizationContext> beforeAdvice = new AuthorizationMethodBeforeAdvice<MethodAuthorizationContext>() {
AuthorizationMethodInterceptor first = new AuthorizationMethodInterceptor() {
@Override
public Pointcut getPointcut() {
return Pointcut.TRUE;
}
@Override
public void before(Supplier<Authentication> authentication,
MethodAuthorizationContext methodAuthorizationContext) {
authentication.get();
public Object invoke(Supplier<Authentication> authentication, MethodInvocation mi) {
return authentication.get();
}
};
AuthorizationMethodAfterAdvice<MethodAuthorizationContext> mockAfterAdvice = mock(
AuthorizationMethodAfterAdvice.class);
AuthorizationMethodInterceptor interceptor = new AuthorizationMethodInterceptor(beforeAdvice, mockAfterAdvice);
AuthorizationMethodInterceptor second = mock(AuthorizationMethodInterceptor.class);
given(second.getPointcut()).willReturn(Pointcut.TRUE);
DelegatingAuthorizationMethodInterceptor interceptor = new DelegatingAuthorizationMethodInterceptor(
Arrays.asList(first, second));
assertThatExceptionOfType(AuthenticationCredentialsNotFoundException.class)
.isThrownBy(() -> interceptor.invoke(mockMethodInvocation))
.withMessage("An Authentication object was not found in the SecurityContext");
verifyNoInteractions(mockAfterAdvice);
verify(second, times(0)).invoke(any(), any());
}
public static class TestClass {

View File

@@ -16,6 +16,7 @@
package org.springframework.security.authorization.method;
import java.util.Collections;
import java.util.function.Supplier;
import javax.annotation.security.DenyAll;
@@ -62,64 +63,59 @@ public class Jsr250AuthorizationManagerTests {
@Test
public void checkDoSomethingWhenNoJsr250AnnotationsThenNullDecision() throws Exception {
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomething");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(methodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
Jsr250AuthorizationManager manager = new Jsr250AuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation);
assertThat(decision).isNull();
}
@Test
public void checkPermitAllRolesAllowedAdminWhenRoleUserThenGrantedDecision() throws Exception {
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"permitAllRolesAllowedAdmin");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(methodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
Jsr250AuthorizationManager manager = new Jsr250AuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
@Test
public void checkDenyAllRolesAllowedAdminWhenRoleAdminThenDeniedDecision() throws Exception {
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"denyAllRolesAllowedAdmin");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(methodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
Jsr250AuthorizationManager manager = new Jsr250AuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedAdmin,
methodAuthorizationContext);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedAdmin, methodInvocation);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isFalse();
}
@Test
public void checkRolesAllowedUserOrAdminWhenRoleUserThenGrantedDecision() throws Exception {
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"rolesAllowedUserOrAdmin");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(methodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
Jsr250AuthorizationManager manager = new Jsr250AuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
@Test
public void checkRolesAllowedUserOrAdminWhenRoleAdminThenGrantedDecision() throws Exception {
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"rolesAllowedUserOrAdmin");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(methodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
Jsr250AuthorizationManager manager = new Jsr250AuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedAdmin,
methodAuthorizationContext);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedAdmin, methodInvocation);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
@@ -128,12 +124,12 @@ public class Jsr250AuthorizationManagerTests {
public void checkRolesAllowedUserOrAdminWhenRoleAnonymousThenDeniedDecision() throws Exception {
Supplier<Authentication> authentication = () -> new TestingAuthenticationToken("user", "password",
"ROLE_ANONYMOUS");
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"rolesAllowedUserOrAdmin");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(methodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
Jsr250AuthorizationManager manager = new Jsr250AuthorizationManager();
AuthorizationDecision decision = manager.check(authentication, methodAuthorizationContext);
AuthorizationDecision decision = manager.check(authentication, methodInvocation);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isFalse();
}

View File

@@ -58,11 +58,10 @@ public class PostAuthorizeAuthorizationManagerTests {
public void checkDoSomethingWhenNoPostAuthorizeAnnotationThenNullDecision() throws Exception {
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomething", new Class[] {}, new Object[] {});
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext, null);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation, null);
assertThat(decision).isNull();
}
@@ -70,11 +69,10 @@ public class PostAuthorizeAuthorizationManagerTests {
public void checkDoSomethingStringWhenArgIsGrantThenGrantedDecision() throws Exception {
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingString", new Class[] { String.class }, new Object[] { "grant" });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext, null);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
@@ -83,11 +81,10 @@ public class PostAuthorizeAuthorizationManagerTests {
public void checkDoSomethingStringWhenArgIsNotGrantThenDeniedDecision() throws Exception {
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingString", new Class[] { String.class }, new Object[] { "deny" });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext, null);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation, null);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isFalse();
}
@@ -97,11 +94,10 @@ public class PostAuthorizeAuthorizationManagerTests {
List<String> list = Arrays.asList("grant", "deny");
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingList", new Class[] { List.class }, new Object[] { list });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext, list);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation, list);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
@@ -111,11 +107,10 @@ public class PostAuthorizeAuthorizationManagerTests {
List<String> list = Collections.singletonList("deny");
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingList", new Class[] { List.class }, new Object[] { list });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext, list);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation, list);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isFalse();
}

View File

@@ -16,14 +16,12 @@
package org.springframework.security.authorization.method;
import java.lang.reflect.Method;
import java.util.Collections;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.Test;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.access.intercept.method.MockMethodInvocation;
@@ -34,43 +32,38 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* Tests for {@link PostFilterAuthorizationMethodAfterAdvice}.
* Tests for {@link PostFilterAuthorizationMethodInterceptor}.
*
* @author Evgeniy Cheban
*/
public class PostFilterAuthorizationMethodAfterAdviceTests {
public class PostFilterAuthorizationMethodInterceptorTests {
@Test
public void setExpressionHandlerWhenNotNullThenSetsExpressionHandler() {
MethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
PostFilterAuthorizationMethodAfterAdvice advice = new PostFilterAuthorizationMethodAfterAdvice(Pointcut.TRUE);
PostFilterAuthorizationMethodInterceptor advice = new PostFilterAuthorizationMethodInterceptor();
advice.setExpressionHandler(expressionHandler);
assertThat(advice).extracting("expressionHandler").isEqualTo(expressionHandler);
}
@Test
public void setExpressionHandlerWhenNullThenException() {
PostFilterAuthorizationMethodAfterAdvice advice = new PostFilterAuthorizationMethodAfterAdvice(Pointcut.TRUE);
PostFilterAuthorizationMethodInterceptor advice = new PostFilterAuthorizationMethodInterceptor();
assertThatIllegalArgumentException().isThrownBy(() -> advice.setExpressionHandler(null))
.withMessage("expressionHandler cannot be null");
}
@Test
public void methodMatcherWhenMethodHasNotPostFilterAnnotationThenNotMatches() throws Exception {
PostFilterAuthorizationMethodAfterAdvice advice = new PostFilterAuthorizationMethodAfterAdvice(
new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return false;
}
});
PostFilterAuthorizationMethodInterceptor advice = new PostFilterAuthorizationMethodInterceptor();
MethodMatcher methodMatcher = advice.getPointcut().getMethodMatcher();
assertThat(methodMatcher.matches(TestClass.class.getMethod("doSomething"), TestClass.class)).isFalse();
assertThat(methodMatcher.matches(NoPostFilterClass.class.getMethod("doSomething"), NoPostFilterClass.class))
.isFalse();
}
@Test
public void methodMatcherWhenMethodHasPostFilterAnnotationThenMatches() throws Exception {
PostFilterAuthorizationMethodAfterAdvice advice = new PostFilterAuthorizationMethodAfterAdvice(Pointcut.TRUE);
PostFilterAuthorizationMethodInterceptor advice = new PostFilterAuthorizationMethodInterceptor();
MethodMatcher methodMatcher = advice.getPointcut().getMethodMatcher();
assertThat(
methodMatcher.matches(TestClass.class.getMethod("doSomethingArray", String[].class), TestClass.class))
@@ -78,24 +71,25 @@ public class PostFilterAuthorizationMethodAfterAdviceTests {
}
@Test
public void afterWhenArrayNotNullThenFilteredArray() throws Exception {
public void afterWhenArrayNotNullThenFilteredArray() throws Throwable {
String[] array = { "john", "bob" };
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingArrayClassLevel", new Class[] { String[].class }, new Object[] { array });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
PostFilterAuthorizationMethodAfterAdvice advice = new PostFilterAuthorizationMethodAfterAdvice(Pointcut.TRUE);
Object result = advice.after(TestAuthentication::authenticatedUser, methodAuthorizationContext, array);
"doSomethingArrayClassLevel", new Class[] { String[].class }, new Object[] { array }) {
@Override
public Object proceed() {
return array;
}
};
PostFilterAuthorizationMethodInterceptor advice = new PostFilterAuthorizationMethodInterceptor();
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
Object result = advice.invoke(TestAuthentication::authenticatedUser, methodInvocation);
assertThat(result).asInstanceOf(InstanceOfAssertFactories.array(String[].class)).containsOnly("john");
}
@PostFilter("filterObject == 'john'")
public static class TestClass {
public void doSomething() {
}
@PostFilter("filterObject == 'john'")
public String[] doSomethingArray(String[] array) {
return array;
@@ -107,4 +101,12 @@ public class PostFilterAuthorizationMethodAfterAdviceTests {
}
public static class NoPostFilterClass {
public void doSomething() {
}
}
}

View File

@@ -16,6 +16,8 @@
package org.springframework.security.authorization.method;
import java.util.Collections;
import org.junit.Test;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
@@ -54,11 +56,10 @@ public class PreAuthorizeAuthorizationManagerTests {
public void checkDoSomethingWhenNoPostAuthorizeAnnotationThenNullDecision() throws Exception {
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomething", new Class[] {}, new Object[] {});
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation);
assertThat(decision).isNull();
}
@@ -66,11 +67,10 @@ public class PreAuthorizeAuthorizationManagerTests {
public void checkDoSomethingStringWhenArgIsGrantThenGrantedDecision() throws Exception {
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingString", new Class[] { String.class }, new Object[] { "grant" });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
@@ -79,11 +79,10 @@ public class PreAuthorizeAuthorizationManagerTests {
public void checkDoSomethingStringWhenArgIsNotGrantThenDeniedDecision() throws Exception {
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingString", new Class[] { String.class }, new Object[] { "deny" });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isFalse();
}

View File

@@ -16,15 +16,13 @@
package org.springframework.security.authorization.method;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.StaticMethodMatcherPointcut;
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
import org.springframework.security.access.intercept.method.MockMethodInvocation;
@@ -36,43 +34,38 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
/**
* Tests for {@link PreFilterAuthorizationMethodBeforeAdvice}.
* Tests for {@link PreFilterAuthorizationMethodInterceptor}.
*
* @author Evgeniy Cheban
*/
public class PreFilterAuthorizationMethodBeforeAdviceTests {
public class PreFilterAuthorizationMethodInterceptorTests {
@Test
public void setExpressionHandlerWhenNotNullThenSetsExpressionHandler() {
MethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
PreFilterAuthorizationMethodBeforeAdvice advice = new PreFilterAuthorizationMethodBeforeAdvice(Pointcut.TRUE);
PreFilterAuthorizationMethodInterceptor advice = new PreFilterAuthorizationMethodInterceptor();
advice.setExpressionHandler(expressionHandler);
assertThat(advice).extracting("expressionHandler").isEqualTo(expressionHandler);
}
@Test
public void setExpressionHandlerWhenNullThenException() {
PreFilterAuthorizationMethodBeforeAdvice advice = new PreFilterAuthorizationMethodBeforeAdvice(Pointcut.TRUE);
PreFilterAuthorizationMethodInterceptor advice = new PreFilterAuthorizationMethodInterceptor();
assertThatIllegalArgumentException().isThrownBy(() -> advice.setExpressionHandler(null))
.withMessage("expressionHandler cannot be null");
}
@Test
public void methodMatcherWhenMethodHasNotPreFilterAnnotationThenNotMatches() throws Exception {
PreFilterAuthorizationMethodBeforeAdvice advice = new PreFilterAuthorizationMethodBeforeAdvice(
new StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return false;
}
});
PreFilterAuthorizationMethodInterceptor advice = new PreFilterAuthorizationMethodInterceptor();
MethodMatcher methodMatcher = advice.getPointcut().getMethodMatcher();
assertThat(methodMatcher.matches(TestClass.class.getMethod("doSomething"), TestClass.class)).isFalse();
assertThat(methodMatcher.matches(NoPreFilterClass.class.getMethod("doSomething"), NoPreFilterClass.class))
.isFalse();
}
@Test
public void methodMatcherWhenMethodHasPreFilterAnnotationThenMatches() throws Exception {
PreFilterAuthorizationMethodBeforeAdvice advice = new PreFilterAuthorizationMethodBeforeAdvice(Pointcut.TRUE);
PreFilterAuthorizationMethodInterceptor advice = new PreFilterAuthorizationMethodInterceptor();
MethodMatcher methodMatcher = advice.getPointcut().getMethodMatcher();
assertThat(methodMatcher.matches(TestClass.class.getMethod("doSomethingListFilterTargetMatch", List.class),
TestClass.class)).isTrue();
@@ -82,12 +75,11 @@ public class PreFilterAuthorizationMethodBeforeAdviceTests {
public void findFilterTargetWhenNameProvidedAndNotMatchThenException() throws Exception {
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingListFilterTargetNotMatch", new Class[] { List.class }, new Object[] { new ArrayList<>() });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
PreFilterAuthorizationMethodBeforeAdvice advice = new PreFilterAuthorizationMethodBeforeAdvice(Pointcut.TRUE);
PreFilterAuthorizationMethodInterceptor advice = new PreFilterAuthorizationMethodInterceptor();
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
assertThatIllegalArgumentException()
.isThrownBy(() -> advice.before(TestAuthentication::authenticatedUser, methodAuthorizationContext))
.withMessage(
.isThrownBy(() -> advice.invoke(TestAuthentication::authenticatedUser, methodInvocation)).withMessage(
"Filter target was null, or no argument with name 'filterTargetNotMatch' found in method.");
}
@@ -95,25 +87,25 @@ public class PreFilterAuthorizationMethodBeforeAdviceTests {
public void findFilterTargetWhenNameProvidedAndMatchAndNullThenException() throws Exception {
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingListFilterTargetMatch", new Class[] { List.class }, new Object[] { null });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
PreFilterAuthorizationMethodBeforeAdvice advice = new PreFilterAuthorizationMethodBeforeAdvice(Pointcut.TRUE);
PreFilterAuthorizationMethodInterceptor advice = new PreFilterAuthorizationMethodInterceptor();
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
assertThatIllegalArgumentException()
.isThrownBy(() -> advice.before(TestAuthentication::authenticatedUser, methodAuthorizationContext))
.isThrownBy(() -> advice.invoke(TestAuthentication::authenticatedUser, methodInvocation))
.withMessage("Filter target was null, or no argument with name 'list' found in method.");
}
@Test
public void findFilterTargetWhenNameProvidedAndMatchAndNotNullThenFiltersList() throws Exception {
public void findFilterTargetWhenNameProvidedAndMatchAndNotNullThenFiltersList() throws Throwable {
List<String> list = new ArrayList<>();
list.add("john");
list.add("bob");
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingListFilterTargetMatch", new Class[] { List.class }, new Object[] { list });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
PreFilterAuthorizationMethodBeforeAdvice advice = new PreFilterAuthorizationMethodBeforeAdvice(Pointcut.TRUE);
advice.before(TestAuthentication::authenticatedUser, methodAuthorizationContext);
PreFilterAuthorizationMethodInterceptor advice = new PreFilterAuthorizationMethodInterceptor();
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
advice.invoke(TestAuthentication::authenticatedUser, methodInvocation);
assertThat(list).hasSize(1);
assertThat(list.get(0)).isEqualTo("john");
}
@@ -122,25 +114,25 @@ public class PreFilterAuthorizationMethodBeforeAdviceTests {
public void findFilterTargetWhenNameNotProvidedAndSingleArgListNullThenException() throws Exception {
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingListFilterTargetNotProvided", new Class[] { List.class }, new Object[] { null });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
PreFilterAuthorizationMethodBeforeAdvice advice = new PreFilterAuthorizationMethodBeforeAdvice(Pointcut.TRUE);
PreFilterAuthorizationMethodInterceptor advice = new PreFilterAuthorizationMethodInterceptor();
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
assertThatIllegalArgumentException()
.isThrownBy(() -> advice.before(TestAuthentication::authenticatedUser, methodAuthorizationContext))
.isThrownBy(() -> advice.invoke(TestAuthentication::authenticatedUser, methodInvocation))
.withMessage("Filter target was null. Make sure you passing the correct value in the method argument.");
}
@Test
public void findFilterTargetWhenNameNotProvidedAndSingleArgListThenFiltersList() throws Exception {
public void findFilterTargetWhenNameNotProvidedAndSingleArgListThenFiltersList() throws Throwable {
List<String> list = new ArrayList<>();
list.add("john");
list.add("bob");
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingListFilterTargetNotProvided", new Class[] { List.class }, new Object[] { list });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
PreFilterAuthorizationMethodBeforeAdvice advice = new PreFilterAuthorizationMethodBeforeAdvice(Pointcut.TRUE);
advice.before(TestAuthentication::authenticatedUser, methodAuthorizationContext);
PreFilterAuthorizationMethodInterceptor advice = new PreFilterAuthorizationMethodInterceptor();
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
advice.invoke(TestAuthentication::authenticatedUser, methodInvocation);
assertThat(list).hasSize(1);
assertThat(list.get(0)).isEqualTo("john");
}
@@ -150,12 +142,11 @@ public class PreFilterAuthorizationMethodBeforeAdviceTests {
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingArrayFilterTargetNotProvided", new Class[] { String[].class },
new Object[] { new String[] {} });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
PreFilterAuthorizationMethodBeforeAdvice advice = new PreFilterAuthorizationMethodBeforeAdvice(Pointcut.TRUE);
PreFilterAuthorizationMethodInterceptor advice = new PreFilterAuthorizationMethodInterceptor();
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
assertThatIllegalStateException()
.isThrownBy(() -> advice.before(TestAuthentication::authenticatedUser, methodAuthorizationContext))
.withMessage(
.isThrownBy(() -> advice.invoke(TestAuthentication::authenticatedUser, methodInvocation)).withMessage(
"Pre-filtering on array types is not supported. Using a Collection will solve this problem.");
}
@@ -164,21 +155,17 @@ public class PreFilterAuthorizationMethodBeforeAdviceTests {
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomethingTwoArgsFilterTargetNotProvided", new Class[] { String.class, List.class },
new Object[] { "", new ArrayList<>() });
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(mockMethodInvocation,
TestClass.class);
PreFilterAuthorizationMethodBeforeAdvice advice = new PreFilterAuthorizationMethodBeforeAdvice(Pointcut.TRUE);
PreFilterAuthorizationMethodInterceptor advice = new PreFilterAuthorizationMethodInterceptor();
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
assertThatIllegalStateException()
.isThrownBy(() -> advice.before(TestAuthentication::authenticatedUser, methodAuthorizationContext))
.isThrownBy(() -> advice.invoke(TestAuthentication::authenticatedUser, methodInvocation))
.withMessage("Unable to determine the method argument for filtering. Specify the filter target.");
}
@PreFilter("filterObject == 'john'")
public static class TestClass {
public void doSomething() {
}
@PreFilter(value = "filterObject == 'john'", filterTarget = "filterTargetNotMatch")
public List<String> doSomethingListFilterTargetNotMatch(List<String> list) {
return list;
@@ -205,4 +192,12 @@ public class PreFilterAuthorizationMethodBeforeAdviceTests {
}
public static class NoPreFilterClass {
public void doSomething() {
}
}
}

View File

@@ -16,6 +16,7 @@
package org.springframework.security.authorization.method;
import java.util.Collections;
import java.util.function.Supplier;
import org.junit.Test;
@@ -38,38 +39,35 @@ public class SecuredAuthorizationManagerTests {
@Test
public void checkDoSomethingWhenNoSecuredAnnotationThenNullDecision() throws Exception {
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"doSomething");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(methodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
SecuredAuthorizationManager manager = new SecuredAuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation);
assertThat(decision).isNull();
}
@Test
public void checkSecuredUserOrAdminWhenRoleUserThenGrantedDecision() throws Exception {
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"securedUserOrAdmin");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(methodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedUser, mockMethodInvocation, Collections.emptyList());
SecuredAuthorizationManager manager = new SecuredAuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser,
methodAuthorizationContext);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
@Test
public void checkSecuredUserOrAdminWhenRoleAdminThenGrantedDecision() throws Exception {
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"securedUserOrAdmin");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(methodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(
TestAuthentication::authenticatedAdmin, mockMethodInvocation, Collections.emptyList());
SecuredAuthorizationManager manager = new SecuredAuthorizationManager();
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedAdmin,
methodAuthorizationContext);
AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedAdmin, methodInvocation);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isTrue();
}
@@ -78,12 +76,12 @@ public class SecuredAuthorizationManagerTests {
public void checkSecuredUserOrAdminWhenRoleAnonymousThenDeniedDecision() throws Exception {
Supplier<Authentication> authentication = () -> new TestingAuthenticationToken("user", "password",
"ROLE_ANONYMOUS");
MockMethodInvocation methodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
MockMethodInvocation mockMethodInvocation = new MockMethodInvocation(new TestClass(), TestClass.class,
"securedUserOrAdmin");
MethodAuthorizationContext methodAuthorizationContext = new MethodAuthorizationContext(methodInvocation,
TestClass.class);
AuthorizationMethodInvocation methodInvocation = new AuthorizationMethodInvocation(authentication,
mockMethodInvocation, Collections.emptyList());
SecuredAuthorizationManager manager = new SecuredAuthorizationManager();
AuthorizationDecision decision = manager.check(authentication, methodAuthorizationContext);
AuthorizationDecision decision = manager.check(authentication, methodInvocation);
assertThat(decision).isNotNull();
assertThat(decision.isGranted()).isFalse();
}