From f565b23b517039d12ec8b4b8f0a0bc2b01a9c91e Mon Sep 17 00:00:00 2001 From: DingHao Date: Mon, 9 Dec 2024 10:52:51 +0800 Subject: [PATCH] Restore Method Parameter Inheritance Support Closes gh-16177 --- ...thenticationPrincipalArgumentResolver.java | 28 ++++++++++++++++--- ...thenticationPrincipalArgumentResolver.java | 28 ++++++++++++++++--- ...urrentSecurityContextArgumentResolver.java | 28 ++++++++++++++++--- ...urrentSecurityContextArgumentResolver.java | 28 ++++++++++++++++--- ...thenticationPrincipalArgumentResolver.java | 28 ++++++++++++++++--- ...urrentSecurityContextArgumentResolver.java | 28 ++++++++++++++++--- 6 files changed, 144 insertions(+), 24 deletions(-) diff --git a/messaging/src/main/java/org/springframework/security/messaging/context/AuthenticationPrincipalArgumentResolver.java b/messaging/src/main/java/org/springframework/security/messaging/context/AuthenticationPrincipalArgumentResolver.java index f3f6f80fbe..5cee1b49ac 100644 --- a/messaging/src/main/java/org/springframework/security/messaging/context/AuthenticationPrincipalArgumentResolver.java +++ b/messaging/src/main/java/org/springframework/security/messaging/context/AuthenticationPrincipalArgumentResolver.java @@ -19,6 +19,8 @@ package org.springframework.security.messaging.context; import java.lang.annotation.Annotation; import org.springframework.core.MethodParameter; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.MergedAnnotations; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.spel.standard.SpelExpressionParser; @@ -95,8 +97,12 @@ public final class AuthenticationPrincipalArgumentResolver implements HandlerMet private ExpressionParser parser = new SpelExpressionParser(); + private final Class annotationType = AuthenticationPrincipal.class; + private SecurityAnnotationScanner scanner = SecurityAnnotationScanners - .requireUnique(AuthenticationPrincipal.class); + .requireUnique(this.annotationType); + + private boolean useAnnotationTemplate = false; @Override public boolean supportsParameter(MethodParameter parameter) { @@ -149,6 +155,7 @@ public final class AuthenticationPrincipalArgumentResolver implements HandlerMet * @since 6.4 */ public void setTemplateDefaults(AnnotationTemplateExpressionDefaults templateDefaults) { + this.useAnnotationTemplate = templateDefaults != null; this.scanner = SecurityAnnotationScanners.requireUnique(AuthenticationPrincipal.class, templateDefaults); } @@ -158,9 +165,22 @@ public final class AuthenticationPrincipalArgumentResolver implements HandlerMet * @param parameter the {@link MethodParameter} to search for an {@link Annotation} * @return the {@link Annotation} that was found or null. */ - @SuppressWarnings("unchecked") - private T findMethodAnnotation(MethodParameter parameter) { - return (T) this.scanner.scan(parameter.getParameter()); + private AuthenticationPrincipal findMethodAnnotation(MethodParameter parameter) { + if (this.useAnnotationTemplate) { + return this.scanner.scan(parameter.getParameter()); + } + AuthenticationPrincipal annotation = parameter.getParameterAnnotation(this.annotationType); + if (annotation != null) { + return annotation; + } + Annotation[] annotationsToSearch = parameter.getParameterAnnotations(); + for (Annotation toSearch : annotationsToSearch) { + annotation = AnnotationUtils.findAnnotation(toSearch.annotationType(), this.annotationType); + if (annotation != null) { + return MergedAnnotations.from(toSearch).get(this.annotationType).synthesize(); + } + } + return null; } } diff --git a/messaging/src/main/java/org/springframework/security/messaging/handler/invocation/reactive/AuthenticationPrincipalArgumentResolver.java b/messaging/src/main/java/org/springframework/security/messaging/handler/invocation/reactive/AuthenticationPrincipalArgumentResolver.java index bb0590a9ca..ef8a93a4d4 100644 --- a/messaging/src/main/java/org/springframework/security/messaging/handler/invocation/reactive/AuthenticationPrincipalArgumentResolver.java +++ b/messaging/src/main/java/org/springframework/security/messaging/handler/invocation/reactive/AuthenticationPrincipalArgumentResolver.java @@ -25,6 +25,8 @@ import org.springframework.core.MethodParameter; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; import org.springframework.core.ResolvableType; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.MergedAnnotations; import org.springframework.expression.BeanResolver; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; @@ -99,8 +101,12 @@ public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArg private ExpressionParser parser = new SpelExpressionParser(); + private final Class annotationType = AuthenticationPrincipal.class; + private SecurityAnnotationScanner scanner = SecurityAnnotationScanners - .requireUnique(AuthenticationPrincipal.class); + .requireUnique(this.annotationType); + + private boolean useAnnotationTemplate = false; private BeanResolver beanResolver; @@ -190,6 +196,7 @@ public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArg * @since 6.4 */ public void setTemplateDefaults(AnnotationTemplateExpressionDefaults templateDefaults) { + this.useAnnotationTemplate = templateDefaults != null; this.scanner = SecurityAnnotationScanners.requireUnique(AuthenticationPrincipal.class, templateDefaults); } @@ -199,9 +206,22 @@ public class AuthenticationPrincipalArgumentResolver implements HandlerMethodArg * @param parameter the {@link MethodParameter} to search for an {@link Annotation} * @return the {@link Annotation} that was found or null. */ - @SuppressWarnings("unchecked") - private T findMethodAnnotation(MethodParameter parameter) { - return (T) this.scanner.scan(parameter.getParameter()); + private AuthenticationPrincipal findMethodAnnotation(MethodParameter parameter) { + if (this.useAnnotationTemplate) { + return this.scanner.scan(parameter.getParameter()); + } + AuthenticationPrincipal annotation = parameter.getParameterAnnotation(this.annotationType); + if (annotation != null) { + return annotation; + } + Annotation[] annotationsToSearch = parameter.getParameterAnnotations(); + for (Annotation toSearch : annotationsToSearch) { + annotation = AnnotationUtils.findAnnotation(toSearch.annotationType(), this.annotationType); + if (annotation != null) { + return MergedAnnotations.from(toSearch).get(this.annotationType).synthesize(); + } + } + return null; } } diff --git a/messaging/src/main/java/org/springframework/security/messaging/handler/invocation/reactive/CurrentSecurityContextArgumentResolver.java b/messaging/src/main/java/org/springframework/security/messaging/handler/invocation/reactive/CurrentSecurityContextArgumentResolver.java index 62f25fefbb..f2d7aafa4d 100644 --- a/messaging/src/main/java/org/springframework/security/messaging/handler/invocation/reactive/CurrentSecurityContextArgumentResolver.java +++ b/messaging/src/main/java/org/springframework/security/messaging/handler/invocation/reactive/CurrentSecurityContextArgumentResolver.java @@ -25,6 +25,8 @@ import org.springframework.core.MethodParameter; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; import org.springframework.core.ResolvableType; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.MergedAnnotations; import org.springframework.expression.BeanResolver; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; @@ -97,8 +99,12 @@ public class CurrentSecurityContextArgumentResolver implements HandlerMethodArgu private ExpressionParser parser = new SpelExpressionParser(); + private final Class annotationType = CurrentSecurityContext.class; + private SecurityAnnotationScanner scanner = SecurityAnnotationScanners - .requireUnique(CurrentSecurityContext.class); + .requireUnique(this.annotationType); + + private boolean useAnnotationTemplate = false; private BeanResolver beanResolver; @@ -208,6 +214,7 @@ public class CurrentSecurityContextArgumentResolver implements HandlerMethodArgu * @since 6.4 */ public void setTemplateDefaults(AnnotationTemplateExpressionDefaults templateDefaults) { + this.useAnnotationTemplate = templateDefaults != null; this.scanner = SecurityAnnotationScanners.requireUnique(CurrentSecurityContext.class, templateDefaults); } @@ -216,9 +223,22 @@ public class CurrentSecurityContextArgumentResolver implements HandlerMethodArgu * @param parameter the {@link MethodParameter} to search for an {@link Annotation} * @return the {@link Annotation} that was found or null. */ - @SuppressWarnings("unchecked") - private T findMethodAnnotation(MethodParameter parameter) { - return (T) this.scanner.scan(parameter.getParameter()); + private CurrentSecurityContext findMethodAnnotation(MethodParameter parameter) { + if (this.useAnnotationTemplate) { + return this.scanner.scan(parameter.getParameter()); + } + CurrentSecurityContext annotation = parameter.getParameterAnnotation(this.annotationType); + if (annotation != null) { + return annotation; + } + Annotation[] annotationsToSearch = parameter.getParameterAnnotations(); + for (Annotation toSearch : annotationsToSearch) { + annotation = AnnotationUtils.findAnnotation(toSearch.annotationType(), this.annotationType); + if (annotation != null) { + return MergedAnnotations.from(toSearch).get(this.annotationType).synthesize(); + } + } + return null; } } diff --git a/web/src/main/java/org/springframework/security/web/method/annotation/CurrentSecurityContextArgumentResolver.java b/web/src/main/java/org/springframework/security/web/method/annotation/CurrentSecurityContextArgumentResolver.java index 600060e78e..74d68e5d09 100644 --- a/web/src/main/java/org/springframework/security/web/method/annotation/CurrentSecurityContextArgumentResolver.java +++ b/web/src/main/java/org/springframework/security/web/method/annotation/CurrentSecurityContextArgumentResolver.java @@ -19,6 +19,8 @@ package org.springframework.security.web.method.annotation; import java.lang.annotation.Annotation; import org.springframework.core.MethodParameter; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.MergedAnnotations; import org.springframework.expression.BeanResolver; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; @@ -84,8 +86,12 @@ public final class CurrentSecurityContextArgumentResolver implements HandlerMeth private ExpressionParser parser = new SpelExpressionParser(); + private final Class annotationType = CurrentSecurityContext.class; + private SecurityAnnotationScanner scanner = SecurityAnnotationScanners - .requireUnique(CurrentSecurityContext.class); + .requireUnique(this.annotationType); + + private boolean useAnnotationTemplate = false; private BeanResolver beanResolver; @@ -140,6 +146,7 @@ public final class CurrentSecurityContextArgumentResolver implements HandlerMeth * @since 6.4 */ public void setTemplateDefaults(AnnotationTemplateExpressionDefaults templateDefaults) { + this.useAnnotationTemplate = templateDefaults != null; this.scanner = SecurityAnnotationScanners.requireUnique(CurrentSecurityContext.class, templateDefaults); } @@ -171,9 +178,22 @@ public final class CurrentSecurityContextArgumentResolver implements HandlerMeth * @param parameter the {@link MethodParameter} to search for an {@link Annotation} * @return the {@link Annotation} that was found or null. */ - @SuppressWarnings("unchecked") - private T findMethodAnnotation(MethodParameter parameter) { - return (T) this.scanner.scan(parameter.getParameter()); + private CurrentSecurityContext findMethodAnnotation(MethodParameter parameter) { + if (this.useAnnotationTemplate) { + return this.scanner.scan(parameter.getParameter()); + } + CurrentSecurityContext annotation = parameter.getParameterAnnotation(this.annotationType); + if (annotation != null) { + return annotation; + } + Annotation[] annotationsToSearch = parameter.getParameterAnnotations(); + for (Annotation toSearch : annotationsToSearch) { + annotation = AnnotationUtils.findAnnotation(toSearch.annotationType(), this.annotationType); + if (annotation != null) { + return MergedAnnotations.from(toSearch).get(this.annotationType).synthesize(); + } + } + return null; } } diff --git a/web/src/main/java/org/springframework/security/web/reactive/result/method/annotation/AuthenticationPrincipalArgumentResolver.java b/web/src/main/java/org/springframework/security/web/reactive/result/method/annotation/AuthenticationPrincipalArgumentResolver.java index aae0b46be2..31faf325a6 100644 --- a/web/src/main/java/org/springframework/security/web/reactive/result/method/annotation/AuthenticationPrincipalArgumentResolver.java +++ b/web/src/main/java/org/springframework/security/web/reactive/result/method/annotation/AuthenticationPrincipalArgumentResolver.java @@ -25,6 +25,8 @@ import org.springframework.core.MethodParameter; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; import org.springframework.core.ResolvableType; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.MergedAnnotations; import org.springframework.expression.BeanResolver; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; @@ -53,8 +55,12 @@ public class AuthenticationPrincipalArgumentResolver extends HandlerMethodArgume private ExpressionParser parser = new SpelExpressionParser(); + private final Class annotationType = AuthenticationPrincipal.class; + private SecurityAnnotationScanner scanner = SecurityAnnotationScanners - .requireUnique(AuthenticationPrincipal.class); + .requireUnique(this.annotationType); + + private boolean useAnnotationTemplate = false; private BeanResolver beanResolver; @@ -134,6 +140,7 @@ public class AuthenticationPrincipalArgumentResolver extends HandlerMethodArgume * @since 6.4 */ public void setTemplateDefaults(AnnotationTemplateExpressionDefaults templateDefaults) { + this.useAnnotationTemplate = templateDefaults != null; this.scanner = SecurityAnnotationScanners.requireUnique(AuthenticationPrincipal.class, templateDefaults); } @@ -143,9 +150,22 @@ public class AuthenticationPrincipalArgumentResolver extends HandlerMethodArgume * @param parameter the {@link MethodParameter} to search for an {@link Annotation} * @return the {@link Annotation} that was found or null. */ - @SuppressWarnings("unchecked") - private T findMethodAnnotation(MethodParameter parameter) { - return (T) this.scanner.scan(parameter.getParameter()); + private AuthenticationPrincipal findMethodAnnotation(MethodParameter parameter) { + if (this.useAnnotationTemplate) { + return this.scanner.scan(parameter.getParameter()); + } + AuthenticationPrincipal annotation = parameter.getParameterAnnotation(this.annotationType); + if (annotation != null) { + return annotation; + } + Annotation[] annotationsToSearch = parameter.getParameterAnnotations(); + for (Annotation toSearch : annotationsToSearch) { + annotation = AnnotationUtils.findAnnotation(toSearch.annotationType(), this.annotationType); + if (annotation != null) { + return MergedAnnotations.from(toSearch).get(this.annotationType).synthesize(); + } + } + return null; } } diff --git a/web/src/main/java/org/springframework/security/web/reactive/result/method/annotation/CurrentSecurityContextArgumentResolver.java b/web/src/main/java/org/springframework/security/web/reactive/result/method/annotation/CurrentSecurityContextArgumentResolver.java index 8fd7c72475..c7107cc150 100644 --- a/web/src/main/java/org/springframework/security/web/reactive/result/method/annotation/CurrentSecurityContextArgumentResolver.java +++ b/web/src/main/java/org/springframework/security/web/reactive/result/method/annotation/CurrentSecurityContextArgumentResolver.java @@ -25,6 +25,8 @@ import org.springframework.core.MethodParameter; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; import org.springframework.core.ResolvableType; +import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.MergedAnnotations; import org.springframework.expression.BeanResolver; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; @@ -53,8 +55,12 @@ public class CurrentSecurityContextArgumentResolver extends HandlerMethodArgumen private ExpressionParser parser = new SpelExpressionParser(); + private final Class annotationType = CurrentSecurityContext.class; + private SecurityAnnotationScanner scanner = SecurityAnnotationScanners - .requireUnique(CurrentSecurityContext.class); + .requireUnique(this.annotationType); + + private boolean useAnnotationTemplate = false; private BeanResolver beanResolver; @@ -81,6 +87,7 @@ public class CurrentSecurityContextArgumentResolver extends HandlerMethodArgumen * @since 6.4 */ public void setTemplateDefaults(AnnotationTemplateExpressionDefaults templateDefaults) { + this.useAnnotationTemplate = templateDefaults != null; this.scanner = SecurityAnnotationScanners.requireUnique(CurrentSecurityContext.class, templateDefaults); } @@ -183,9 +190,22 @@ public class CurrentSecurityContextArgumentResolver extends HandlerMethodArgumen * @param parameter the {@link MethodParameter} to search for an {@link Annotation} * @return the {@link Annotation} that was found or null. */ - @SuppressWarnings("unchecked") - private T findMethodAnnotation(MethodParameter parameter) { - return (T) this.scanner.scan(parameter.getParameter()); + private CurrentSecurityContext findMethodAnnotation(MethodParameter parameter) { + if (this.useAnnotationTemplate) { + return this.scanner.scan(parameter.getParameter()); + } + CurrentSecurityContext annotation = parameter.getParameterAnnotation(this.annotationType); + if (annotation != null) { + return annotation; + } + Annotation[] annotationsToSearch = parameter.getParameterAnnotations(); + for (Annotation toSearch : annotationsToSearch) { + annotation = AnnotationUtils.findAnnotation(toSearch.annotationType(), this.annotationType); + if (annotation != null) { + return MergedAnnotations.from(toSearch).get(this.annotationType).synthesize(); + } + } + return null; } }