26
26
import org .apache .commons .logging .LogFactory ;
27
27
28
28
import org .springframework .core .log .LogMessage ;
29
- import org .springframework .http .server .PathContainer ;
30
29
import org .springframework .messaging .Message ;
31
30
import org .springframework .messaging .simp .SimpMessageType ;
32
31
import org .springframework .security .authorization .AuthenticatedAuthorizationManager ;
36
35
import org .springframework .security .authorization .SingleResultAuthorizationManager ;
37
36
import org .springframework .security .core .Authentication ;
38
37
import org .springframework .security .messaging .util .matcher .MessageMatcher ;
38
+ import org .springframework .security .messaging .util .matcher .MessageMatcherFactory ;
39
39
import org .springframework .security .messaging .util .matcher .PathPatternMessageMatcher ;
40
40
import org .springframework .security .messaging .util .matcher .SimpDestinationMessageMatcher ;
41
41
import org .springframework .security .messaging .util .matcher .SimpMessageTypeMatcher ;
42
42
import org .springframework .util .AntPathMatcher ;
43
43
import org .springframework .util .Assert ;
44
+ import org .springframework .util .CollectionUtils ;
44
45
import org .springframework .util .PathMatcher ;
45
46
import org .springframework .util .function .SingletonSupplier ;
46
- import org .springframework .web .util .pattern .PathPatternParser ;
47
47
48
48
public final class MessageMatcherDelegatingAuthorizationManager implements AuthorizationManager <Message <?>> {
49
49
@@ -89,13 +89,16 @@ public AuthorizationDecision check(Supplier<Authentication> authentication, Mess
89
89
}
90
90
91
91
private MessageAuthorizationContext <?> authorizationContext (MessageMatcher <?> matcher , Message <?> message ) {
92
- if (!matcher .matches ((Message ) message )) {
92
+ MessageMatcher .MatchResult matchResult = matcher .matcher ((Message ) message );
93
+ if (!matchResult .isMatch ()) {
93
94
return null ;
94
95
}
95
- if (matcher instanceof Builder .LazySimpDestinationMessageMatcher pathMatcher ) {
96
- return new MessageAuthorizationContext <>(message , pathMatcher .extractPathVariables (message ));
96
+
97
+ if (!CollectionUtils .isEmpty (matchResult .getVariables ())) {
98
+ return new MessageAuthorizationContext <>(message , matchResult .getVariables ());
97
99
}
98
- if (matcher instanceof Builder .LazySimpDestinationPatternMessageMatcher pathMatcher ) {
100
+
101
+ if (matcher instanceof Builder .LazySimpDestinationMessageMatcher pathMatcher ) {
99
102
return new MessageAuthorizationContext <>(message , pathMatcher .extractPathVariables (message ));
100
103
}
101
104
return new MessageAuthorizationContext <>(message );
@@ -119,8 +122,6 @@ public static final class Builder {
119
122
@ Deprecated
120
123
private Supplier <PathMatcher > pathMatcher = AntPathMatcher ::new ;
121
124
122
- private boolean useHttpPathSeparator = true ;
123
-
124
125
public Builder () {
125
126
}
126
127
@@ -157,159 +158,70 @@ public Builder.Constraint simpTypeMatchers(SimpMessageType... typesToMatch) {
157
158
}
158
159
159
160
/**
160
- * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances without
161
- * regard to the {@link SimpMessageType}. If no destination is found on the
162
- * Message, then the Matcher returns false.
163
- * @param patterns the patterns to create
164
- * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
165
- * from.
166
- * @deprecated use {@link #destinationPathPatterns(String...)}
161
+ * Maps a {@link List} of {@link SimpDestinationMessageMatcher} (or
162
+ * {@link PathPatternMessageMatcher} if the application has configured a
163
+ * {@link org.springframework.security.messaging.util.matcher.PathPatternMessageMatcherBuilderFactoryBean})
164
+ * instances without regard to the {@link SimpMessageType}. If no destination is
165
+ * found on the Message, then the Matcher returns false.
166
+ * @param patterns the patterns to create {@code MessageMatcher}s from.
167
167
*/
168
- @ Deprecated
169
168
public Builder .Constraint simpDestMatchers (String ... patterns ) {
170
169
return simpDestMatchers (null , patterns );
171
170
}
172
171
173
172
/**
174
- * Allows the creation of a security {@link Constraint} applying to messages whose
175
- * destinations match the provided {@code patterns}.
176
- * <p>
177
- * The matching of each pattern is performed by a
178
- * {@link PathPatternMessageMatcher} instance that matches irrespectively of
179
- * {@link SimpMessageType}. If no destination is found on the {@code Message},
180
- * then each {@code Matcher} returns false.
181
- * </p>
182
- * @param patterns the destination path patterns to which the security
183
- * {@code Constraint} will be applicable
184
- * @since 6.5
173
+ * Maps a {@link List} of {@link SimpDestinationMessageMatcher} (or
174
+ * {@link PathPatternMessageMatcher} if the application has configured a
175
+ * {@link org.springframework.security.messaging.util.matcher.PathPatternMessageMatcherBuilderFactoryBean})
176
+ * instances that match on {@code SimpMessageType.MESSAGE}. If no destination is
177
+ * found on the Message, then the Matcher returns false.
178
+ * @param patterns the patterns to create {@code MessageMatcher}s from.
185
179
*/
186
- public Builder .Constraint destinationPathPatterns (String ... patterns ) {
187
- return destinationPathPatterns (null , patterns );
188
- }
189
-
190
- /**
191
- * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances that
192
- * match on {@code SimpMessageType.MESSAGE}. If no destination is found on the
193
- * Message, then the Matcher returns false.
194
- * @param patterns the patterns to create
195
- * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
196
- * from.
197
- * @deprecated use {@link #destinationPathPatterns(String...)}
198
- */
199
- @ Deprecated
200
180
public Builder .Constraint simpMessageDestMatchers (String ... patterns ) {
201
181
return simpDestMatchers (SimpMessageType .MESSAGE , patterns );
202
182
}
203
183
204
184
/**
205
- * Allows the creation of a security {@link Constraint} applying to messages of
206
- * the type {@code SimpMessageType.MESSAGE} whose destinations match the provided
207
- * {@code patterns}.
208
- * <p>
209
- * The matching of each pattern is performed by a
210
- * {@link PathPatternMessageMatcher}. If no destination is found on the
211
- * {@code Message}, then each {@code Matcher} returns false.
212
- * @param patterns the patterns to create {@link PathPatternMessageMatcher} from.
213
- * @since 6.5
214
- */
215
- public Builder .Constraint simpTypeMessageDestinationPatterns (String ... patterns ) {
216
- return destinationPathPatterns (SimpMessageType .MESSAGE , patterns );
217
- }
218
-
219
- /**
220
- * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances that
221
- * match on {@code SimpMessageType.SUBSCRIBE}. If no destination is found on the
222
- * Message, then the Matcher returns false.
223
- * @param patterns the patterns to create
224
- * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
225
- * from.
226
- * @deprecated use {@link #simpTypeSubscribeDestinationPatterns(String...)}
185
+ * Maps a {@link List} of {@link SimpDestinationMessageMatcher} (or
186
+ * {@link PathPatternMessageMatcher} if the application has configured a
187
+ * {@link org.springframework.security.messaging.util.matcher.PathPatternMessageMatcherBuilderFactoryBean})
188
+ * instances that match on {@code SimpMessageType.SUBSCRIBE}. If no destination is
189
+ * found on the Message, then the Matcher returns false.
190
+ * @param patterns the patterns to create {@code MessageMatcher}s from.
227
191
*/
228
- @ Deprecated
229
192
public Builder .Constraint simpSubscribeDestMatchers (String ... patterns ) {
230
193
return simpDestMatchers (SimpMessageType .SUBSCRIBE , patterns );
231
194
}
232
195
233
196
/**
234
- * Allows the creation of a security {@link Constraint} applying to messages of
235
- * the type {@code SimpMessageType.SUBSCRIBE} whose destinations match the
236
- * provided {@code patterns}.
237
- * <p>
238
- * The matching of each pattern is performed by a
239
- * {@link PathPatternMessageMatcher}. If no destination is found on the
240
- * {@code Message}, then each {@code Matcher} returns false.
241
- * @param patterns the patterns to create {@link PathPatternMessageMatcher} from.
242
- * @since 6.5
243
- */
244
- public Builder .Constraint simpTypeSubscribeDestinationPatterns (String ... patterns ) {
245
- return destinationPathPatterns (SimpMessageType .SUBSCRIBE , patterns );
246
- }
247
-
248
- /**
249
- * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances. If no
250
- * destination is found on the Message, then the Matcher returns false.
197
+ * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances, or
198
+ * {@link PathPatternMessageMatcher} if the application has configured a
199
+ * {@link org.springframework.security.messaging.util.matcher.PathPatternMessageMatcherBuilderFactoryBean}.
200
+ * If no destination is found on the Message, then the Matcher returns false.
251
201
* @param type the {@link SimpMessageType} to match on. If null, the
252
202
* {@link SimpMessageType} is not considered for matching.
253
- * @param patterns the patterns to create
254
- * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
255
- * from.
203
+ * @param patterns the patterns to create {@code MessageMatcher}s from.
256
204
* @return the {@link Builder.Constraint} that is associated to the
257
205
* {@link MessageMatcher}
258
- * @deprecated use {@link #destinationPathPatterns(String...)}
259
206
*/
260
- @ Deprecated
261
207
private Builder .Constraint simpDestMatchers (SimpMessageType type , String ... patterns ) {
262
208
List <MessageMatcher <?>> matchers = new ArrayList <>(patterns .length );
263
209
for (String pattern : patterns ) {
264
- MessageMatcher <Object > matcher = new LazySimpDestinationMessageMatcher (pattern , type );
210
+ MessageMatcher <Object > matcher = MessageMatcherFactory .usesPathPatterns ()
211
+ ? MessageMatcherFactory .matcher (pattern , type )
212
+ : new LazySimpDestinationMessageMatcher (pattern , type );
265
213
matchers .add (matcher );
266
214
}
267
215
return new Builder .Constraint (matchers );
268
216
}
269
217
270
- /**
271
- * Allows the creation of a security {@link Constraint} applying to messages of
272
- * the provided {@code type} whose destinations match the provided
273
- * {@code patterns}.
274
- * <p>
275
- * The matching of each pattern is performed by a
276
- * {@link PathPatternMessageMatcher}. If no destination is found on the
277
- * {@code Message}, then each {@code Matcher} returns false.
278
- * </p>
279
- * @param type the {@link SimpMessageType} to match on. If null, the
280
- * {@link SimpMessageType} is not considered for matching.
281
- * @param patterns the patterns to create {@link PathPatternMessageMatcher} from.
282
- * @return the {@link Builder.Constraint} that is associated to the
283
- * {@link MessageMatcher}s
284
- * @since 6.5
285
- */
286
- private Builder .Constraint destinationPathPatterns (SimpMessageType type , String ... patterns ) {
287
- List <MessageMatcher <?>> matchers = new ArrayList <>(patterns .length );
288
- for (String pattern : patterns ) {
289
- MessageMatcher <Object > matcher = new LazySimpDestinationPatternMessageMatcher (pattern , type ,
290
- this .useHttpPathSeparator );
291
- matchers .add (matcher );
292
- }
293
- return new Builder .Constraint (matchers );
294
- }
295
-
296
- /**
297
- * Instruct this builder to match message destinations using the separator
298
- * configured in
299
- * {@link org.springframework.http.server.PathContainer.Options#MESSAGE_ROUTE}
300
- */
301
- public Builder messageRouteSeparator () {
302
- this .useHttpPathSeparator = false ;
303
- return this ;
304
- }
305
-
306
218
/**
307
219
* The {@link PathMatcher} to be used with the
308
220
* {@link Builder#simpDestMatchers(String...)}. The default is to use the default
309
221
* constructor of {@link AntPathMatcher}.
310
222
* @param pathMatcher the {@link PathMatcher} to use. Cannot be null.
311
223
* @return the {@link Builder} for further customization.
312
- * @deprecated use {@link #messageRouteSeparator()} to alter the path separator
224
+ * @deprecated
313
225
*/
314
226
@ Deprecated
315
227
public Builder simpDestPathMatcher (PathMatcher pathMatcher ) {
@@ -324,7 +236,7 @@ public Builder simpDestPathMatcher(PathMatcher pathMatcher) {
324
236
* computation or lookup of the {@link PathMatcher}.
325
237
* @param pathMatcher the {@link PathMatcher} to use. Cannot be null.
326
238
* @return the {@link Builder} for further customization.
327
- * @deprecated use {@link #messageRouteSeparator()} to alter the path separator
239
+ * @deprecated
328
240
*/
329
241
@ Deprecated
330
242
public Builder simpDestPathMatcher (Supplier <PathMatcher > pathMatcher ) {
@@ -513,40 +425,6 @@ Map<String, String> extractPathVariables(Message<?> message) {
513
425
514
426
}
515
427
516
- private static final class LazySimpDestinationPatternMessageMatcher implements MessageMatcher <Object > {
517
-
518
- private final Supplier <PathPatternMessageMatcher > delegate ;
519
-
520
- private LazySimpDestinationPatternMessageMatcher (String pattern , SimpMessageType type ,
521
- boolean useHttpPathSeparator ) {
522
- this .delegate = SingletonSupplier .of (() -> {
523
- PathPatternParser dotSeparatedPathParser = new PathPatternParser ();
524
- dotSeparatedPathParser .setPathOptions (PathContainer .Options .MESSAGE_ROUTE );
525
- PathPatternMessageMatcher .Builder builder = (useHttpPathSeparator )
526
- ? PathPatternMessageMatcher .withDefaults ()
527
- : PathPatternMessageMatcher .withPathPatternParser (dotSeparatedPathParser );
528
- if (type == null ) {
529
- return builder .matcher (pattern );
530
- }
531
- if (SimpMessageType .MESSAGE == type || SimpMessageType .SUBSCRIBE == type ) {
532
- return builder .matcher (pattern , type );
533
- }
534
- throw new IllegalStateException (type + " is not supported since it does not have a destination" );
535
- });
536
- }
537
-
538
- @ Override
539
- public boolean matches (Message <?> message ) {
540
- return this .delegate .get ().matches (message );
541
- }
542
-
543
- Map <String , String > extractPathVariables (Message <?> message ) {
544
- MatchResult matchResult = this .delegate .get ().matcher (message );
545
- return matchResult .getVariables ();
546
- }
547
-
548
- }
549
-
550
428
}
551
429
552
430
private static final class Entry <T > {
0 commit comments