Browse Source

Merge branch '6.4.x' into 6.5.x

Josh Cummings 1 week ago
parent
commit
d0f93fa6d8

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

@@ -305,7 +305,7 @@ final class UniqueSecurityAnnotationScanner<A extends Annotation> extends Abstra
 		}
 		for (int i = 0; i < rootParameterTypes.length; i++) {
 			Class<?> resolvedParameterType = ResolvableType.forMethodParameter(candidateMethod, i, sourceDeclaringClass)
-				.resolve();
+				.toClass();
 			if (rootParameterTypes[i] != resolvedParameterType) {
 				return false;
 			}

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

@@ -28,6 +28,7 @@ import org.junit.jupiter.api.Test;
 
 import org.springframework.core.annotation.AnnotationConfigurationException;
 import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.util.ClassUtils;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -326,6 +327,14 @@ public class UniqueSecurityAnnotationScannerTests {
 			.isThrownBy(() -> this.parameterScanner.scan(parameter));
 	}
 
+	// gh-17898
+	@Test
+	void scanWhenAnnotationOnParameterizedUndeclaredMethodAndThenLocates() throws Exception {
+		Method method = ClassUtils.getMethod(GenericInterfaceImpl.class, "processOneAndTwo", Long.class, Object.class);
+		PreAuthorize pre = this.scanner.scan(method, method.getDeclaringClass());
+		assertThat(pre).isNotNull();
+	}
+
 	interface UserService {
 
 		void add(@CustomParameterAnnotation("one") String user);
@@ -764,4 +773,27 @@ public class UniqueSecurityAnnotationScannerTests {
 
 	}
 
+	interface GenericInterface<A, B> {
+
+		@PreAuthorize("hasAuthority('thirtythree')")
+		void processOneAndTwo(A value1, B value2);
+
+	}
+
+	abstract static class GenericAbstractSuperclass<C> implements GenericInterface<Long, C> {
+
+		@Override
+		public void processOneAndTwo(Long value1, C value2) {
+		}
+
+	}
+
+	static class GenericInterfaceImpl extends GenericAbstractSuperclass<String> {
+
+		// The compiler does not require us to declare a concrete
+		// processOneAndTwo(Long, String) method, and we intentionally
+		// do not declare one here.
+
+	}
+
 }