Skip to content

Commit c2ff553

Browse files
committed
Fixed the issue where the annotation parameter scan skipped first-level conflicts.
1 parent 95ec49a commit c2ff553

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

Diff for: core/src/main/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScanner.java

+11-10
Original file line numberDiff line numberDiff line change
@@ -146,25 +146,26 @@ private List<MergedAnnotation<A>> findParameterAnnotations(Parameter current) {
146146
}
147147
Executable executable = current.getDeclaringExecutable();
148148
if (executable instanceof Method method) {
149-
Class<?> clazz = method.getDeclaringClass();
150-
Set<Class<?>> visited = new HashSet<>();
151-
while (clazz != null && clazz != Object.class) {
152-
directAnnotations = findClosestParameterAnnotations(method, clazz, current, visited);
153-
if (!directAnnotations.isEmpty()) {
154-
return directAnnotations;
155-
}
156-
clazz = clazz.getSuperclass();
149+
directAnnotations = findClosestParameterAnnotations(method, method.getDeclaringClass(), current,
150+
new HashSet<>());
151+
if (!directAnnotations.isEmpty()) {
152+
return directAnnotations;
157153
}
158154
}
159155
return Collections.emptyList();
160156
}
161157

162158
private List<MergedAnnotation<A>> findClosestParameterAnnotations(Method method, Class<?> clazz, Parameter current,
163159
Set<Class<?>> visited) {
164-
if (!visited.add(clazz)) {
160+
if (clazz == null || clazz == Object.class || !visited.add(clazz)) {
165161
return Collections.emptyList();
166162
}
167-
List<MergedAnnotation<A>> annotations = new ArrayList<>(findDirectParameterAnnotations(method, clazz, current));
163+
List<MergedAnnotation<A>> directAnnotations = findDirectParameterAnnotations(method, clazz, current);
164+
if (!directAnnotations.isEmpty()) {
165+
return directAnnotations;
166+
}
167+
List<MergedAnnotation<A>> annotations = new ArrayList<>(
168+
findClosestParameterAnnotations(method, clazz.getSuperclass(), current, visited));
168169
for (Class<?> ifc : clazz.getInterfaces()) {
169170
annotations.addAll(findClosestParameterAnnotations(method, ifc, current, visited));
170171
}

Diff for: core/src/test/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScannerTests.java

+23
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,13 @@ void scanParameterAnnotationWhenInterfaceNoAnnotationsThenException() throws Exc
295295
.isThrownBy(() -> this.parameterScanner.scan(parameter));
296296
}
297297

298+
@Test
299+
void scanParameterAnnotationWhenPresentInParentAndInterfaceThenException() throws Exception {
300+
Parameter parameter = DefaultUserService.class.getDeclaredMethod("batch", String[].class).getParameters()[0];
301+
assertThatExceptionOfType(AnnotationConfigurationException.class)
302+
.isThrownBy(() -> this.parameterScanner.scan(parameter));
303+
}
304+
298305
interface UserService {
299306

300307
void add(@CustomParameterAnnotation("one") String user);
@@ -321,6 +328,8 @@ interface ThirdPartyUserService {
321328

322329
interface RemoteUserService extends ThirdPartyUserService {
323330

331+
void batch(@CustomParameterAnnotation("six") String... user);
332+
324333
}
325334

326335
static class UserServiceImpl implements UserService, OtherUserService, RemoteUserService {
@@ -345,6 +354,20 @@ public void delete(String user) {
345354

346355
}
347356

357+
@Override
358+
public void batch(@CustomParameterAnnotation("seven") String... user) {
359+
360+
}
361+
362+
}
363+
364+
static class DefaultUserService extends UserServiceImpl implements RemoteUserService {
365+
366+
@Override
367+
public void batch(String... user) {
368+
369+
}
370+
348371
}
349372

350373
@Target({ ElementType.PARAMETER })

0 commit comments

Comments
 (0)