Fallback to Object When Determining Overridden Methods

Closes gh-17898
This commit is contained in:
Josh Cummings 2025-09-15 09:16:50 -06:00
parent 9de0aad31b
commit e5694ac7b5
No known key found for this signature in database
GPG Key ID: 869B37A20E876129
2 changed files with 33 additions and 1 deletions

View File

@ -252,7 +252,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;
}

View File

@ -22,6 +22,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;
@ -275,6 +276,14 @@ public class UniqueSecurityAnnotationScannerTests {
assertThat(pre).isNotNull();
}
// 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();
}
@PreAuthorize("one")
private interface AnnotationOnInterface {
@ -637,4 +646,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.
}
}