Explorar o código

Annotation parameter scan finds first-level conflicts

Closes PR-16312
DingHao hai 8 meses
pai
achega
96b9820e19

+ 11 - 10
core/src/main/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScanner.java

@@ -149,14 +149,10 @@ final class UniqueSecurityAnnotationScanner<A extends Annotation> extends Abstra
 		}
 		Executable executable = current.getDeclaringExecutable();
 		if (executable instanceof Method method) {
-			Class<?> clazz = method.getDeclaringClass();
-			Set<Class<?>> visited = new HashSet<>();
-			while (clazz != null && clazz != Object.class) {
-				directAnnotations = findClosestParameterAnnotations(method, clazz, current, visited);
-				if (!directAnnotations.isEmpty()) {
-					return directAnnotations;
-				}
-				clazz = clazz.getSuperclass();
+			directAnnotations = findClosestParameterAnnotations(method, method.getDeclaringClass(), current,
+					new HashSet<>());
+			if (!directAnnotations.isEmpty()) {
+				return directAnnotations;
 			}
 		}
 		return Collections.emptyList();
@@ -164,10 +160,15 @@ final class UniqueSecurityAnnotationScanner<A extends Annotation> extends Abstra
 
 	private List<MergedAnnotation<A>> findClosestParameterAnnotations(Method method, Class<?> clazz, Parameter current,
 			Set<Class<?>> visited) {
-		if (!visited.add(clazz)) {
+		if (clazz == null || clazz == Object.class || !visited.add(clazz)) {
 			return Collections.emptyList();
 		}
-		List<MergedAnnotation<A>> annotations = new ArrayList<>(findDirectParameterAnnotations(method, clazz, current));
+		List<MergedAnnotation<A>> directAnnotations = findDirectParameterAnnotations(method, clazz, current);
+		if (!directAnnotations.isEmpty()) {
+			return directAnnotations;
+		}
+		List<MergedAnnotation<A>> annotations = new ArrayList<>(
+				findClosestParameterAnnotations(method, clazz.getSuperclass(), current, visited));
 		for (Class<?> ifc : clazz.getInterfaces()) {
 			annotations.addAll(findClosestParameterAnnotations(method, ifc, current, visited));
 		}

+ 23 - 0
core/src/test/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScannerTests.java

@@ -319,6 +319,13 @@ public class UniqueSecurityAnnotationScannerTests {
 		assertThat(pre).isNotNull();
 	}
 
+	@Test
+	void scanParameterAnnotationWhenPresentInParentAndInterfaceThenException() throws Exception {
+		Parameter parameter = DefaultUserService.class.getDeclaredMethod("batch", String[].class).getParameters()[0];
+		assertThatExceptionOfType(AnnotationConfigurationException.class)
+			.isThrownBy(() -> this.parameterScanner.scan(parameter));
+	}
+
 	interface UserService {
 
 		void add(@CustomParameterAnnotation("one") String user);
@@ -345,6 +352,8 @@ public class UniqueSecurityAnnotationScannerTests {
 
 	interface RemoteUserService extends ThirdPartyUserService {
 
+		void batch(@CustomParameterAnnotation("six") String... user);
+
 	}
 
 	static class UserServiceImpl implements UserService, OtherUserService, RemoteUserService {
@@ -369,6 +378,20 @@ public class UniqueSecurityAnnotationScannerTests {
 
 		}
 
+		@Override
+		public void batch(@CustomParameterAnnotation("seven") String... user) {
+
+		}
+
+	}
+
+	static class DefaultUserService extends UserServiceImpl implements RemoteUserService {
+
+		@Override
+		public void batch(String... user) {
+
+		}
+
 	}
 
 	@Target({ ElementType.PARAMETER })