Skip to content

Commit 5ae703e

Browse files
kse-musicjzheaux
authored andcommitted
Annotation parameter scan finds first-level conflicts
Closes PR-16312
1 parent 103ccb3 commit 5ae703e

File tree

2 files changed

+34
-10
lines changed

2 files changed

+34
-10
lines changed

core/src/main/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScanner.java

+11-10
Original file line numberDiff line numberDiff line change
@@ -149,25 +149,26 @@ private List<MergedAnnotation<A>> findParameterAnnotations(Parameter current) {
149149
}
150150
Executable executable = current.getDeclaringExecutable();
151151
if (executable instanceof Method method) {
152-
Class<?> clazz = method.getDeclaringClass();
153-
Set<Class<?>> visited = new HashSet<>();
154-
while (clazz != null && clazz != Object.class) {
155-
directAnnotations = findClosestParameterAnnotations(method, clazz, current, visited);
156-
if (!directAnnotations.isEmpty()) {
157-
return directAnnotations;
158-
}
159-
clazz = clazz.getSuperclass();
152+
directAnnotations = findClosestParameterAnnotations(method, method.getDeclaringClass(), current,
153+
new HashSet<>());
154+
if (!directAnnotations.isEmpty()) {
155+
return directAnnotations;
160156
}
161157
}
162158
return Collections.emptyList();
163159
}
164160

165161
private List<MergedAnnotation<A>> findClosestParameterAnnotations(Method method, Class<?> clazz, Parameter current,
166162
Set<Class<?>> visited) {
167-
if (!visited.add(clazz)) {
163+
if (clazz == null || clazz == Object.class || !visited.add(clazz)) {
168164
return Collections.emptyList();
169165
}
170-
List<MergedAnnotation<A>> annotations = new ArrayList<>(findDirectParameterAnnotations(method, clazz, current));
166+
List<MergedAnnotation<A>> directAnnotations = findDirectParameterAnnotations(method, clazz, current);
167+
if (!directAnnotations.isEmpty()) {
168+
return directAnnotations;
169+
}
170+
List<MergedAnnotation<A>> annotations = new ArrayList<>(
171+
findClosestParameterAnnotations(method, clazz.getSuperclass(), current, visited));
171172
for (Class<?> ifc : clazz.getInterfaces()) {
172173
annotations.addAll(findClosestParameterAnnotations(method, ifc, current, visited));
173174
}

core/src/test/java/org/springframework/security/core/annotation/UniqueSecurityAnnotationScannerTests.java

+23
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,13 @@ void scanWhenAnnotationOnParameterizedMethodThenLocates() throws Exception {
319319
assertThat(pre).isNotNull();
320320
}
321321

322+
@Test
323+
void scanParameterAnnotationWhenPresentInParentAndInterfaceThenException() throws Exception {
324+
Parameter parameter = DefaultUserService.class.getDeclaredMethod("batch", String[].class).getParameters()[0];
325+
assertThatExceptionOfType(AnnotationConfigurationException.class)
326+
.isThrownBy(() -> this.parameterScanner.scan(parameter));
327+
}
328+
322329
interface UserService {
323330

324331
void add(@CustomParameterAnnotation("one") String user);
@@ -345,6 +352,8 @@ interface ThirdPartyUserService {
345352

346353
interface RemoteUserService extends ThirdPartyUserService {
347354

355+
void batch(@CustomParameterAnnotation("six") String... user);
356+
348357
}
349358

350359
static class UserServiceImpl implements UserService, OtherUserService, RemoteUserService {
@@ -369,6 +378,20 @@ public void delete(String user) {
369378

370379
}
371380

381+
@Override
382+
public void batch(@CustomParameterAnnotation("seven") String... user) {
383+
384+
}
385+
386+
}
387+
388+
static class DefaultUserService extends UserServiceImpl implements RemoteUserService {
389+
390+
@Override
391+
public void batch(String... user) {
392+
393+
}
394+
372395
}
373396

374397
@Target({ ElementType.PARAMETER })

0 commit comments

Comments
 (0)