1717package org .springframework .security .messaging .access .intercept ;
1818
1919import java .util .ArrayList ;
20+ import java .util .Arrays ;
2021import java .util .List ;
2122import java .util .Map ;
2223import java .util .function .Supplier ;
3435import org .springframework .security .authorization .SingleResultAuthorizationManager ;
3536import org .springframework .security .core .Authentication ;
3637import org .springframework .security .messaging .util .matcher .MessageMatcher ;
38+ import org .springframework .security .messaging .util .matcher .MessageMatcherFactory ;
39+ import org .springframework .security .messaging .util .matcher .PathPatternMessageMatcher ;
3740import org .springframework .security .messaging .util .matcher .SimpDestinationMessageMatcher ;
3841import org .springframework .security .messaging .util .matcher .SimpMessageTypeMatcher ;
3942import org .springframework .util .AntPathMatcher ;
4043import org .springframework .util .Assert ;
44+ import org .springframework .util .CollectionUtils ;
4145import org .springframework .util .PathMatcher ;
4246import org .springframework .util .function .SingletonSupplier ;
4347
@@ -85,15 +89,17 @@ public AuthorizationDecision check(Supplier<Authentication> authentication, Mess
8589 }
8690
8791 private MessageAuthorizationContext <?> authorizationContext (MessageMatcher <?> matcher , Message <?> message ) {
88- if (!matcher .matches ((Message ) message )) {
92+ MessageMatcher .MatchResult matchResult = matcher .matcher ((Message ) message );
93+ if (!matchResult .isMatch ()) {
8994 return null ;
9095 }
91- if (matcher instanceof SimpDestinationMessageMatcher simp ) {
92- return new MessageAuthorizationContext <>(message , simp .extractPathVariables (message ));
96+
97+ if (!CollectionUtils .isEmpty (matchResult .getVariables ())) {
98+ return new MessageAuthorizationContext <>(message , matchResult .getVariables ());
9399 }
94- if ( matcher instanceof Builder . LazySimpDestinationMessageMatcher ) {
95- Builder . LazySimpDestinationMessageMatcher path = ( Builder .LazySimpDestinationMessageMatcher ) matcher ;
96- return new MessageAuthorizationContext <>(message , path .extractPathVariables (message ));
100+
101+ if ( matcher instanceof Builder .LazySimpDestinationMessageMatcher pathMatcher ) {
102+ return new MessageAuthorizationContext <>(message , pathMatcher .extractPathVariables (message ));
97103 }
98104 return new MessageAuthorizationContext <>(message );
99105 }
@@ -113,6 +119,7 @@ public static final class Builder {
113119
114120 private final List <Entry <AuthorizationManager <MessageAuthorizationContext <?>>>> mappings = new ArrayList <>();
115121
122+ @ Deprecated
116123 private Supplier <PathMatcher > pathMatcher = AntPathMatcher ::new ;
117124
118125 public Builder () {
@@ -133,11 +140,11 @@ public Builder.Constraint anyMessage() {
133140 * @return the Expression to associate
134141 */
135142 public Builder .Constraint nullDestMatcher () {
136- return matchers (SimpDestinationMessageMatcher .NULL_DESTINATION_MATCHER );
143+ return matchers (PathPatternMessageMatcher .NULL_DESTINATION_MATCHER );
137144 }
138145
139146 /**
140- * Maps a {@link List} of {@link SimpDestinationMessageMatcher } instances.
147+ * Maps a {@link List} of {@link SimpMessageTypeMatcher } instances.
141148 * @param typesToMatch the {@link SimpMessageType} instance to match on
142149 * @return the {@link Builder.Constraint} associated to the matchers.
143150 */
@@ -151,56 +158,58 @@ public Builder.Constraint simpTypeMatchers(SimpMessageType... typesToMatch) {
151158 }
152159
153160 /**
154- * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances without
155- * regard to the {@link SimpMessageType}. If no destination is found on the
156- * Message, then the Matcher returns false.
157- * @param patterns the patterns to create
158- * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
159- * from.
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.
160167 */
161168 public Builder .Constraint simpDestMatchers (String ... patterns ) {
162169 return simpDestMatchers (null , patterns );
163170 }
164171
165172 /**
166- * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances that
167- * match on {@code SimpMessageType.MESSAGE}. If no destination is found on the
168- * Message, then the Matcher returns false.
169- * @param patterns the patterns to create
170- * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
171- * from.
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.
172179 */
173180 public Builder .Constraint simpMessageDestMatchers (String ... patterns ) {
174181 return simpDestMatchers (SimpMessageType .MESSAGE , patterns );
175182 }
176183
177184 /**
178- * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances that
179- * match on {@code SimpMessageType.SUBSCRIBE}. If no destination is found on the
180- * Message, then the Matcher returns false.
181- * @param patterns the patterns to create
182- * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
183- * from.
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.
184191 */
185192 public Builder .Constraint simpSubscribeDestMatchers (String ... patterns ) {
186193 return simpDestMatchers (SimpMessageType .SUBSCRIBE , patterns );
187194 }
188195
189196 /**
190- * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances. If no
191- * 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.
192201 * @param type the {@link SimpMessageType} to match on. If null, the
193202 * {@link SimpMessageType} is not considered for matching.
194- * @param patterns the patterns to create
195- * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
196- * from.
203+ * @param patterns the patterns to create {@code MessageMatcher}s from.
197204 * @return the {@link Builder.Constraint} that is associated to the
198205 * {@link MessageMatcher}
199206 */
200207 private Builder .Constraint simpDestMatchers (SimpMessageType type , String ... patterns ) {
201208 List <MessageMatcher <?>> matchers = new ArrayList <>(patterns .length );
202209 for (String pattern : patterns ) {
203- MessageMatcher <Object > matcher = new LazySimpDestinationMessageMatcher (pattern , type );
210+ MessageMatcher <Object > matcher = MessageMatcherFactory .usesPathPatterns ()
211+ ? MessageMatcherFactory .matcher (pattern , type )
212+ : new LazySimpDestinationMessageMatcher (pattern , type );
204213 matchers .add (matcher );
205214 }
206215 return new Builder .Constraint (matchers );
@@ -212,7 +221,9 @@ private Builder.Constraint simpDestMatchers(SimpMessageType type, String... patt
212221 * constructor of {@link AntPathMatcher}.
213222 * @param pathMatcher the {@link PathMatcher} to use. Cannot be null.
214223 * @return the {@link Builder} for further customization.
224+ * @deprecated
215225 */
226+ @ Deprecated
216227 public Builder simpDestPathMatcher (PathMatcher pathMatcher ) {
217228 Assert .notNull (pathMatcher , "pathMatcher cannot be null" );
218229 this .pathMatcher = () -> pathMatcher ;
@@ -225,7 +236,9 @@ public Builder simpDestPathMatcher(PathMatcher pathMatcher) {
225236 * computation or lookup of the {@link PathMatcher}.
226237 * @param pathMatcher the {@link PathMatcher} to use. Cannot be null.
227238 * @return the {@link Builder} for further customization.
239+ * @deprecated
228240 */
241+ @ Deprecated
229242 public Builder simpDestPathMatcher (Supplier <PathMatcher > pathMatcher ) {
230243 Assert .notNull (pathMatcher , "pathMatcher cannot be null" );
231244 this .pathMatcher = pathMatcher ;
@@ -241,9 +254,7 @@ public Builder simpDestPathMatcher(Supplier<PathMatcher> pathMatcher) {
241254 */
242255 public Builder .Constraint matchers (MessageMatcher <?>... matchers ) {
243256 List <MessageMatcher <?>> builders = new ArrayList <>(matchers .length );
244- for (MessageMatcher <?> matcher : matchers ) {
245- builders .add (matcher );
246- }
257+ builders .addAll (Arrays .asList (matchers ));
247258 return new Builder .Constraint (builders );
248259 }
249260
@@ -382,6 +393,7 @@ public Builder access(AuthorizationManager<MessageAuthorizationContext<?>> autho
382393
383394 }
384395
396+ @ Deprecated
385397 private final class LazySimpDestinationMessageMatcher implements MessageMatcher <Object > {
386398
387399 private final Supplier <SimpDestinationMessageMatcher > delegate ;
@@ -421,7 +433,7 @@ private static final class Entry<T> {
421433
422434 private final T entry ;
423435
424- Entry (MessageMatcher requestMatcher , T entry ) {
436+ Entry (MessageMatcher <?> requestMatcher , T entry ) {
425437 this .messageMatcher = requestMatcher ;
426438 this .entry = entry ;
427439 }
0 commit comments