diff --git a/core/src/main/java/org/springframework/security/authorization/method/AbstractExpressionAttributeRegistry.java b/core/src/main/java/org/springframework/security/authorization/method/AbstractExpressionAttributeRegistry.java index 42b7cd92c03..23693f7c93d 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/AbstractExpressionAttributeRegistry.java +++ b/core/src/main/java/org/springframework/security/authorization/method/AbstractExpressionAttributeRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 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. @@ -29,6 +29,7 @@ * For internal use only, as this contract is likely to change * * @author Evgeniy Cheban + * @author DingHao */ abstract class AbstractExpressionAttributeRegistry { @@ -67,4 +68,8 @@ final T getAttribute(Method method, Class targetClass) { @NonNull abstract T resolveAttribute(Method method, Class targetClass); + Class targetClass(Method method, Class targetClass) { + return (targetClass != null) ? targetClass : method.getDeclaringClass(); + } + } diff --git a/core/src/main/java/org/springframework/security/authorization/method/Jsr250AuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/method/Jsr250AuthorizationManager.java index beb318ed15f..f913db85f68 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/Jsr250AuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/method/Jsr250AuthorizationManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 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. @@ -44,6 +44,7 @@ * * @author Evgeniy Cheban * @author Josh Cummings + * @author DingHao * @since 5.6 */ public final class Jsr250AuthorizationManager implements AuthorizationManager { @@ -121,7 +122,8 @@ AuthorizationManager resolveManager(Method method, Class ta private Annotation findJsr250Annotation(Method method, Class targetClass) { Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass); Annotation annotation = findAnnotation(specificMethod); - return (annotation != null) ? annotation : findAnnotation(specificMethod.getDeclaringClass()); + return (annotation != null) ? annotation + : findAnnotation((targetClass != null) ? targetClass : specificMethod.getDeclaringClass()); } private Annotation findAnnotation(Method method) { diff --git a/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeExpressionAttributeRegistry.java b/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeExpressionAttributeRegistry.java index c89bbc3e312..300fd08f7ee 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeExpressionAttributeRegistry.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PostAuthorizeExpressionAttributeRegistry.java @@ -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. @@ -31,6 +31,7 @@ * For internal use only, as this contract is likely to change. * * @author Evgeniy Cheban + * @author DingHao * @since 5.8 */ final class PostAuthorizeExpressionAttributeRegistry extends AbstractExpressionAttributeRegistry { @@ -54,7 +55,7 @@ MethodSecurityExpressionHandler getExpressionHandler() { @Override ExpressionAttribute resolveAttribute(Method method, Class targetClass) { Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass); - PostAuthorize postAuthorize = findPostAuthorizeAnnotation(specificMethod); + PostAuthorize postAuthorize = findPostAuthorizeAnnotation(specificMethod, targetClass); if (postAuthorize == null) { return ExpressionAttribute.NULL_ATTRIBUTE; } @@ -63,10 +64,10 @@ ExpressionAttribute resolveAttribute(Method method, Class targetClass) { return new ExpressionAttribute(postAuthorizeExpression); } - private PostAuthorize findPostAuthorizeAnnotation(Method method) { + private PostAuthorize findPostAuthorizeAnnotation(Method method, Class targetClass) { PostAuthorize postAuthorize = AuthorizationAnnotationUtils.findUniqueAnnotation(method, PostAuthorize.class); - return (postAuthorize != null) ? postAuthorize - : AuthorizationAnnotationUtils.findUniqueAnnotation(method.getDeclaringClass(), PostAuthorize.class); + return (postAuthorize != null) ? postAuthorize : AuthorizationAnnotationUtils + .findUniqueAnnotation(targetClass(method, targetClass), PostAuthorize.class); } } diff --git a/core/src/main/java/org/springframework/security/authorization/method/PostFilterExpressionAttributeRegistry.java b/core/src/main/java/org/springframework/security/authorization/method/PostFilterExpressionAttributeRegistry.java index 4bc33bc493d..541d2caae54 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PostFilterExpressionAttributeRegistry.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PostFilterExpressionAttributeRegistry.java @@ -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. @@ -30,6 +30,7 @@ * For internal use only, as this contract is likely to change. * * @author Evgeniy Cheban + * @author DingHao * @since 5.8 */ final class PostFilterExpressionAttributeRegistry extends AbstractExpressionAttributeRegistry { @@ -53,7 +54,7 @@ MethodSecurityExpressionHandler getExpressionHandler() { @Override ExpressionAttribute resolveAttribute(Method method, Class targetClass) { Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass); - PostFilter postFilter = findPostFilterAnnotation(specificMethod); + PostFilter postFilter = findPostFilterAnnotation(specificMethod, targetClass); if (postFilter == null) { return ExpressionAttribute.NULL_ATTRIBUTE; } @@ -62,10 +63,10 @@ ExpressionAttribute resolveAttribute(Method method, Class targetClass) { return new ExpressionAttribute(postFilterExpression); } - private PostFilter findPostFilterAnnotation(Method method) { + private PostFilter findPostFilterAnnotation(Method method, Class targetClass) { PostFilter postFilter = AuthorizationAnnotationUtils.findUniqueAnnotation(method, PostFilter.class); return (postFilter != null) ? postFilter - : AuthorizationAnnotationUtils.findUniqueAnnotation(method.getDeclaringClass(), PostFilter.class); + : AuthorizationAnnotationUtils.findUniqueAnnotation(targetClass(method, targetClass), PostFilter.class); } } diff --git a/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeExpressionAttributeRegistry.java b/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeExpressionAttributeRegistry.java index dcae13eb205..0c445a37d1f 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeExpressionAttributeRegistry.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PreAuthorizeExpressionAttributeRegistry.java @@ -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. @@ -31,6 +31,7 @@ * For internal use only, as this contract is likely to change. * * @author Evgeniy Cheban + * @author DingHao * @since 5.8 */ final class PreAuthorizeExpressionAttributeRegistry extends AbstractExpressionAttributeRegistry { @@ -58,7 +59,7 @@ MethodSecurityExpressionHandler getExpressionHandler() { @Override ExpressionAttribute resolveAttribute(Method method, Class targetClass) { Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass); - PreAuthorize preAuthorize = findPreAuthorizeAnnotation(specificMethod); + PreAuthorize preAuthorize = findPreAuthorizeAnnotation(specificMethod, targetClass); if (preAuthorize == null) { return ExpressionAttribute.NULL_ATTRIBUTE; } @@ -67,10 +68,10 @@ ExpressionAttribute resolveAttribute(Method method, Class targetClass) { return new ExpressionAttribute(preAuthorizeExpression); } - private PreAuthorize findPreAuthorizeAnnotation(Method method) { + private PreAuthorize findPreAuthorizeAnnotation(Method method, Class targetClass) { PreAuthorize preAuthorize = AuthorizationAnnotationUtils.findUniqueAnnotation(method, PreAuthorize.class); - return (preAuthorize != null) ? preAuthorize - : AuthorizationAnnotationUtils.findUniqueAnnotation(method.getDeclaringClass(), PreAuthorize.class); + return (preAuthorize != null) ? preAuthorize : AuthorizationAnnotationUtils + .findUniqueAnnotation(targetClass(method, targetClass), PreAuthorize.class); } } diff --git a/core/src/main/java/org/springframework/security/authorization/method/PreFilterExpressionAttributeRegistry.java b/core/src/main/java/org/springframework/security/authorization/method/PreFilterExpressionAttributeRegistry.java index 6fa8448355a..67bab2c7ff7 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/PreFilterExpressionAttributeRegistry.java +++ b/core/src/main/java/org/springframework/security/authorization/method/PreFilterExpressionAttributeRegistry.java @@ -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. @@ -30,6 +30,7 @@ * For internal use only, as this contract is likely to change. * * @author Evgeniy Cheban + * @author DingHao * @since 5.8 */ final class PreFilterExpressionAttributeRegistry @@ -54,7 +55,7 @@ MethodSecurityExpressionHandler getExpressionHandler() { @Override PreFilterExpressionAttribute resolveAttribute(Method method, Class targetClass) { Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass); - PreFilter preFilter = findPreFilterAnnotation(specificMethod); + PreFilter preFilter = findPreFilterAnnotation(specificMethod, targetClass); if (preFilter == null) { return PreFilterExpressionAttribute.NULL_ATTRIBUTE; } @@ -63,10 +64,10 @@ PreFilterExpressionAttribute resolveAttribute(Method method, Class targetClas return new PreFilterExpressionAttribute(preFilterExpression, preFilter.filterTarget()); } - private PreFilter findPreFilterAnnotation(Method method) { + private PreFilter findPreFilterAnnotation(Method method, Class targetClass) { PreFilter preFilter = AuthorizationAnnotationUtils.findUniqueAnnotation(method, PreFilter.class); return (preFilter != null) ? preFilter - : AuthorizationAnnotationUtils.findUniqueAnnotation(method.getDeclaringClass(), PreFilter.class); + : AuthorizationAnnotationUtils.findUniqueAnnotation(targetClass(method, targetClass), PreFilter.class); } static final class PreFilterExpressionAttribute extends ExpressionAttribute { diff --git a/core/src/main/java/org/springframework/security/authorization/method/SecuredAuthorizationManager.java b/core/src/main/java/org/springframework/security/authorization/method/SecuredAuthorizationManager.java index dcfc8a8511f..63553503d21 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/SecuredAuthorizationManager.java +++ b/core/src/main/java/org/springframework/security/authorization/method/SecuredAuthorizationManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 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. @@ -41,6 +41,7 @@ * contains a specified authority from the Spring Security's {@link Secured} annotation. * * @author Evgeniy Cheban + * @author DingHao * @since 5.6 */ public final class SecuredAuthorizationManager implements AuthorizationManager { @@ -86,14 +87,14 @@ private Set getAuthorities(MethodInvocation methodInvocation) { private Set resolveAuthorities(Method method, Class targetClass) { Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass); - Secured secured = findSecuredAnnotation(specificMethod); + Secured secured = findSecuredAnnotation(specificMethod, targetClass); return (secured != null) ? Set.of(secured.value()) : Collections.emptySet(); } - private Secured findSecuredAnnotation(Method method) { + private Secured findSecuredAnnotation(Method method, Class targetClass) { Secured secured = AuthorizationAnnotationUtils.findUniqueAnnotation(method, Secured.class); - return (secured != null) ? secured - : AuthorizationAnnotationUtils.findUniqueAnnotation(method.getDeclaringClass(), Secured.class); + return (secured != null) ? secured : AuthorizationAnnotationUtils + .findUniqueAnnotation((targetClass != null) ? targetClass : method.getDeclaringClass(), Secured.class); } } diff --git a/core/src/test/java/org/springframework/security/authorization/method/Jsr250AuthorizationManagerTests.java b/core/src/test/java/org/springframework/security/authorization/method/Jsr250AuthorizationManagerTests.java index 5a35b884895..59187469232 100644 --- a/core/src/test/java/org/springframework/security/authorization/method/Jsr250AuthorizationManagerTests.java +++ b/core/src/test/java/org/springframework/security/authorization/method/Jsr250AuthorizationManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 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. @@ -225,6 +225,56 @@ public void checkInheritedAnnotationsWhenConflictingThenAnnotationConfigurationE .isThrownBy(() -> manager.check(authentication, methodInvocation)); } + @Test + public void checkRequiresUserWhenMethodsFromInheritThenApplies() throws Exception { + MockMethodInvocation methodInvocation = new MockMethodInvocation(new RolesAllowedClass(), + RolesAllowedClass.class, "securedUser"); + Jsr250AuthorizationManager manager = new Jsr250AuthorizationManager(); + AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation); + assertThat(decision.isGranted()).isTrue(); + } + + @Test + public void checkPermitAllWhenMethodsFromInheritThenApplies() throws Exception { + MockMethodInvocation methodInvocation = new MockMethodInvocation(new PermitAllClass(), PermitAllClass.class, + "securedUser"); + Jsr250AuthorizationManager manager = new Jsr250AuthorizationManager(); + AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation); + assertThat(decision.isGranted()).isTrue(); + } + + @Test + public void checkDenyAllWhenMethodsFromInheritThenApplies() throws Exception { + MockMethodInvocation methodInvocation = new MockMethodInvocation(new DenyAllClass(), DenyAllClass.class, + "securedUser"); + Jsr250AuthorizationManager manager = new Jsr250AuthorizationManager(); + AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation); + assertThat(decision.isGranted()).isFalse(); + } + + @RolesAllowed("USER") + public static class RolesAllowedClass extends ParentClass { + + } + + @PermitAll + public static class PermitAllClass extends ParentClass { + + } + + @DenyAll + public static class DenyAllClass extends ParentClass { + + } + + public static class ParentClass { + + public void securedUser() { + + } + + } + public static class TestClass implements InterfaceAnnotationsOne, InterfaceAnnotationsTwo { public void doSomething() { diff --git a/core/src/test/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManagerTests.java b/core/src/test/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManagerTests.java index 37383b40d57..8d0cbbf61aa 100644 --- a/core/src/test/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManagerTests.java +++ b/core/src/test/java/org/springframework/security/authorization/method/PostAuthorizeAuthorizationManagerTests.java @@ -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. @@ -167,6 +167,29 @@ public void checkInheritedAnnotationsWhenConflictingThenAnnotationConfigurationE .isThrownBy(() -> manager.check(authentication, result)); } + @Test + public void checkRequiresUserWhenMethodsFromInheritThenApplies() throws Exception { + MockMethodInvocation methodInvocation = new MockMethodInvocation(new PostAuthorizeClass(), + PostAuthorizeClass.class, "securedUser"); + MethodInvocationResult result = new MethodInvocationResult(methodInvocation, null); + PostAuthorizeAuthorizationManager manager = new PostAuthorizeAuthorizationManager(); + AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, result); + assertThat(decision.isGranted()).isTrue(); + } + + @PostAuthorize("hasRole('USER')") + public static class PostAuthorizeClass extends ParentClass { + + } + + public static class ParentClass { + + public void securedUser() { + + } + + } + public static class TestClass implements InterfaceAnnotationsOne, InterfaceAnnotationsTwo { public void doSomething() { diff --git a/core/src/test/java/org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptorTests.java b/core/src/test/java/org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptorTests.java index 00f2aed42dd..48eec006186 100644 --- a/core/src/test/java/org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptorTests.java +++ b/core/src/test/java/org/springframework/security/authorization/method/PostFilterAuthorizationMethodInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 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. @@ -170,6 +170,34 @@ public Object proceed() { SecurityContextHolder.setContextHolderStrategy(saved); } + @Test + public void checkPostFilterWhenMethodsFromInheritThenApplies() throws Throwable { + String[] array = { "john", "bob" }; + MockMethodInvocation methodInvocation = new MockMethodInvocation(new PostFilterClass(), PostFilterClass.class, + "inheritMethod", new Class[] { String[].class }, new Object[] { array }) { + @Override + public Object proceed() { + return array; + } + }; + PostFilterAuthorizationMethodInterceptor advice = new PostFilterAuthorizationMethodInterceptor(); + Object result = advice.invoke(methodInvocation); + assertThat(result).asInstanceOf(InstanceOfAssertFactories.array(String[].class)).containsOnly("john"); + } + + @PostFilter("filterObject == 'john'") + public static class PostFilterClass extends ParentClass { + + } + + public static class ParentClass { + + public String[] inheritMethod(String[] array) { + return array; + } + + } + @PostFilter("filterObject == 'john'") public static class TestClass implements InterfaceAnnotationsOne, InterfaceAnnotationsTwo { diff --git a/core/src/test/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManagerTests.java b/core/src/test/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManagerTests.java index cb43868dbf0..6b8153ba618 100644 --- a/core/src/test/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManagerTests.java +++ b/core/src/test/java/org/springframework/security/authorization/method/PreAuthorizeAuthorizationManagerTests.java @@ -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. @@ -147,6 +147,28 @@ public void checkTargetClassAwareWhenInterfaceLevelAnnotationsThenApplies() thro assertThat(decision.isGranted()).isTrue(); } + @Test + public void checkRequiresUserWhenMethodsFromInheritThenApplies() throws Exception { + MockMethodInvocation methodInvocation = new MockMethodInvocation(new PreAuthorizeClass(), + PreAuthorizeClass.class, "securedUser"); + PreAuthorizeAuthorizationManager manager = new PreAuthorizeAuthorizationManager(); + AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation); + assertThat(decision.isGranted()).isTrue(); + } + + @PreAuthorize("hasRole('USER')") + public static class PreAuthorizeClass extends ParentClass { + + } + + public static class ParentClass { + + public void securedUser() { + + } + + } + public static class TestClass implements InterfaceAnnotationsOne, InterfaceAnnotationsTwo { public void doSomething() { diff --git a/core/src/test/java/org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptorTests.java b/core/src/test/java/org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptorTests.java index 4f1d56fb146..30d40a369fe 100644 --- a/core/src/test/java/org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptorTests.java +++ b/core/src/test/java/org/springframework/security/authorization/method/PreFilterAuthorizationMethodInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 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. @@ -224,6 +224,32 @@ public void preFilterWhenStaticSecurityContextHolderStrategyAfterConstructorThen SecurityContextHolder.setContextHolderStrategy(saved); } + @Test + public void checkPreFilterWhenMethodsFromInheritThenApplies() throws Throwable { + List list = new ArrayList<>(); + list.add("john"); + list.add("bob"); + MockMethodInvocation invocation = new MockMethodInvocation(new PreFilterClass(), PreFilterClass.class, + "inheritMethod", new Class[] { List.class }, new Object[] { list }); + PreFilterAuthorizationMethodInterceptor advice = new PreFilterAuthorizationMethodInterceptor(); + advice.invoke(invocation); + assertThat(list).hasSize(1); + assertThat(list.get(0)).isEqualTo("john"); + } + + @PreFilter("filterObject == 'john'") + public static class PreFilterClass extends ParentClass { + + } + + public static class ParentClass { + + public void inheritMethod(List list) { + + } + + } + @PreFilter("filterObject == 'john'") public static class TestClass implements InterfaceAnnotationsOne, InterfaceAnnotationsTwo { diff --git a/core/src/test/java/org/springframework/security/authorization/method/SecuredAuthorizationManagerTests.java b/core/src/test/java/org/springframework/security/authorization/method/SecuredAuthorizationManagerTests.java index 5d8651df9e8..5567ad7ae64 100644 --- a/core/src/test/java/org/springframework/security/authorization/method/SecuredAuthorizationManagerTests.java +++ b/core/src/test/java/org/springframework/security/authorization/method/SecuredAuthorizationManagerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 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. @@ -167,6 +167,28 @@ public void checkTargetClassAwareWhenInterfaceLevelAnnotationsThenApplies() thro assertThat(decision.isGranted()).isTrue(); } + @Test + public void checkRequiresUserWhenMethodsFromInheritThenApplies() throws Exception { + MockMethodInvocation methodInvocation = new MockMethodInvocation(new SecuredSonClass(), SecuredSonClass.class, + "securedUser"); + SecuredAuthorizationManager manager = new SecuredAuthorizationManager(); + AuthorizationDecision decision = manager.check(TestAuthentication::authenticatedUser, methodInvocation); + assertThat(decision.isGranted()).isTrue(); + } + + @Secured("ROLE_USER") + public static class SecuredSonClass extends ParentClass { + + } + + public static class ParentClass { + + public void securedUser() { + + } + + } + public static class TestClass implements InterfaceAnnotationsOne, InterfaceAnnotationsTwo { public void doSomething() {