Преглед на файлове

Revert "Add AuthorizationManager to Messaging"

This reverts commit 77a6e014a9c3da916559ae7d1707b09db3ab1194.
Josh Cummings преди 3 години
родител
ревизия
b39f213e64
променени са 20 файла, в които са добавени 12 реда и са изтрити 2005 реда
  1. 3 3
      config/src/main/java/org/springframework/security/config/annotation/web/configuration/EnableWebSecurity.java
  2. 0 43
      config/src/main/java/org/springframework/security/config/annotation/web/configuration/SpringWebSocketImportSelector.java
  3. 0 354
      config/src/main/java/org/springframework/security/config/annotation/web/messaging/AuthorizationManagerMessageMatcherRegistry.java
  4. 1 3
      config/src/main/java/org/springframework/security/config/annotation/web/messaging/MessageSecurityMetadataSourceRegistry.java
  5. 1 7
      config/src/main/java/org/springframework/security/config/annotation/web/socket/AbstractSecurityWebSocketMessageBrokerConfigurer.java
  6. 0 34
      config/src/main/java/org/springframework/security/config/annotation/web/socket/MessageMatcherAuthorizationManagerConfiguration.java
  7. 0 211
      config/src/main/java/org/springframework/security/config/annotation/web/socket/WebSocketMessageBrokerSecurityConfiguration.java
  8. 0 176
      config/src/test/java/org/springframework/security/config/annotation/web/socket/WebSocketMessageBrokerSecurityConfigurationDocTests.java
  9. 0 796
      config/src/test/java/org/springframework/security/config/annotation/web/socket/WebSocketMessageBrokerSecurityConfigurationTests.java
  10. 1 4
      messaging/src/main/java/org/springframework/security/messaging/access/expression/EvaluationContextPostProcessor.java
  11. 1 5
      messaging/src/main/java/org/springframework/security/messaging/access/expression/ExpressionBasedMessageSecurityMetadataSourceFactory.java
  12. 1 5
      messaging/src/main/java/org/springframework/security/messaging/access/expression/MessageExpressionConfigAttribute.java
  13. 1 5
      messaging/src/main/java/org/springframework/security/messaging/access/expression/MessageExpressionVoter.java
  14. 0 95
      messaging/src/main/java/org/springframework/security/messaging/access/intercept/AuthorizationChannelInterceptor.java
  15. 1 3
      messaging/src/main/java/org/springframework/security/messaging/access/intercept/ChannelSecurityInterceptor.java
  16. 1 3
      messaging/src/main/java/org/springframework/security/messaging/access/intercept/DefaultMessageSecurityMetadataSource.java
  17. 0 75
      messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageAuthorizationContext.java
  18. 0 136
      messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageMatcherDelegatingAuthorizationManager.java
  19. 1 3
      messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource.java
  20. 0 44
      messaging/src/main/java/org/springframework/security/messaging/util/matcher/MessageMatcherEntry.java

+ 3 - 3
config/src/main/java/org/springframework/security/config/annotation/web/configuration/EnableWebSecurity.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2020 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -75,8 +75,8 @@ import org.springframework.security.config.annotation.web.WebSecurityConfigurer;
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
 @Documented
-@Import({ WebSecurityConfiguration.class, SpringWebMvcImportSelector.class, SpringWebSocketImportSelector.class,
-		OAuth2ImportSelector.class, HttpSecurityConfiguration.class })
+@Import({ WebSecurityConfiguration.class, SpringWebMvcImportSelector.class, OAuth2ImportSelector.class,
+		HttpSecurityConfiguration.class })
 @EnableGlobalAuthentication
 @Configuration
 public @interface EnableWebSecurity {

+ 0 - 43
config/src/main/java/org/springframework/security/config/annotation/web/configuration/SpringWebSocketImportSelector.java

@@ -1,43 +0,0 @@
-/*
- * Copyright 2002-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.config.annotation.web.configuration;
-
-import org.springframework.context.annotation.ImportSelector;
-import org.springframework.core.type.AnnotationMetadata;
-import org.springframework.util.ClassUtils;
-
-/**
- * Used by {@link EnableWebSecurity} to conditionally import
- * {@link org.springframework.security.config.annotation.web.socket.WebSocketMessageBrokerSecurityConfiguration}
- * when the AbstractWebSocketHandler is present on the classpath.
- *
- * @author Josh Cummings
- * @since 5.7
- */
-class SpringWebSocketImportSelector implements ImportSelector {
-
-	@Override
-	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
-		if (!ClassUtils.isPresent("org.springframework.web.socket.handler.AbstractWebSocketHandler",
-				getClass().getClassLoader())) {
-			return new String[0];
-		}
-		return new String[] {
-				"org.springframework.security.config.annotation.web.socket.WebSocketMessageBrokerSecurityConfiguration" };
-	}
-
-}

+ 0 - 354
config/src/main/java/org/springframework/security/config/annotation/web/messaging/AuthorizationManagerMessageMatcherRegistry.java

@@ -1,354 +0,0 @@
-/*
- * Copyright 2002-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.config.annotation.web.messaging;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Supplier;
-
-import org.springframework.context.ApplicationContext;
-import org.springframework.messaging.Message;
-import org.springframework.messaging.simp.SimpMessageType;
-import org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler;
-import org.springframework.security.authorization.AuthenticatedAuthorizationManager;
-import org.springframework.security.authorization.AuthorityAuthorizationManager;
-import org.springframework.security.authorization.AuthorizationDecision;
-import org.springframework.security.authorization.AuthorizationManager;
-import org.springframework.security.messaging.access.intercept.MessageAuthorizationContext;
-import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager;
-import org.springframework.security.messaging.util.matcher.MessageMatcher;
-import org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher;
-import org.springframework.security.messaging.util.matcher.SimpMessageTypeMatcher;
-import org.springframework.util.AntPathMatcher;
-import org.springframework.util.Assert;
-import org.springframework.util.PathMatcher;
-
-/**
- * Allows mapping security constraints using {@link MessageMatcher} to authorization
- * managers.
- *
- * @author Josh Cummings
- * @since 5.7
- */
-public final class AuthorizationManagerMessageMatcherRegistry {
-
-	private final MessageMatcherDelegatingAuthorizationManager.Builder builder = MessageMatcherDelegatingAuthorizationManager
-			.builder();
-
-	private final ApplicationContext context;
-
-	private PathMatcher pathMatcher;
-
-	public AuthorizationManagerMessageMatcherRegistry(ApplicationContext context) {
-		this.context = context;
-	}
-
-	/**
-	 * Maps any {@link Message} to a security expression.
-	 * @return the Expression to associate
-	 */
-	public AuthorizationManagerMessageMatcherRegistry.Constraint anyMessage() {
-		return matchers(MessageMatcher.ANY_MESSAGE);
-	}
-
-	/**
-	 * Maps any {@link Message} that has a null SimpMessageHeaderAccessor destination
-	 * header (i.e. CONNECT, CONNECT_ACK, HEARTBEAT, UNSUBSCRIBE, DISCONNECT,
-	 * DISCONNECT_ACK, OTHER)
-	 * @return the Expression to associate
-	 */
-	public AuthorizationManagerMessageMatcherRegistry.Constraint nullDestMatcher() {
-		return matchers(SimpDestinationMessageMatcher.NULL_DESTINATION_MATCHER);
-	}
-
-	/**
-	 * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances.
-	 * @param typesToMatch the {@link SimpMessageType} instance to match on
-	 * @return the {@link Constraint} associated to the matchers.
-	 */
-	public AuthorizationManagerMessageMatcherRegistry.Constraint simpTypeMatchers(SimpMessageType... typesToMatch) {
-		MessageMatcher<?>[] typeMatchers = new MessageMatcher<?>[typesToMatch.length];
-		for (int i = 0; i < typesToMatch.length; i++) {
-			SimpMessageType typeToMatch = typesToMatch[i];
-			typeMatchers[i] = new SimpMessageTypeMatcher(typeToMatch);
-		}
-		return matchers(typeMatchers);
-	}
-
-	/**
-	 * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances without
-	 * regard to the {@link SimpMessageType}. If no destination is found on the Message,
-	 * then the Matcher returns false.
-	 * @param patterns the patterns to create
-	 * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
-	 * from.
-	 */
-	public Constraint simpDestMatchers(String... patterns) {
-		return simpDestMatchers(null, patterns);
-	}
-
-	/**
-	 * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances that match
-	 * on {@code SimpMessageType.MESSAGE}. If no destination is found on the Message, then
-	 * the Matcher returns false.
-	 * @param patterns the patterns to create
-	 * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
-	 * from.
-	 */
-	public Constraint simpMessageDestMatchers(String... patterns) {
-		return simpDestMatchers(SimpMessageType.MESSAGE, patterns);
-	}
-
-	/**
-	 * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances that match
-	 * on {@code SimpMessageType.SUBSCRIBE}. If no destination is found on the Message,
-	 * then the Matcher returns false.
-	 * @param patterns the patterns to create
-	 * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
-	 * from.
-	 */
-	public Constraint simpSubscribeDestMatchers(String... patterns) {
-		return simpDestMatchers(SimpMessageType.SUBSCRIBE, patterns);
-	}
-
-	/**
-	 * Maps a {@link List} of {@link SimpDestinationMessageMatcher} instances. If no
-	 * destination is found on the Message, then the Matcher returns false.
-	 * @param type the {@link SimpMessageType} to match on. If null, the
-	 * {@link SimpMessageType} is not considered for matching.
-	 * @param patterns the patterns to create
-	 * {@link org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher}
-	 * from.
-	 * @return the {@link Constraint} that is associated to the {@link MessageMatcher}
-	 */
-	private Constraint simpDestMatchers(SimpMessageType type, String... patterns) {
-		List<MessageMatcher<?>> matchers = new ArrayList<>(patterns.length);
-		for (String pattern : patterns) {
-			Supplier<MessageMatcher<Object>> supplier = new PathMatcherMessageMatcherBuilder(pattern, type);
-			MessageMatcher<?> matcher = new SupplierMessageMatcher(supplier);
-			matchers.add(matcher);
-		}
-		return new Constraint(matchers);
-	}
-
-	/**
-	 * The {@link PathMatcher} to be used with the
-	 * {@link MessageSecurityMetadataSourceRegistry#simpDestMatchers(String...)}. The
-	 * default is to use the default constructor of {@link AntPathMatcher}.
-	 * @param pathMatcher the {@link PathMatcher} to use. Cannot be null.
-	 * @return the {@link MessageSecurityMetadataSourceRegistry} for further
-	 * customization.
-	 */
-	public AuthorizationManagerMessageMatcherRegistry simpDestPathMatcher(PathMatcher pathMatcher) {
-		Assert.notNull(pathMatcher, "pathMatcher cannot be null");
-		this.pathMatcher = pathMatcher;
-		return this;
-	}
-
-	/**
-	 * Maps a {@link List} of {@link MessageMatcher} instances to a security expression.
-	 * @param matchers the {@link MessageMatcher} instances to map.
-	 * @return The {@link Constraint} that is associated to the {@link MessageMatcher}
-	 * instances
-	 */
-	public Constraint matchers(MessageMatcher<?>... matchers) {
-		List<MessageMatcher<?>> builders = new ArrayList<>(matchers.length);
-		for (MessageMatcher<?> matcher : matchers) {
-			builders.add(matcher);
-		}
-		return new Constraint(builders);
-	}
-
-	public AuthorizationManager<Message<?>> build() {
-		return this.builder.build();
-	}
-
-	/**
-	 * Represents the security constraint to be applied to the {@link MessageMatcher}
-	 * instances.
-	 */
-	public final class Constraint {
-
-		private final List<? extends MessageMatcher<?>> messageMatchers;
-
-		/**
-		 * Creates a new instance
-		 * @param messageMatchers the {@link MessageMatcher} instances to map to this
-		 * constraint
-		 */
-		private Constraint(List<? extends MessageMatcher<?>> messageMatchers) {
-			Assert.notEmpty(messageMatchers, "messageMatchers cannot be null or empty");
-			this.messageMatchers = messageMatchers;
-		}
-
-		/**
-		 * Shortcut for specifying {@link Message} instances require a particular role. If
-		 * you do not want to have "ROLE_" automatically inserted see
-		 * {@link #hasAuthority(String)}.
-		 * @param role the role to require (i.e. USER, ADMIN, etc). Note, it should not
-		 * start with "ROLE_" as this is automatically inserted.
-		 * @return the {@link MessageMatcherDelegatingAuthorizationManager.Builder} for
-		 * further customization
-		 */
-		public AuthorizationManagerMessageMatcherRegistry hasRole(String role) {
-			return access(AuthorityAuthorizationManager.hasRole(role));
-		}
-
-		/**
-		 * Shortcut for specifying {@link Message} instances require any of a number of
-		 * roles. If you do not want to have "ROLE_" automatically inserted see
-		 * {@link #hasAnyAuthority(String...)}
-		 * @param roles the roles to require (i.e. USER, ADMIN, etc). Note, it should not
-		 * start with "ROLE_" as this is automatically inserted.
-		 * @return the {@link MessageMatcherDelegatingAuthorizationManager.Builder} for
-		 * further customization
-		 */
-		public AuthorizationManagerMessageMatcherRegistry hasAnyRole(String... roles) {
-			return access(AuthorityAuthorizationManager.hasAnyRole(roles));
-		}
-
-		/**
-		 * Specify that {@link Message} instances require a particular authority.
-		 * @param authority the authority to require (i.e. ROLE_USER, ROLE_ADMIN, etc).
-		 * @return the {@link MessageMatcherDelegatingAuthorizationManager.Builder} for
-		 * further customization
-		 */
-		public AuthorizationManagerMessageMatcherRegistry hasAuthority(String authority) {
-			return access(AuthorityAuthorizationManager.hasAuthority(authority));
-		}
-
-		/**
-		 * Specify that {@link Message} instances requires any of a number authorities.
-		 * @param authorities the requests require at least one of the authorities (i.e.
-		 * "ROLE_USER","ROLE_ADMIN" would mean either "ROLE_USER" or "ROLE_ADMIN" is
-		 * required).
-		 * @return the {@link MessageMatcherDelegatingAuthorizationManager.Builder} for
-		 * further customization
-		 */
-		public AuthorizationManagerMessageMatcherRegistry hasAnyAuthority(String... authorities) {
-			return access(AuthorityAuthorizationManager.hasAnyAuthority(authorities));
-		}
-
-		/**
-		 * Specify that Messages are allowed by anyone.
-		 * @return the {@link MessageMatcherDelegatingAuthorizationManager.Builder} for
-		 * further customization
-		 */
-		public AuthorizationManagerMessageMatcherRegistry permitAll() {
-			return access((authentication, context) -> new AuthorizationDecision(true));
-		}
-
-		/**
-		 * Specify that Messages are not allowed by anyone.
-		 * @return the {@link MessageMatcherDelegatingAuthorizationManager.Builder} for
-		 * further customization
-		 */
-		public AuthorizationManagerMessageMatcherRegistry denyAll() {
-			return access((authorization, context) -> new AuthorizationDecision(false));
-		}
-
-		/**
-		 * Specify that Messages are allowed by any authenticated user.
-		 * @return the {@link MessageMatcherDelegatingAuthorizationManager.Builder} for
-		 * further customization
-		 */
-		public AuthorizationManagerMessageMatcherRegistry authenticated() {
-			return access(AuthenticatedAuthorizationManager.authenticated());
-		}
-
-		/**
-		 * Allows specifying that Messages are secured by an arbitrary expression
-		 * @param authorizationManager the {@link AuthorizationManager} to secure the
-		 * destinations
-		 * @return the {@link MessageMatcherDelegatingAuthorizationManager.Builder} for
-		 * further customization
-		 */
-		public AuthorizationManagerMessageMatcherRegistry access(
-				AuthorizationManager<MessageAuthorizationContext<?>> authorizationManager) {
-			for (MessageMatcher<?> messageMatcher : this.messageMatchers) {
-				AuthorizationManagerMessageMatcherRegistry.this.builder.add(messageMatcher, authorizationManager);
-			}
-			return AuthorizationManagerMessageMatcherRegistry.this;
-		}
-
-	}
-
-	private static final class SupplierMessageMatcher implements MessageMatcher<Object> {
-
-		private final Supplier<MessageMatcher<Object>> supplier;
-
-		private volatile MessageMatcher<Object> delegate;
-
-		SupplierMessageMatcher(Supplier<MessageMatcher<Object>> supplier) {
-			this.supplier = supplier;
-		}
-
-		@Override
-		public boolean matches(Message<?> message) {
-			if (this.delegate == null) {
-				synchronized (this.supplier) {
-					if (this.delegate == null) {
-						this.delegate = this.supplier.get();
-					}
-				}
-			}
-			return this.delegate.matches(message);
-		}
-
-	}
-
-	private final class PathMatcherMessageMatcherBuilder implements Supplier<MessageMatcher<Object>> {
-
-		private final String pattern;
-
-		private final SimpMessageType type;
-
-		private PathMatcherMessageMatcherBuilder(String pattern, SimpMessageType type) {
-			this.pattern = pattern;
-			this.type = type;
-		}
-
-		private PathMatcher resolvePathMatcher() {
-			if (AuthorizationManagerMessageMatcherRegistry.this.pathMatcher != null) {
-				return AuthorizationManagerMessageMatcherRegistry.this.pathMatcher;
-			}
-			if (AuthorizationManagerMessageMatcherRegistry.this.context
-					.getBeanNamesForType(SimpAnnotationMethodMessageHandler.class).length > 0) {
-				return AuthorizationManagerMessageMatcherRegistry.this.context
-						.getBean(SimpAnnotationMethodMessageHandler.class).getPathMatcher();
-			}
-			return new AntPathMatcher();
-		}
-
-		@Override
-		public MessageMatcher<Object> get() {
-			PathMatcher pathMatcher = resolvePathMatcher();
-			if (this.type == null) {
-				return new SimpDestinationMessageMatcher(this.pattern, pathMatcher);
-			}
-			if (SimpMessageType.MESSAGE == this.type) {
-				return SimpDestinationMessageMatcher.createMessageMatcher(this.pattern, pathMatcher);
-			}
-			if (SimpMessageType.SUBSCRIBE == this.type) {
-				return SimpDestinationMessageMatcher.createSubscribeMatcher(this.pattern, pathMatcher);
-			}
-			throw new IllegalStateException(this.type + " is not supported since it does not have a destination");
-		}
-
-	}
-
-}

+ 1 - 3
config/src/main/java/org/springframework/security/config/annotation/web/messaging/MessageSecurityMetadataSourceRegistry.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -43,9 +43,7 @@ import org.springframework.util.StringUtils;
  *
  * @author Rob Winch
  * @since 4.0
- * @deprecated Use {@link AuthorizationManagerMessageMatcherRegistry} instead
  */
-@Deprecated
 public class MessageSecurityMetadataSourceRegistry {
 
 	private static final String permitAll = "permitAll";

+ 1 - 7
config/src/main/java/org/springframework/security/config/annotation/web/socket/AbstractSecurityWebSocketMessageBrokerConfigurer.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -81,15 +81,9 @@ import org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsSe
  *
  * @author Rob Winch
  * @since 4.0
- * @see WebSocketMessageBrokerSecurityConfiguration
- * @deprecated Use
- * {@link org.springframework.security.config.annotation.web.configuration.EnableWebSecurity}
- * and see {@link WebSocketMessageBrokerSecurityConfiguration} for additional usage
- * information instead
  */
 @Order(Ordered.HIGHEST_PRECEDENCE + 100)
 @Import(ObjectPostProcessorConfiguration.class)
-@Deprecated
 public abstract class AbstractSecurityWebSocketMessageBrokerConfigurer extends AbstractWebSocketMessageBrokerConfigurer
 		implements SmartInitializingSingleton {
 

+ 0 - 34
config/src/main/java/org/springframework/security/config/annotation/web/socket/MessageMatcherAuthorizationManagerConfiguration.java

@@ -1,34 +0,0 @@
-/*
- * Copyright 2002-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.config.annotation.web.socket;
-
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Scope;
-import org.springframework.security.config.annotation.web.messaging.AuthorizationManagerMessageMatcherRegistry;
-
-@Configuration(proxyBeanMethods = false)
-final class MessageMatcherAuthorizationManagerConfiguration {
-
-	@Bean
-	@Scope("prototype")
-	AuthorizationManagerMessageMatcherRegistry authorizationManagerMessageMatcherRegistry(ApplicationContext context) {
-		return new AuthorizationManagerMessageMatcherRegistry(context);
-	}
-
-}

+ 0 - 211
config/src/main/java/org/springframework/security/config/annotation/web/socket/WebSocketMessageBrokerSecurityConfiguration.java

@@ -1,211 +0,0 @@
-/*
- * Copyright 2002-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.config.annotation.web.socket;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Consumer;
-
-import org.springframework.beans.factory.SmartInitializingSingleton;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Import;
-import org.springframework.core.Ordered;
-import org.springframework.core.annotation.Order;
-import org.springframework.messaging.Message;
-import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver;
-import org.springframework.messaging.simp.config.ChannelRegistration;
-import org.springframework.messaging.support.ChannelInterceptor;
-import org.springframework.security.authorization.AuthenticatedAuthorizationManager;
-import org.springframework.security.authorization.AuthorizationManager;
-import org.springframework.security.authorization.SpringAuthorizationEventPublisher;
-import org.springframework.security.messaging.access.intercept.AuthorizationChannelInterceptor;
-import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager;
-import org.springframework.security.messaging.context.AuthenticationPrincipalArgumentResolver;
-import org.springframework.security.messaging.context.SecurityContextChannelInterceptor;
-import org.springframework.security.messaging.util.matcher.MessageMatcher;
-import org.springframework.security.messaging.web.csrf.CsrfChannelInterceptor;
-import org.springframework.security.messaging.web.socket.server.CsrfTokenHandshakeInterceptor;
-import org.springframework.util.Assert;
-import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
-import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
-import org.springframework.web.socket.server.HandshakeInterceptor;
-import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler;
-import org.springframework.web.socket.sockjs.SockJsService;
-import org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler;
-import org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService;
-
-/**
- * Allows configuring WebSocket Authorization.
- *
- * <p>
- * For example:
- * </p>
- *
- * <pre>
- * &#064;Configuration
- * &#064;EnableWebSecurity
- * public class WebSocketSecurityConfig {
- *
- * 	&#064;Bean
- * 	AuthorizationManager&lt;Message&lt;?&gt;&gt; (AuthorizationManagerMessageMatcherRegistry messages) {
- * 		messages.simpDestMatchers(&quot;/user/queue/errors&quot;).permitAll()
- * 				.simpDestMatchers(&quot;/admin/**&quot;).hasRole(&quot;ADMIN&quot;).anyMessage()
- * 				.authenticated();
- *
- *		return messages.build();
- * 	}
- * }
- * </pre>
- *
- * @author Josh Cummings
- * @since 5.7
- */
-@Order(Ordered.HIGHEST_PRECEDENCE + 100)
-@Import(MessageMatcherAuthorizationManagerConfiguration.class)
-final class WebSocketMessageBrokerSecurityConfiguration
-		implements WebSocketMessageBrokerConfigurer, SmartInitializingSingleton {
-
-	private static final String SIMPLE_URL_HANDLER_MAPPING_BEAN_NAME = "stompWebSocketHandlerMapping";
-
-	private static final AuthorizationManager<Message<?>> ANY_MESSAGE_AUTHENTICATED = MessageMatcherDelegatingAuthorizationManager
-			.builder().add(MessageMatcher.ANY_MESSAGE, AuthenticatedAuthorizationManager.authenticated()).build();
-
-	private ChannelInterceptor securityContextChannelInterceptor = new SecurityContextChannelInterceptor();
-
-	private ChannelInterceptor csrfChannelInterceptor = new CsrfChannelInterceptor();
-
-	private AuthorizationChannelInterceptor authorizationChannelInterceptor = new AuthorizationChannelInterceptor(
-			ANY_MESSAGE_AUTHENTICATED);
-
-	private Consumer<List<ChannelInterceptor>> interceptorsCustomizer = (interceptors) -> {
-	};
-
-	private ApplicationContext context;
-
-	private AbstractSecurityWebSocketMessageBrokerConfigurer configurer;
-
-	WebSocketMessageBrokerSecurityConfiguration(ApplicationContext context) {
-		this.context = context;
-	}
-
-	@Override
-	public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
-		if (this.configurer != null) {
-			return;
-		}
-		argumentResolvers.add(new AuthenticationPrincipalArgumentResolver());
-	}
-
-	@Override
-	public void configureClientInboundChannel(ChannelRegistration registration) {
-		if (this.configurer != null) {
-			return;
-		}
-		this.authorizationChannelInterceptor
-				.setAuthorizationEventPublisher(new SpringAuthorizationEventPublisher(this.context));
-		List<ChannelInterceptor> interceptors = new ArrayList<>(Arrays.asList(this.securityContextChannelInterceptor,
-				this.csrfChannelInterceptor, this.authorizationChannelInterceptor));
-		this.interceptorsCustomizer.accept(interceptors);
-		registration.interceptors(interceptors.toArray(new ChannelInterceptor[0]));
-	}
-
-	@Autowired(required = false)
-	void setSecurityContextChannelInterceptor(SecurityContextChannelInterceptor interceptor) {
-		this.securityContextChannelInterceptor = interceptor;
-	}
-
-	@Autowired(required = false)
-	void setCsrfChannelInterceptor(CsrfChannelInterceptor csrfChannelInterceptor) {
-		this.csrfChannelInterceptor = csrfChannelInterceptor;
-	}
-
-	@Autowired(required = false)
-	void setAuthorizationManager(AuthorizationManager<Message<?>> authorizationManager) {
-		this.authorizationChannelInterceptor = new AuthorizationChannelInterceptor(authorizationManager);
-	}
-
-	@Autowired(required = false)
-	void setInterceptorsCustomizer(Consumer<List<ChannelInterceptor>> interceptorsCustomizer) {
-		this.interceptorsCustomizer = interceptorsCustomizer;
-	}
-
-	@Autowired(required = false)
-	@Deprecated
-	void setAbstractSecurityWebSocketMessageBrokerConfigurer(
-			AbstractSecurityWebSocketMessageBrokerConfigurer configurer) {
-		this.configurer = configurer;
-	}
-
-	@Override
-	public void afterSingletonsInstantiated() {
-		if (this.configurer != null) {
-			return;
-		}
-		SimpleUrlHandlerMapping mapping = getBeanOrNull(SIMPLE_URL_HANDLER_MAPPING_BEAN_NAME,
-				SimpleUrlHandlerMapping.class);
-		if (mapping == null) {
-			return;
-		}
-		configureCsrf(mapping);
-	}
-
-	private <T> T getBeanOrNull(String name, Class<T> type) {
-		Map<String, T> beans = this.context.getBeansOfType(type);
-		return beans.get(name);
-	}
-
-	private void configureCsrf(SimpleUrlHandlerMapping mapping) {
-		Map<String, Object> mappings = mapping.getHandlerMap();
-		for (Object object : mappings.values()) {
-			if (object instanceof SockJsHttpRequestHandler) {
-				setHandshakeInterceptors((SockJsHttpRequestHandler) object);
-			}
-			else if (object instanceof WebSocketHttpRequestHandler) {
-				setHandshakeInterceptors((WebSocketHttpRequestHandler) object);
-			}
-			else {
-				throw new IllegalStateException(
-						"Bean " + SIMPLE_URL_HANDLER_MAPPING_BEAN_NAME + " is expected to contain mappings to either a "
-								+ "SockJsHttpRequestHandler or a WebSocketHttpRequestHandler but got " + object);
-			}
-		}
-	}
-
-	private void setHandshakeInterceptors(SockJsHttpRequestHandler handler) {
-		SockJsService sockJsService = handler.getSockJsService();
-		Assert.state(sockJsService instanceof TransportHandlingSockJsService,
-				() -> "sockJsService must be instance of TransportHandlingSockJsService got " + sockJsService);
-		TransportHandlingSockJsService transportHandlingSockJsService = (TransportHandlingSockJsService) sockJsService;
-		List<HandshakeInterceptor> handshakeInterceptors = transportHandlingSockJsService.getHandshakeInterceptors();
-		List<HandshakeInterceptor> interceptorsToSet = new ArrayList<>(handshakeInterceptors.size() + 1);
-		interceptorsToSet.add(new CsrfTokenHandshakeInterceptor());
-		interceptorsToSet.addAll(handshakeInterceptors);
-		transportHandlingSockJsService.setHandshakeInterceptors(interceptorsToSet);
-	}
-
-	private void setHandshakeInterceptors(WebSocketHttpRequestHandler handler) {
-		List<HandshakeInterceptor> handshakeInterceptors = handler.getHandshakeInterceptors();
-		List<HandshakeInterceptor> interceptorsToSet = new ArrayList<>(handshakeInterceptors.size() + 1);
-		interceptorsToSet.add(new CsrfTokenHandshakeInterceptor());
-		interceptorsToSet.addAll(handshakeInterceptors);
-		handler.setHandshakeInterceptors(interceptorsToSet);
-	}
-
-}

+ 0 - 176
config/src/test/java/org/springframework/security/config/annotation/web/socket/WebSocketMessageBrokerSecurityConfigurationDocTests.java

@@ -1,176 +0,0 @@
-/*
- * Copyright 2002-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.config.annotation.web.socket;
-
-import java.util.HashMap;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.messaging.Message;
-import org.springframework.messaging.MessageChannel;
-import org.springframework.messaging.MessageDeliveryException;
-import org.springframework.messaging.handler.annotation.MessageMapping;
-import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
-import org.springframework.messaging.simp.SimpMessageType;
-import org.springframework.messaging.simp.config.MessageBrokerRegistry;
-import org.springframework.messaging.support.GenericMessage;
-import org.springframework.mock.web.MockServletConfig;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.authentication.TestingAuthenticationToken;
-import org.springframework.security.authorization.AuthorizationManager;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.messaging.AuthorizationManagerMessageMatcherRegistry;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.security.web.csrf.CsrfToken;
-import org.springframework.security.web.csrf.DefaultCsrfToken;
-import org.springframework.stereotype.Controller;
-import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
-import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
-import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
-import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
-
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-
-public class WebSocketMessageBrokerSecurityConfigurationDocTests {
-
-	AnnotationConfigWebApplicationContext context;
-
-	TestingAuthenticationToken messageUser;
-
-	CsrfToken token;
-
-	String sessionAttr;
-
-	@BeforeEach
-	public void setup() {
-		this.token = new DefaultCsrfToken("header", "param", "token");
-		this.sessionAttr = "sessionAttr";
-		this.messageUser = new TestingAuthenticationToken("user", "pass", "ROLE_USER");
-	}
-
-	@AfterEach
-	public void cleanup() {
-		if (this.context != null) {
-			this.context.close();
-		}
-	}
-
-	@Test
-	public void securityMappings() {
-		loadConfig(WebSocketSecurityConfig.class);
-		clientInboundChannel().send(message("/user/queue/errors", SimpMessageType.SUBSCRIBE));
-		assertThatExceptionOfType(MessageDeliveryException.class)
-				.isThrownBy(() -> clientInboundChannel().send(message("/denyAll", SimpMessageType.MESSAGE)))
-				.withCauseInstanceOf(AccessDeniedException.class);
-	}
-
-	private void loadConfig(Class<?>... configs) {
-		this.context = new AnnotationConfigWebApplicationContext();
-		this.context.register(configs);
-		this.context.register(WebSocketConfig.class, SyncExecutorConfig.class);
-		this.context.setServletConfig(new MockServletConfig());
-		this.context.refresh();
-	}
-
-	private MessageChannel clientInboundChannel() {
-		return this.context.getBean("clientInboundChannel", MessageChannel.class);
-	}
-
-	private Message<String> message(String destination, SimpMessageType type) {
-		SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(type);
-		return message(headers, destination);
-	}
-
-	private Message<String> message(SimpMessageHeaderAccessor headers, String destination) {
-		headers.setSessionId("123");
-		headers.setSessionAttributes(new HashMap<>());
-		if (destination != null) {
-			headers.setDestination(destination);
-		}
-		if (this.messageUser != null) {
-			headers.setUser(this.messageUser);
-		}
-		return new GenericMessage<>("hi", headers.getMessageHeaders());
-	}
-
-	@Controller
-	static class MyController {
-
-		@MessageMapping("/authentication")
-		void authentication(@AuthenticationPrincipal String un) {
-			// ... do something ...
-		}
-
-	}
-
-	@Configuration
-	@EnableWebSecurity
-	static class WebSocketSecurityConfig {
-
-		@Bean
-		AuthorizationManager<Message<?>> authorizationManager(AuthorizationManagerMessageMatcherRegistry messages) {
-			messages.nullDestMatcher().authenticated()
-					// <1>
-					.simpSubscribeDestMatchers("/user/queue/errors").permitAll()
-					// <2>
-					.simpDestMatchers("/app/**").hasRole("USER")
-					// <3>
-					.simpSubscribeDestMatchers("/user/**", "/topic/friends/*").hasRole("USER") // <4>
-					.simpTypeMatchers(SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE).denyAll() // <5>
-					.anyMessage().denyAll(); // <6>
-			return messages.build();
-		}
-
-	}
-
-	@Configuration
-	@EnableWebSocketMessageBroker
-	static class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
-
-		@Override
-		public void registerStompEndpoints(StompEndpointRegistry registry) {
-			registry.addEndpoint("/chat").withSockJS();
-		}
-
-		@Override
-		public void configureMessageBroker(MessageBrokerRegistry registry) {
-			registry.enableSimpleBroker("/queue/", "/topic/");
-			registry.setApplicationDestinationPrefixes("/permitAll", "/denyAll");
-		}
-
-		@Bean
-		MyController myController() {
-			return new MyController();
-		}
-
-	}
-
-	@Configuration
-	static class SyncExecutorConfig {
-
-		@Bean
-		static SyncExecutorSubscribableChannelPostProcessor postProcessor() {
-			return new SyncExecutorSubscribableChannelPostProcessor();
-		}
-
-	}
-
-}

+ 0 - 796
config/src/test/java/org/springframework/security/config/annotation/web/socket/WebSocketMessageBrokerSecurityConfigurationTests.java

@@ -1,796 +0,0 @@
-/*
- * Copyright 2002-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.config.annotation.web.socket;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
-import org.springframework.core.MethodParameter;
-import org.springframework.http.server.ServerHttpRequest;
-import org.springframework.http.server.ServerHttpResponse;
-import org.springframework.messaging.Message;
-import org.springframework.messaging.MessageChannel;
-import org.springframework.messaging.MessageDeliveryException;
-import org.springframework.messaging.handler.annotation.MessageMapping;
-import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver;
-import org.springframework.messaging.simp.SimpMessageHeaderAccessor;
-import org.springframework.messaging.simp.SimpMessageType;
-import org.springframework.messaging.simp.config.MessageBrokerRegistry;
-import org.springframework.messaging.support.AbstractMessageChannel;
-import org.springframework.messaging.support.ChannelInterceptor;
-import org.springframework.messaging.support.GenericMessage;
-import org.springframework.mock.web.MockHttpServletRequest;
-import org.springframework.mock.web.MockHttpServletResponse;
-import org.springframework.mock.web.MockServletConfig;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.authentication.TestingAuthenticationToken;
-import org.springframework.security.authorization.AuthorizationDecision;
-import org.springframework.security.authorization.AuthorizationManager;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.messaging.AuthorizationManagerMessageMatcherRegistry;
-import org.springframework.security.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.annotation.AuthenticationPrincipal;
-import org.springframework.security.messaging.access.intercept.AuthorizationChannelInterceptor;
-import org.springframework.security.messaging.access.intercept.ChannelSecurityInterceptor;
-import org.springframework.security.messaging.access.intercept.MessageAuthorizationContext;
-import org.springframework.security.messaging.context.SecurityContextChannelInterceptor;
-import org.springframework.security.messaging.web.csrf.CsrfChannelInterceptor;
-import org.springframework.security.web.csrf.CsrfToken;
-import org.springframework.security.web.csrf.DefaultCsrfToken;
-import org.springframework.security.web.csrf.MissingCsrfTokenException;
-import org.springframework.stereotype.Controller;
-import org.springframework.test.util.ReflectionTestUtils;
-import org.springframework.util.AntPathMatcher;
-import org.springframework.web.HttpRequestHandler;
-import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
-import org.springframework.web.servlet.HandlerMapping;
-import org.springframework.web.socket.WebSocketHandler;
-import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
-import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
-import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
-import org.springframework.web.socket.server.HandshakeFailureException;
-import org.springframework.web.socket.server.HandshakeHandler;
-import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
-import org.springframework.web.socket.sockjs.transport.handler.SockJsWebSocketHandler;
-import org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.assertj.core.api.Assertions.fail;
-
-public class WebSocketMessageBrokerSecurityConfigurationTests {
-
-	AnnotationConfigWebApplicationContext context;
-
-	TestingAuthenticationToken messageUser;
-
-	CsrfToken token;
-
-	String sessionAttr;
-
-	@BeforeEach
-	public void setup() {
-		this.token = new DefaultCsrfToken("header", "param", "token");
-		this.sessionAttr = "sessionAttr";
-		this.messageUser = new TestingAuthenticationToken("user", "pass", "ROLE_USER");
-	}
-
-	@AfterEach
-	public void cleanup() {
-		if (this.context != null) {
-			this.context.close();
-		}
-	}
-
-	@Test
-	public void simpleRegistryMappings() {
-		loadConfig(SockJsSecurityConfig.class);
-		clientInboundChannel().send(message("/permitAll"));
-		assertThatExceptionOfType(MessageDeliveryException.class)
-				.isThrownBy(() -> clientInboundChannel().send(message("/denyAll")))
-				.withCauseInstanceOf(AccessDeniedException.class);
-	}
-
-	@Test
-	public void annonymousSupported() {
-		loadConfig(SockJsSecurityConfig.class);
-		this.messageUser = null;
-		clientInboundChannel().send(message("/permitAll"));
-	}
-
-	// gh-3797
-	@Test
-	public void beanResolver() {
-		loadConfig(SockJsSecurityConfig.class);
-		this.messageUser = null;
-		clientInboundChannel().send(message("/beanResolver"));
-	}
-
-	@Test
-	public void addsAuthenticationPrincipalResolver() {
-		loadConfig(SockJsSecurityConfig.class);
-		MessageChannel messageChannel = clientInboundChannel();
-		Message<String> message = message("/permitAll/authentication");
-		messageChannel.send(message);
-		assertThat(this.context.getBean(MyController.class).authenticationPrincipal)
-				.isEqualTo((String) this.messageUser.getPrincipal());
-	}
-
-	@Test
-	public void addsAuthenticationPrincipalResolverWhenNoAuthorization() {
-		loadConfig(NoInboundSecurityConfig.class);
-		MessageChannel messageChannel = clientInboundChannel();
-		Message<String> message = message("/permitAll/authentication");
-		messageChannel.send(message);
-		assertThat(this.context.getBean(MyController.class).authenticationPrincipal)
-				.isEqualTo((String) this.messageUser.getPrincipal());
-	}
-
-	@Test
-	public void addsCsrfProtectionWhenNoAuthorization() {
-		loadConfig(NoInboundSecurityConfig.class);
-		SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.CONNECT);
-		Message<?> message = message(headers, "/authentication");
-		MessageChannel messageChannel = clientInboundChannel();
-		assertThatExceptionOfType(MessageDeliveryException.class).isThrownBy(() -> messageChannel.send(message))
-				.withCauseInstanceOf(MissingCsrfTokenException.class);
-	}
-
-	@Test
-	public void csrfProtectionForConnect() {
-		loadConfig(SockJsSecurityConfig.class);
-		SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.CONNECT);
-		Message<?> message = message(headers, "/authentication");
-		MessageChannel messageChannel = clientInboundChannel();
-		assertThatExceptionOfType(MessageDeliveryException.class).isThrownBy(() -> messageChannel.send(message))
-				.withCauseInstanceOf(MissingCsrfTokenException.class);
-	}
-
-	@Test
-	public void csrfProtectionDisabledForConnect() {
-		loadConfig(CsrfDisabledSockJsSecurityConfig.class);
-		SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.CONNECT);
-		Message<?> message = message(headers, "/permitAll/connect");
-		MessageChannel messageChannel = clientInboundChannel();
-		messageChannel.send(message);
-	}
-
-	@Test
-	public void csrfProtectionDefinedByBean() {
-		loadConfig(SockJsProxylessSecurityConfig.class);
-		MessageChannel messageChannel = clientInboundChannel();
-		Stream<Class<? extends ChannelInterceptor>> interceptors = ((AbstractMessageChannel) messageChannel)
-				.getInterceptors().stream().map(ChannelInterceptor::getClass);
-		assertThat(interceptors).contains(CsrfChannelInterceptor.class);
-	}
-
-	@Test
-	public void messagesConnectUseCsrfTokenHandshakeInterceptor() throws Exception {
-		loadConfig(SockJsSecurityConfig.class);
-		SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.CONNECT);
-		Message<?> message = message(headers, "/authentication");
-		MockHttpServletRequest request = sockjsHttpRequest("/chat");
-		HttpRequestHandler handler = handler(request);
-		handler.handleRequest(request, new MockHttpServletResponse());
-		assertHandshake(request);
-	}
-
-	@Test
-	public void messagesConnectUseCsrfTokenHandshakeInterceptorMultipleMappings() throws Exception {
-		loadConfig(SockJsSecurityConfig.class);
-		SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.CONNECT);
-		Message<?> message = message(headers, "/authentication");
-		MockHttpServletRequest request = sockjsHttpRequest("/other");
-		HttpRequestHandler handler = handler(request);
-		handler.handleRequest(request, new MockHttpServletResponse());
-		assertHandshake(request);
-	}
-
-	@Test
-	public void messagesConnectWebSocketUseCsrfTokenHandshakeInterceptor() throws Exception {
-		loadConfig(WebSocketSecurityConfig.class);
-		SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(SimpMessageType.CONNECT);
-		Message<?> message = message(headers, "/authentication");
-		MockHttpServletRequest request = websocketHttpRequest("/websocket");
-		HttpRequestHandler handler = handler(request);
-		handler.handleRequest(request, new MockHttpServletResponse());
-		assertHandshake(request);
-	}
-
-	@Test
-	public void msmsRegistryCustomPatternMatcher() {
-		loadConfig(MsmsRegistryCustomPatternMatcherConfig.class);
-		clientInboundChannel().send(message("/app/a.b"));
-		assertThatExceptionOfType(MessageDeliveryException.class)
-				.isThrownBy(() -> clientInboundChannel().send(message("/app/a.b.c")))
-				.withCauseInstanceOf(AccessDeniedException.class);
-	}
-
-	@Test
-	public void overrideMsmsRegistryCustomPatternMatcher() {
-		loadConfig(OverrideMsmsRegistryCustomPatternMatcherConfig.class);
-		clientInboundChannel().send(message("/app/a/b"));
-		assertThatExceptionOfType(MessageDeliveryException.class)
-				.isThrownBy(() -> clientInboundChannel().send(message("/app/a/b/c")))
-				.withCauseInstanceOf(AccessDeniedException.class);
-	}
-
-	@Test
-	public void defaultPatternMatcher() {
-		loadConfig(DefaultPatternMatcherConfig.class);
-		clientInboundChannel().send(message("/app/a/b"));
-		assertThatExceptionOfType(MessageDeliveryException.class)
-				.isThrownBy(() -> clientInboundChannel().send(message("/app/a/b/c")))
-				.withCauseInstanceOf(AccessDeniedException.class);
-	}
-
-	@Test
-	public void customExpression() {
-		loadConfig(CustomExpressionConfig.class);
-		clientInboundChannel().send(message("/denyRob"));
-		this.messageUser = new TestingAuthenticationToken("rob", "password", "ROLE_USER");
-		assertThatExceptionOfType(MessageDeliveryException.class)
-				.isThrownBy(() -> clientInboundChannel().send(message("/denyRob")))
-				.withCauseInstanceOf(AccessDeniedException.class);
-	}
-
-	@Test
-	public void channelSecurityInterceptorUsesMetadataSourceBeanWhenProxyingDisabled() {
-		loadConfig(SockJsProxylessSecurityConfig.class);
-		AbstractMessageChannel messageChannel = clientInboundChannel();
-		AuthorizationManager<Message<?>> authorizationManager = this.context.getBean(AuthorizationManager.class);
-		for (ChannelInterceptor interceptor : messageChannel.getInterceptors()) {
-			if (interceptor instanceof AuthorizationChannelInterceptor) {
-				assertThat(ReflectionTestUtils.getField(interceptor, "preSendAuthorizationManager"))
-						.isSameAs(authorizationManager);
-				return;
-			}
-		}
-		fail("did not find AuthorizationChannelInterceptor");
-	}
-
-	@Test
-	public void securityContextChannelInterceptorDefinedByBean() {
-		loadConfig(SockJsProxylessSecurityConfig.class);
-		MessageChannel messageChannel = clientInboundChannel();
-		Stream<Class<? extends ChannelInterceptor>> interceptors = ((AbstractMessageChannel) messageChannel)
-				.getInterceptors().stream().map(ChannelInterceptor::getClass);
-		assertThat(interceptors).contains(SecurityContextChannelInterceptor.class);
-	}
-
-	@Test
-	public void inboundChannelSecurityDefinedByBean() {
-		loadConfig(SockJsProxylessSecurityConfig.class);
-		MessageChannel messageChannel = clientInboundChannel();
-		Stream<Class<? extends ChannelInterceptor>> interceptors = ((AbstractMessageChannel) messageChannel)
-				.getInterceptors().stream().map(ChannelInterceptor::getClass);
-		assertThat(interceptors).contains(AuthorizationChannelInterceptor.class);
-	}
-
-	@Test
-	public void usingLegacyThenNewFiltersNotUsed() {
-		loadConfig(UsingLegacyConfigurerConfig.class);
-		AbstractMessageChannel messageChannel = clientInboundChannel();
-		List<Class<? extends ChannelInterceptor>> interceptors = messageChannel.getInterceptors().stream()
-				.map(ChannelInterceptor::getClass).collect(Collectors.toList());
-		assertThat(interceptors).contains(ChannelSecurityInterceptor.class);
-		assertThat(interceptors).doesNotContain(AuthorizationChannelInterceptor.class);
-	}
-
-	private void assertHandshake(HttpServletRequest request) {
-		TestHandshakeHandler handshakeHandler = this.context.getBean(TestHandshakeHandler.class);
-		assertThat(handshakeHandler.attributes.get(CsrfToken.class.getName())).isSameAs(this.token);
-		assertThat(handshakeHandler.attributes.get(this.sessionAttr))
-				.isEqualTo(request.getSession().getAttribute(this.sessionAttr));
-	}
-
-	private HttpRequestHandler handler(HttpServletRequest request) throws Exception {
-		HandlerMapping handlerMapping = this.context.getBean(HandlerMapping.class);
-		return (HttpRequestHandler) handlerMapping.getHandler(request).getHandler();
-	}
-
-	private MockHttpServletRequest websocketHttpRequest(String mapping) {
-		MockHttpServletRequest request = sockjsHttpRequest(mapping);
-		request.setRequestURI(mapping);
-		return request;
-	}
-
-	private MockHttpServletRequest sockjsHttpRequest(String mapping) {
-		MockHttpServletRequest request = new MockHttpServletRequest("GET", "");
-		request.setMethod("GET");
-		request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/289/tpyx6mde/websocket");
-		request.setRequestURI(mapping + "/289/tpyx6mde/websocket");
-		request.getSession().setAttribute(this.sessionAttr, "sessionValue");
-		request.setAttribute(CsrfToken.class.getName(), this.token);
-		return request;
-	}
-
-	private Message<String> message(String destination) {
-		SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create();
-		return message(headers, destination);
-	}
-
-	private Message<String> message(SimpMessageHeaderAccessor headers, String destination) {
-		headers.setSessionId("123");
-		headers.setSessionAttributes(new HashMap<>());
-		if (destination != null) {
-			headers.setDestination(destination);
-		}
-		if (this.messageUser != null) {
-			headers.setUser(this.messageUser);
-		}
-		return new GenericMessage<>("hi", headers.getMessageHeaders());
-	}
-
-	private <T extends MessageChannel> T clientInboundChannel() {
-		return (T) this.context.getBean("clientInboundChannel", MessageChannel.class);
-	}
-
-	private void loadConfig(Class<?>... configs) {
-		this.context = new AnnotationConfigWebApplicationContext();
-		this.context.register(configs);
-		this.context.setServletConfig(new MockServletConfig());
-		this.context.refresh();
-	}
-
-	@Configuration
-	@EnableWebSocketMessageBroker
-	@EnableWebSecurity
-	@Import(SyncExecutorConfig.class)
-	static class MsmsRegistryCustomPatternMatcherConfig implements WebSocketMessageBrokerConfigurer {
-
-		// @formatter:off
-		@Override
-		public void registerStompEndpoints(StompEndpointRegistry registry) {
-			registry
-				.addEndpoint("/other")
-				.setHandshakeHandler(testHandshakeHandler());
-		}
-		// @formatter:on
-
-		@Override
-		public void configureMessageBroker(MessageBrokerRegistry registry) {
-			registry.setPathMatcher(new AntPathMatcher("."));
-			registry.enableSimpleBroker("/queue/", "/topic/");
-			registry.setApplicationDestinationPrefixes("/app");
-		}
-
-		// @formatter:off
-		@Bean
-		AuthorizationManager<Message<?>> authorizationManager(AuthorizationManagerMessageMatcherRegistry messages) {
-			messages
-					.simpDestMatchers("/app/a.*").permitAll()
-					.anyMessage().denyAll();
-
-			return messages.build();
-		}
-		// @formatter:on
-
-		@Bean
-		TestHandshakeHandler testHandshakeHandler() {
-			return new TestHandshakeHandler();
-		}
-
-	}
-
-	@Configuration
-	@EnableWebSocketMessageBroker
-	@EnableWebSecurity
-	@Import(SyncExecutorConfig.class)
-	static class OverrideMsmsRegistryCustomPatternMatcherConfig implements WebSocketMessageBrokerConfigurer {
-
-		// @formatter:off
-		@Override
-		public void registerStompEndpoints(StompEndpointRegistry registry) {
-			registry
-				.addEndpoint("/other")
-				.setHandshakeHandler(testHandshakeHandler());
-		}
-		// @formatter:on
-
-		@Override
-		public void configureMessageBroker(MessageBrokerRegistry registry) {
-			registry.setPathMatcher(new AntPathMatcher("."));
-			registry.enableSimpleBroker("/queue/", "/topic/");
-			registry.setApplicationDestinationPrefixes("/app");
-		}
-
-		// @formatter:off
-		@Bean
-		AuthorizationManager<Message<?>> authorizationManager(AuthorizationManagerMessageMatcherRegistry messages) {
-			messages
-					.simpDestPathMatcher(new AntPathMatcher())
-					.simpDestMatchers("/app/a/*").permitAll()
-					.anyMessage().denyAll();
-			return messages.build();
-		}
-		// @formatter:on
-
-		@Bean
-		TestHandshakeHandler testHandshakeHandler() {
-			return new TestHandshakeHandler();
-		}
-
-	}
-
-	@Configuration
-	@EnableWebSocketMessageBroker
-	@EnableWebSecurity
-	@Import(SyncExecutorConfig.class)
-	static class DefaultPatternMatcherConfig implements WebSocketMessageBrokerConfigurer {
-
-		// @formatter:off
-		@Override
-		public void registerStompEndpoints(StompEndpointRegistry registry) {
-			registry
-				.addEndpoint("/other")
-				.setHandshakeHandler(testHandshakeHandler());
-		}
-		// @formatter:on
-
-		@Override
-		public void configureMessageBroker(MessageBrokerRegistry registry) {
-			registry.enableSimpleBroker("/queue/", "/topic/");
-			registry.setApplicationDestinationPrefixes("/app");
-		}
-
-		// @formatter:off
-		@Bean
-		AuthorizationManager<Message<?>> authorizationManager(AuthorizationManagerMessageMatcherRegistry messages) {
-			messages
-					.simpDestMatchers("/app/a/*").permitAll()
-					.anyMessage().denyAll();
-
-			return messages.build();
-		}
-		// @formatter:on
-
-		@Bean
-		TestHandshakeHandler testHandshakeHandler() {
-			return new TestHandshakeHandler();
-		}
-
-	}
-
-	@Configuration
-	@EnableWebSocketMessageBroker
-	@EnableWebSecurity
-	@Import(SyncExecutorConfig.class)
-	static class CustomExpressionConfig implements WebSocketMessageBrokerConfigurer {
-
-		// @formatter:off
-		@Override
-		public void registerStompEndpoints(StompEndpointRegistry registry) {
-			registry
-				.addEndpoint("/other")
-				.setHandshakeHandler(testHandshakeHandler());
-		}
-		// @formatter:on
-
-		@Override
-		public void configureMessageBroker(MessageBrokerRegistry registry) {
-			registry.enableSimpleBroker("/queue/", "/topic/");
-			registry.setApplicationDestinationPrefixes("/app");
-		}
-
-		@Bean
-		AuthorizationManager<Message<Object>> authorizationManager() {
-			return (authentication, message) -> {
-				Authentication auth = authentication.get();
-				return new AuthorizationDecision(auth != null && !"rob".equals(auth.getName()));
-			};
-		}
-
-		@Bean
-		TestHandshakeHandler testHandshakeHandler() {
-			return new TestHandshakeHandler();
-		}
-
-	}
-
-	@Controller
-	static class MyController {
-
-		String authenticationPrincipal;
-
-		MyCustomArgument myCustomArgument;
-
-		@MessageMapping("/authentication")
-		void authentication(@AuthenticationPrincipal String un) {
-			this.authenticationPrincipal = un;
-		}
-
-		@MessageMapping("/myCustom")
-		void myCustom(MyCustomArgument myCustomArgument) {
-			this.myCustomArgument = myCustomArgument;
-		}
-
-	}
-
-	static class MyCustomArgument {
-
-		MyCustomArgument(String notDefaultConstr) {
-		}
-
-	}
-
-	static class MyCustomArgumentResolver implements HandlerMethodArgumentResolver {
-
-		@Override
-		public boolean supportsParameter(MethodParameter parameter) {
-			return parameter.getParameterType().isAssignableFrom(MyCustomArgument.class);
-		}
-
-		@Override
-		public Object resolveArgument(MethodParameter parameter, Message<?> message) {
-			return new MyCustomArgument("");
-		}
-
-	}
-
-	static class TestHandshakeHandler implements HandshakeHandler {
-
-		Map<String, Object> attributes;
-
-		@Override
-		public boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
-				Map<String, Object> attributes) throws HandshakeFailureException {
-			this.attributes = attributes;
-			if (wsHandler instanceof SockJsWebSocketHandler) {
-				// work around SPR-12716
-				SockJsWebSocketHandler sockJs = (SockJsWebSocketHandler) wsHandler;
-				WebSocketServerSockJsSession session = (WebSocketServerSockJsSession) ReflectionTestUtils
-						.getField(sockJs, "sockJsSession");
-				this.attributes = session.getAttributes();
-			}
-			return true;
-		}
-
-	}
-
-	@Configuration
-	@EnableWebSecurity
-	@EnableWebSocketMessageBroker
-	@Import(SyncExecutorConfig.class)
-	static class SockJsSecurityConfig implements WebSocketMessageBrokerConfigurer {
-
-		@Override
-		public void registerStompEndpoints(StompEndpointRegistry registry) {
-			// @formatter:off
-			registry.addEndpoint("/other").setHandshakeHandler(testHandshakeHandler())
-					.withSockJS().setInterceptors(new HttpSessionHandshakeInterceptor());
-			registry.addEndpoint("/chat").setHandshakeHandler(testHandshakeHandler())
-					.withSockJS().setInterceptors(new HttpSessionHandshakeInterceptor());
-			// @formatter:on
-		}
-
-		// @formatter:off
-		@Bean
-		AuthorizationManager<Message<?>> authorizationManager(AuthorizationManagerMessageMatcherRegistry messages,
-				SecurityCheck security) {
-			AuthorizationManager<MessageAuthorizationContext<?>> beanResolver =
-					(authentication, context) -> new AuthorizationDecision(security.check());
-			messages
-				.simpDestMatchers("/permitAll/**").permitAll()
-				.simpDestMatchers("/beanResolver/**").access(beanResolver)
-				.anyMessage().denyAll();
-			return messages.build();
-		}
-		// @formatter:on
-
-		@Override
-		public void configureMessageBroker(MessageBrokerRegistry registry) {
-			registry.enableSimpleBroker("/queue/", "/topic/");
-			registry.setApplicationDestinationPrefixes("/permitAll", "/denyAll");
-		}
-
-		@Bean
-		MyController myController() {
-			return new MyController();
-		}
-
-		@Bean
-		TestHandshakeHandler testHandshakeHandler() {
-			return new TestHandshakeHandler();
-		}
-
-		@Bean
-		SecurityCheck security() {
-			return new SecurityCheck();
-		}
-
-		static class SecurityCheck {
-
-			private boolean check;
-
-			boolean check() {
-				this.check = !this.check;
-				return this.check;
-			}
-
-		}
-
-	}
-
-	@Configuration
-	@EnableWebSecurity
-	@EnableWebSocketMessageBroker
-	@Import(SyncExecutorConfig.class)
-	static class NoInboundSecurityConfig implements WebSocketMessageBrokerConfigurer {
-
-		@Override
-		public void registerStompEndpoints(StompEndpointRegistry registry) {
-			// @formatter:off
-			registry.addEndpoint("/other")
-					.withSockJS().setInterceptors(new HttpSessionHandshakeInterceptor());
-			registry.addEndpoint("/chat")
-					.withSockJS().setInterceptors(new HttpSessionHandshakeInterceptor());
-			// @formatter:on
-		}
-
-		@Override
-		public void configureMessageBroker(MessageBrokerRegistry registry) {
-			registry.enableSimpleBroker("/queue/", "/topic/");
-			registry.setApplicationDestinationPrefixes("/permitAll", "/denyAll");
-		}
-
-		@Bean
-		MyController myController() {
-			return new MyController();
-		}
-
-	}
-
-	@Configuration
-	@Import(SockJsSecurityConfig.class)
-	static class CsrfDisabledSockJsSecurityConfig {
-
-		@Bean
-		Consumer<List<ChannelInterceptor>> channelInterceptorCustomizer() {
-			return (interceptors) -> interceptors.remove(1);
-		}
-
-	}
-
-	@Configuration
-	@EnableWebSecurity
-	@EnableWebSocketMessageBroker
-	@Import(SyncExecutorConfig.class)
-	static class WebSocketSecurityConfig implements WebSocketMessageBrokerConfigurer {
-
-		@Override
-		public void registerStompEndpoints(StompEndpointRegistry registry) {
-			// @formatter:off
-			registry.addEndpoint("/websocket")
-					.setHandshakeHandler(testHandshakeHandler())
-					.addInterceptors(new HttpSessionHandshakeInterceptor());
-			// @formatter:on
-		}
-
-		@Bean
-		AuthorizationManager<Message<?>> authorizationManager(AuthorizationManagerMessageMatcherRegistry messages) {
-			// @formatter:off
-			messages
-				.simpDestMatchers("/permitAll/**").permitAll()
-				.anyMessage().denyAll();
-			// @formatter:on
-			return messages.build();
-		}
-
-		@Bean
-		TestHandshakeHandler testHandshakeHandler() {
-			return new TestHandshakeHandler();
-		}
-
-	}
-
-	@Configuration
-	@EnableWebSecurity
-	@EnableWebSocketMessageBroker
-	@Import(SyncExecutorConfig.class)
-	static class UsingLegacyConfigurerConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
-
-		@Override
-		public void registerStompEndpoints(StompEndpointRegistry registry) {
-			// @formatter:off
-			registry.addEndpoint("/websocket")
-					.setHandshakeHandler(testHandshakeHandler())
-					.addInterceptors(new HttpSessionHandshakeInterceptor());
-			// @formatter:on
-		}
-
-		@Override
-		public void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
-			// @formatter:off
-			messages
-					.simpDestMatchers("/permitAll/**").permitAll()
-					.anyMessage().denyAll();
-			// @formatter:on
-		}
-
-		@Bean
-		TestHandshakeHandler testHandshakeHandler() {
-			return new TestHandshakeHandler();
-		}
-
-	}
-
-	@Configuration(proxyBeanMethods = false)
-	@EnableWebSecurity
-	@EnableWebSocketMessageBroker
-	@Import(SyncExecutorConfig.class)
-	static class SockJsProxylessSecurityConfig implements WebSocketMessageBrokerConfigurer {
-
-		private ApplicationContext context;
-
-		@Override
-		public void registerStompEndpoints(StompEndpointRegistry registry) {
-			// @formatter:off
-			registry.addEndpoint("/chat")
-					.setHandshakeHandler(this.context.getBean(TestHandshakeHandler.class))
-					.withSockJS().setInterceptors(new HttpSessionHandshakeInterceptor());
-			// @formatter:on
-		}
-
-		@Autowired
-		void setContext(ApplicationContext context) {
-			this.context = context;
-		}
-
-		// @formatter:off
-		@Bean
-		AuthorizationManager<Message<?>> authorizationManager(AuthorizationManagerMessageMatcherRegistry messages) {
-			messages
-					.anyMessage().denyAll();
-			return messages.build();
-		}
-		// @formatter:on
-
-		@Bean
-		TestHandshakeHandler testHandshakeHandler() {
-			return new TestHandshakeHandler();
-		}
-
-	}
-
-	@Configuration
-	static class SyncExecutorConfig {
-
-		@Bean
-		static SyncExecutorSubscribableChannelPostProcessor postProcessor() {
-			return new SyncExecutorSubscribableChannelPostProcessor();
-		}
-
-	}
-
-}

+ 1 - 4
messaging/src/main/java/org/springframework/security/messaging/access/expression/EvaluationContextPostProcessor.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,10 +27,7 @@ import org.springframework.expression.EvaluationContext;
  *
  * @author Daniel Bustamante Ospina
  * @since 5.2
- * @deprecated Since {@link MessageExpressionVoter} is deprecated, there is no more need
- * for this class
  */
-@Deprecated
 interface EvaluationContextPostProcessor<I> {
 
 	/**

+ 1 - 5
messaging/src/main/java/org/springframework/security/messaging/access/expression/ExpressionBasedMessageSecurityMetadataSourceFactory.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -35,11 +35,7 @@ import org.springframework.security.messaging.util.matcher.MessageMatcher;
  *
  * @author Rob Winch
  * @since 4.0
- * @deprecated Use
- * {@link org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager}
- * instead
  */
-@Deprecated
 public final class ExpressionBasedMessageSecurityMetadataSourceFactory {
 
 	private ExpressionBasedMessageSecurityMetadataSourceFactory() {

+ 1 - 5
messaging/src/main/java/org/springframework/security/messaging/access/expression/MessageExpressionConfigAttribute.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,11 +32,7 @@ import org.springframework.util.Assert;
  * @author Rob Winch
  * @author Daniel Bustamante Ospina
  * @since 4.0
- * @deprecated Use
- * {@link org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager}
- * instead
  */
-@Deprecated
 @SuppressWarnings("serial")
 class MessageExpressionConfigAttribute implements ConfigAttribute, EvaluationContextPostProcessor<Message<?>> {
 

+ 1 - 5
messaging/src/main/java/org/springframework/security/messaging/access/expression/MessageExpressionVoter.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2019 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -37,11 +37,7 @@ import org.springframework.util.Assert;
  * @author Rob Winch
  * @author Daniel Bustamante Ospina
  * @since 4.0
- * @deprecated Use
- * {@link org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager}
- * instead
  */
-@Deprecated
 public class MessageExpressionVoter<T> implements AccessDecisionVoter<Message<T>> {
 
 	private SecurityExpressionHandler<Message<T>> expressionHandler = new DefaultMessageSecurityExpressionHandler<>();

+ 0 - 95
messaging/src/main/java/org/springframework/security/messaging/access/intercept/AuthorizationChannelInterceptor.java

@@ -1,95 +0,0 @@
-/*
- * Copyright 2002-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.messaging.access.intercept;
-
-import java.util.function.Supplier;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.core.log.LogMessage;
-import org.springframework.messaging.Message;
-import org.springframework.messaging.MessageChannel;
-import org.springframework.messaging.support.ChannelInterceptor;
-import org.springframework.security.access.AccessDeniedException;
-import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
-import org.springframework.security.authorization.AuthorizationDecision;
-import org.springframework.security.authorization.AuthorizationEventPublisher;
-import org.springframework.security.authorization.AuthorizationManager;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.util.Assert;
-
-/**
- * Authorizes {@link Message} resources using the provided {@link AuthorizationManager}
- *
- * @author Josh Cummings
- * @since 5.7
- */
-public final class AuthorizationChannelInterceptor implements ChannelInterceptor {
-
-	static final Supplier<Authentication> AUTHENTICATION_SUPPLIER = () -> {
-		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
-		if (authentication == null) {
-			throw new AuthenticationCredentialsNotFoundException(
-					"An Authentication object was not found in the SecurityContext");
-		}
-		return authentication;
-	};
-
-	private final Log logger = LogFactory.getLog(this.getClass());
-
-	private final AuthorizationManager<Message<?>> preSendAuthorizationManager;
-
-	private AuthorizationEventPublisher eventPublisher;
-
-	/**
-	 * Creates a new instance
-	 * @param preSendAuthorizationManager the {@link AuthorizationManager} to use. Cannot
-	 * be null.
-	 *
-	 */
-	public AuthorizationChannelInterceptor(AuthorizationManager<Message<?>> preSendAuthorizationManager) {
-		Assert.notNull(preSendAuthorizationManager, "preSendAuthorizationManager cannot be null");
-		this.preSendAuthorizationManager = preSendAuthorizationManager;
-	}
-
-	@Override
-	public Message<?> preSend(Message<?> message, MessageChannel channel) {
-		this.logger.debug(LogMessage.of(() -> "Authorizing message send"));
-		AuthorizationDecision decision = this.preSendAuthorizationManager.check(AUTHENTICATION_SUPPLIER, message);
-		this.eventPublisher.publishAuthorizationEvent(AUTHENTICATION_SUPPLIER, message, decision);
-		if (decision == null || !decision.isGranted()) { // default deny
-			this.logger.debug(LogMessage.of(() -> "Failed to authorize message with authorization manager "
-					+ this.preSendAuthorizationManager + " and decision " + decision));
-			throw new AccessDeniedException("Access Denied");
-		}
-		this.logger.debug(LogMessage.of(() -> "Authorized message send"));
-		return message;
-	}
-
-	/**
-	 * Use this {@link AuthorizationEventPublisher} to publish the
-	 * {@link AuthorizationManager} result.
-	 * @param eventPublisher
-	 */
-	public void setAuthorizationEventPublisher(AuthorizationEventPublisher eventPublisher) {
-		Assert.notNull(eventPublisher, "eventPublisher cannot be null");
-		this.eventPublisher = eventPublisher;
-	}
-
-}

+ 1 - 3
messaging/src/main/java/org/springframework/security/messaging/access/intercept/ChannelSecurityInterceptor.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -36,9 +36,7 @@ import org.springframework.util.Assert;
  *
  * @author Rob Winch
  * @since 4.0
- * @deprecated Use {@link AuthorizationChannelInterceptor} instead
  */
-@Deprecated
 public final class ChannelSecurityInterceptor extends AbstractSecurityInterceptor implements ChannelInterceptor {
 
 	private static final ThreadLocal<InterceptorStatusToken> tokenHolder = new ThreadLocal<>();

+ 1 - 3
messaging/src/main/java/org/springframework/security/messaging/access/intercept/DefaultMessageSecurityMetadataSource.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,9 +40,7 @@ import org.springframework.security.messaging.util.matcher.MessageMatcher;
  * @since 4.0
  * @see ChannelSecurityInterceptor
  * @see ExpressionBasedMessageSecurityMetadataSourceFactory
- * @deprecated Use {@link MessageMatcherDelegatingAuthorizationManager} instead
  */
-@Deprecated
 public final class DefaultMessageSecurityMetadataSource implements MessageSecurityMetadataSource {
 
 	private final Map<MessageMatcher<?>, Collection<ConfigAttribute>> messageMap;

+ 0 - 75
messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageAuthorizationContext.java

@@ -1,75 +0,0 @@
-/*
- * Copyright 2002-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.messaging.access.intercept;
-
-import java.util.Collections;
-import java.util.Map;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.springframework.messaging.Message;
-
-/**
- * An {@link Message} authorization context.
- *
- * @author Josh Cummings
- * @since 5.7
- */
-public final class MessageAuthorizationContext<T> {
-
-	private final Message<T> message;
-
-	private final Map<String, String> variables;
-
-	/**
-	 * Creates an instance.
-	 * @param message the {@link HttpServletRequest} to use
-	 */
-	public MessageAuthorizationContext(Message<T> message) {
-		this(message, Collections.emptyMap());
-	}
-
-	/**
-	 * Creates an instance.
-	 * @param message the {@link HttpServletRequest} to use
-	 * @param variables a map containing key-value pairs representing extracted variable
-	 * names and variable values
-	 */
-	public MessageAuthorizationContext(Message<T> message, Map<String, String> variables) {
-		this.message = message;
-		this.variables = variables;
-	}
-
-	/**
-	 * Returns the {@link HttpServletRequest}.
-	 * @return the {@link HttpServletRequest} to use
-	 */
-	public Message<T> getMessage() {
-		return this.message;
-	}
-
-	/**
-	 * Returns the extracted variable values where the key is the variable name and the
-	 * value is the variable value.
-	 * @return a map containing key-value pairs representing extracted variable names and
-	 * variable values
-	 */
-	public Map<String, String> getVariables() {
-		return this.variables;
-	}
-
-}

+ 0 - 136
messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageMatcherDelegatingAuthorizationManager.java

@@ -1,136 +0,0 @@
-/*
- * Copyright 2002-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.messaging.access.intercept;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Supplier;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.core.log.LogMessage;
-import org.springframework.messaging.Message;
-import org.springframework.security.authorization.AuthorizationDecision;
-import org.springframework.security.authorization.AuthorizationManager;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.messaging.util.matcher.MessageMatcher;
-import org.springframework.security.messaging.util.matcher.MessageMatcherEntry;
-import org.springframework.security.messaging.util.matcher.SimpDestinationMessageMatcher;
-import org.springframework.util.Assert;
-
-/**
- * An {@link AuthorizationManager} which delegates to a specific
- * {@link AuthorizationManager} based on a {@link MessageMatcher} evaluation.
- *
- * @author Josh Cummings
- * @since 5.7
- */
-public final class MessageMatcherDelegatingAuthorizationManager implements AuthorizationManager<Message<?>> {
-
-	private final Log logger = LogFactory.getLog(getClass());
-
-	private final List<MessageMatcherEntry<AuthorizationManager<MessageAuthorizationContext<?>>>> mappings;
-
-	private MessageMatcherDelegatingAuthorizationManager(
-			List<MessageMatcherEntry<AuthorizationManager<MessageAuthorizationContext<?>>>> mappings) {
-		Assert.notEmpty(mappings, "mappings cannot be empty");
-		this.mappings = mappings;
-	}
-
-	/**
-	 * Delegates to a specific {@link AuthorizationManager} based on a
-	 * {@link MessageMatcher} evaluation.
-	 * @param authentication the {@link Supplier} of the {@link Authentication} to check
-	 * @param message the {@link Message} to check
-	 * @return an {@link AuthorizationDecision}. If there is no {@link MessageMatcher}
-	 * matching the message, or the {@link AuthorizationManager} could not decide, then
-	 * null is returned
-	 */
-	@Override
-	public AuthorizationDecision check(Supplier<Authentication> authentication, Message<?> message) {
-		if (this.logger.isTraceEnabled()) {
-			this.logger.trace(LogMessage.format("Authorizing message"));
-		}
-		for (MessageMatcherEntry<AuthorizationManager<MessageAuthorizationContext<?>>> mapping : this.mappings) {
-			MessageMatcher<?> matcher = mapping.getMessageMatcher();
-			MessageAuthorizationContext<?> authorizationContext = authorizationContext(matcher, message);
-			if (authorizationContext != null) {
-				AuthorizationManager<MessageAuthorizationContext<?>> manager = mapping.getEntry();
-				if (this.logger.isTraceEnabled()) {
-					this.logger.trace(LogMessage.format("Checking authorization on message using %s", manager));
-				}
-				return manager.check(authentication, authorizationContext);
-			}
-		}
-		this.logger.trace("Abstaining since did not find matching MessageMatcher");
-		return null;
-	}
-
-	private MessageAuthorizationContext<?> authorizationContext(MessageMatcher<?> matcher, Message<?> message) {
-		if (!matcher.matches((Message) message)) {
-			return null;
-		}
-		if (matcher instanceof SimpDestinationMessageMatcher) {
-			SimpDestinationMessageMatcher simp = (SimpDestinationMessageMatcher) matcher;
-			return new MessageAuthorizationContext<>(message, simp.extractPathVariables(message));
-		}
-		return new MessageAuthorizationContext<>(message);
-	}
-
-	/**
-	 * Creates a builder for {@link MessageMatcherDelegatingAuthorizationManager}.
-	 * @return the new {@link MessageMatcherDelegatingAuthorizationManager.Builder}
-	 * instance
-	 */
-	public static Builder builder() {
-		return new Builder();
-	}
-
-	/**
-	 * A builder for {@link MessageMatcherDelegatingAuthorizationManager}.
-	 */
-	public static final class Builder {
-
-		private final List<MessageMatcherEntry<AuthorizationManager<MessageAuthorizationContext<?>>>> mappings = new ArrayList<>();
-
-		/**
-		 * Maps a {@link MessageMatcher} to an {@link AuthorizationManager}.
-		 * @param matcher the {@link MessageMatcher} to use
-		 * @param manager the {@link AuthorizationManager} to use
-		 * @return the {@link MessageMatcherDelegatingAuthorizationManager.Builder} for
-		 * further customizations
-		 */
-		public MessageMatcherDelegatingAuthorizationManager.Builder add(MessageMatcher<?> matcher,
-				AuthorizationManager<MessageAuthorizationContext<?>> manager) {
-			Assert.notNull(matcher, "matcher cannot be null");
-			Assert.notNull(manager, "manager cannot be null");
-			this.mappings.add(new MessageMatcherEntry<>(matcher, manager));
-			return this;
-		}
-
-		/**
-		 * Creates a {@link MessageMatcherDelegatingAuthorizationManager} instance.
-		 * @return the {@link MessageMatcherDelegatingAuthorizationManager} instance
-		 */
-		public MessageMatcherDelegatingAuthorizationManager build() {
-			return new MessageMatcherDelegatingAuthorizationManager(this.mappings);
-		}
-
-	}
-
-}

+ 1 - 3
messaging/src/main/java/org/springframework/security/messaging/access/intercept/MessageSecurityMetadataSource.java

@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2022 the original author or authors.
+ * Copyright 2002-2016 the original author or authors.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,9 +26,7 @@ import org.springframework.security.access.SecurityMetadataSource;
  * @since 4.0
  * @see ChannelSecurityInterceptor
  * @see DefaultMessageSecurityMetadataSource
- * @deprecated Use {@link MessageMatcherDelegatingAuthorizationManager} instead
  */
-@Deprecated
 public interface MessageSecurityMetadataSource extends SecurityMetadataSource {
 
 }

+ 0 - 44
messaging/src/main/java/org/springframework/security/messaging/util/matcher/MessageMatcherEntry.java

@@ -1,44 +0,0 @@
-/*
- * Copyright 2002-2022 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.springframework.security.messaging.util.matcher;
-
-/**
- * A rich object for associating a {@link MessageMatcher} to another object.
- *
- * @author Josh Cummings
- * @since 5.7
- */
-public class MessageMatcherEntry<T> {
-
-	private final MessageMatcher<?> messageMatcher;
-
-	private final T entry;
-
-	public MessageMatcherEntry(MessageMatcher requestMatcher, T entry) {
-		this.messageMatcher = requestMatcher;
-		this.entry = entry;
-	}
-
-	public MessageMatcher<?> getMessageMatcher() {
-		return this.messageMatcher;
-	}
-
-	public T getEntry() {
-		return this.entry;
-	}
-
-}