diff --git a/core/src/main/java/org/springframework/security/authorization/method/AuthorizationAnnotationUtils.java b/core/src/main/java/org/springframework/security/authorization/method/AuthorizationAnnotationUtils.java index 87d425f2f4..fa883a2089 100644 --- a/core/src/main/java/org/springframework/security/authorization/method/AuthorizationAnnotationUtils.java +++ b/core/src/main/java/org/springframework/security/authorization/method/AuthorizationAnnotationUtils.java @@ -95,17 +95,28 @@ final class AuthorizationAnnotationUtils { private static boolean hasDuplicate(MergedAnnotations mergedAnnotations, Class annotationType) { - boolean alreadyFound = false; + MergedAnnotation alreadyFound = null; for (MergedAnnotation mergedAnnotation : mergedAnnotations) { if (isSynthetic(mergedAnnotation.getSource())) { continue; } - if (mergedAnnotation.getType() == annotationType) { - if (alreadyFound) { - return true; - } - alreadyFound = true; + if (mergedAnnotation.getType() != annotationType) { + continue; + } + + if (alreadyFound == null) { + alreadyFound = mergedAnnotation; + continue; + } + + // https://github.com/spring-projects/spring-framework/issues/31803 + if (!mergedAnnotation.getSource().equals(alreadyFound.getSource())) { + return true; + } + + if (mergedAnnotation.getRoot().getType() != alreadyFound.getRoot().getType()) { + return true; } } return false; diff --git a/core/src/test/java/org/springframework/security/authorization/method/AuthorizationAnnotationUtilsTests.java b/core/src/test/java/org/springframework/security/authorization/method/AuthorizationAnnotationUtilsTests.java index 3e9ce0d810..8c7cfc3ec8 100644 --- a/core/src/test/java/org/springframework/security/authorization/method/AuthorizationAnnotationUtilsTests.java +++ b/core/src/test/java/org/springframework/security/authorization/method/AuthorizationAnnotationUtilsTests.java @@ -41,6 +41,13 @@ class AuthorizationAnnotationUtilsTests { .isThrownBy(() -> AuthorizationAnnotationUtils.findUniqueAnnotation(method, PreAuthorize.class)); } + @Test // gh-13625 + void annotationsFromSuperSuperInterfaceShouldNotTriggerAnnotationConfigurationException() throws Exception { + Method method = HelloImpl.class.getMethod("sayHello"); + assertThatNoException() + .isThrownBy(() -> AuthorizationAnnotationUtils.findUniqueAnnotation(method, PreAuthorize.class)); + } + private interface BaseRepository { Iterable findAll(); @@ -55,4 +62,24 @@ class AuthorizationAnnotationUtilsTests { } + private interface Hello { + + @PreAuthorize("hasRole('someRole')") + String sayHello(); + + } + + private interface SayHello extends Hello { + + } + + private static class HelloImpl implements SayHello { + + @Override + public String sayHello() { + return "hello"; + } + + } + }