17
17
package org .springframework .security .messaging .context ;
18
18
19
19
import java .lang .annotation .Annotation ;
20
- import java .lang .reflect .AnnotatedElement ;
21
- import java .util .HashMap ;
22
20
import java .util .Map ;
23
21
import java .util .concurrent .ConcurrentHashMap ;
24
- import java .util .function .Function ;
25
22
26
23
import org .springframework .core .MethodParameter ;
27
- import org .springframework .core .annotation .MergedAnnotation ;
28
- import org .springframework .core .annotation .MergedAnnotations ;
29
- import org .springframework .core .annotation .RepeatableContainers ;
30
- import org .springframework .core .convert .support .DefaultConversionService ;
31
24
import org .springframework .expression .Expression ;
32
25
import org .springframework .expression .ExpressionParser ;
33
26
import org .springframework .expression .spel .standard .SpelExpressionParser ;
34
27
import org .springframework .expression .spel .support .StandardEvaluationContext ;
35
- import org .springframework .lang .NonNull ;
36
28
import org .springframework .messaging .Message ;
37
29
import org .springframework .messaging .handler .invocation .HandlerMethodArgumentResolver ;
38
- import org .springframework .security .authorization .method .AuthenticationPrincipalTemplateDefaults ;
39
30
import org .springframework .security .core .Authentication ;
31
+ import org .springframework .security .core .annotation .AnnotationSynthesizer ;
32
+ import org .springframework .security .core .annotation .AnnotationSynthesizers ;
33
+ import org .springframework .security .core .annotation .AnnotationTemplateExpressionDefaults ;
40
34
import org .springframework .security .core .annotation .AuthenticationPrincipal ;
41
35
import org .springframework .security .core .context .SecurityContextHolder ;
42
36
import org .springframework .security .core .context .SecurityContextHolderStrategy ;
43
37
import org .springframework .stereotype .Controller ;
44
38
import org .springframework .util .Assert ;
45
39
import org .springframework .util .ClassUtils ;
46
- import org .springframework .util .PropertyPlaceholderHelper ;
47
40
import org .springframework .util .StringUtils ;
48
41
49
42
/**
@@ -106,11 +99,12 @@ public final class AuthenticationPrincipalArgumentResolver implements HandlerMet
106
99
107
100
private ExpressionParser parser = new SpelExpressionParser ();
108
101
109
- private AuthenticationPrincipalTemplateDefaults principalTemplateDefaults = new AuthenticationPrincipalTemplateDefaults ();
102
+ private AnnotationSynthesizer <AuthenticationPrincipal > synthesizer = AnnotationSynthesizers
103
+ .requireUnique (AuthenticationPrincipal .class );
110
104
111
105
@ Override
112
106
public boolean supportsParameter (MethodParameter parameter ) {
113
- return findMethodAnnotation (AuthenticationPrincipal . class , parameter ) != null ;
107
+ return findMethodAnnotation (parameter ) != null ;
114
108
}
115
109
116
110
@ Override
@@ -120,7 +114,7 @@ public Object resolveArgument(MethodParameter parameter, Message<?> message) {
120
114
return null ;
121
115
}
122
116
Object principal = authentication .getPrincipal ();
123
- AuthenticationPrincipal authPrincipal = findMethodAnnotation (AuthenticationPrincipal . class , parameter );
117
+ AuthenticationPrincipal authPrincipal = findMethodAnnotation (parameter );
124
118
String expressionToParse = authPrincipal .expression ();
125
119
if (StringUtils .hasLength (expressionToParse )) {
126
120
StandardEvaluationContext context = new StandardEvaluationContext ();
@@ -154,69 +148,24 @@ public void setSecurityContextHolderStrategy(SecurityContextHolderStrategy secur
154
148
* <p>
155
149
* By default, this value is <code>null</code>, which indicates that templates should
156
150
* not be resolved.
157
- * @param principalTemplateDefaults - whether to resolve AuthenticationPrincipal
158
- * templates parameters
151
+ * @param templateDefaults - whether to resolve AuthenticationPrincipal templates
152
+ * parameters
159
153
* @since 6.4
160
154
*/
161
- public void setTemplateDefaults (@ NonNull AuthenticationPrincipalTemplateDefaults principalTemplateDefaults ) {
162
- Assert .notNull (principalTemplateDefaults , "principalTemplateDefaults cannot be null" );
163
- this .principalTemplateDefaults = principalTemplateDefaults ;
155
+ public void setTemplateDefaults (AnnotationTemplateExpressionDefaults templateDefaults ) {
156
+ this .synthesizer = AnnotationSynthesizers .requireUnique (AuthenticationPrincipal .class , templateDefaults );
164
157
}
165
158
166
159
/**
167
160
* Obtains the specified {@link Annotation} on the specified {@link MethodParameter}.
168
- * @param annotationClass the class of the {@link Annotation} to find on the
169
161
* {@link MethodParameter}
170
162
* @param parameter the {@link MethodParameter} to search for an {@link Annotation}
171
163
* @return the {@link Annotation} that was found or null.
172
164
*/
173
165
@ SuppressWarnings ("unchecked" )
174
- private <T extends Annotation > T findMethodAnnotation (Class < T > annotationClass , MethodParameter parameter ) {
166
+ private <T extends Annotation > T findMethodAnnotation (MethodParameter parameter ) {
175
167
return (T ) this .cachedAttributes .computeIfAbsent (parameter ,
176
- (methodParameter ) -> findMethodAnnotation (annotationClass , methodParameter ,
177
- this .principalTemplateDefaults ));
178
- }
179
-
180
- private static <T extends Annotation > T findMethodAnnotation (Class <T > annotationClass , MethodParameter parameter ,
181
- AuthenticationPrincipalTemplateDefaults principalTemplateDefaults ) {
182
- T annotation = parameter .getParameterAnnotation (annotationClass );
183
- if (annotation != null ) {
184
- return annotation ;
185
- }
186
- return MergedAnnotations
187
- .from (parameter .getParameter (), MergedAnnotations .SearchStrategy .TYPE_HIERARCHY ,
188
- RepeatableContainers .none ())
189
- .stream (annotationClass )
190
- .map (mapper (annotationClass , principalTemplateDefaults .isIgnoreUnknown (), "expression" ))
191
- .findFirst ()
192
- .orElse (null );
193
- }
194
-
195
- private static <T extends Annotation > Function <MergedAnnotation <T >, T > mapper (Class <T > annotationClass ,
196
- boolean ignoreUnresolvablePlaceholders , String ... attrs ) {
197
- return (mergedAnnotation ) -> {
198
- MergedAnnotation <?> metaSource = mergedAnnotation .getMetaSource ();
199
- if (metaSource == null ) {
200
- return mergedAnnotation .synthesize ();
201
- }
202
- PropertyPlaceholderHelper helper = new PropertyPlaceholderHelper ("{" , "}" , null , null ,
203
- ignoreUnresolvablePlaceholders );
204
- Map <String , String > stringProperties = new HashMap <>();
205
- for (Map .Entry <String , Object > property : metaSource .asMap ().entrySet ()) {
206
- String key = property .getKey ();
207
- Object value = property .getValue ();
208
- String asString = (value instanceof String ) ? (String ) value
209
- : DefaultConversionService .getSharedInstance ().convert (value , String .class );
210
- stringProperties .put (key , asString );
211
- }
212
- Map <String , Object > attrMap = mergedAnnotation .asMap ();
213
- Map <String , Object > properties = new HashMap <>(attrMap );
214
- for (String attr : attrs ) {
215
- properties .put (attr , helper .replacePlaceholders ((String ) attrMap .get (attr ), stringProperties ::get ));
216
- }
217
- return MergedAnnotation .of ((AnnotatedElement ) mergedAnnotation .getSource (), annotationClass , properties )
218
- .synthesize ();
219
- };
168
+ (methodParameter ) -> this .synthesizer .synthesize (methodParameter .getParameter ()));
220
169
}
221
170
222
171
}
0 commit comments