diff --git a/config/src/main/java/org/springframework/security/config/annotation/web/socket/AbstractSecurityWebSocketMessageBrokerConfigurer.java b/config/src/main/java/org/springframework/security/config/annotation/web/socket/AbstractSecurityWebSocketMessageBrokerConfigurer.java
deleted file mode 100644
index cd2baed7335..00000000000
--- a/config/src/main/java/org/springframework/security/config/annotation/web/socket/AbstractSecurityWebSocketMessageBrokerConfigurer.java
+++ /dev/null
@@ -1,286 +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.List;
-import java.util.Map;
-
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.beans.factory.SmartInitializingSingleton;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-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.annotation.support.SimpAnnotationMethodMessageHandler;
-import org.springframework.messaging.simp.config.ChannelRegistration;
-import org.springframework.security.access.AccessDecisionVoter;
-import org.springframework.security.access.expression.SecurityExpressionHandler;
-import org.springframework.security.access.vote.AffirmativeBased;
-import org.springframework.security.config.ObjectPostProcessor;
-import org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration;
-import org.springframework.security.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry;
-import org.springframework.security.messaging.access.expression.DefaultMessageSecurityExpressionHandler;
-import org.springframework.security.messaging.access.expression.MessageExpressionVoter;
-import org.springframework.security.messaging.access.intercept.ChannelSecurityInterceptor;
-import org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource;
-import org.springframework.security.messaging.context.AuthenticationPrincipalArgumentResolver;
-import org.springframework.security.messaging.context.SecurityContextChannelInterceptor;
-import org.springframework.security.messaging.web.csrf.CsrfChannelInterceptor;
-import org.springframework.security.messaging.web.socket.server.CsrfTokenHandshakeInterceptor;
-import org.springframework.util.AntPathMatcher;
-import org.springframework.util.Assert;
-import org.springframework.util.PathMatcher;
-import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
-import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
-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.
- *
- *
- * For example:
- *
- *
- *
- * @Configuration
- * public class WebSocketSecurityConfig extends
- * AbstractSecurityWebSocketMessageBrokerConfigurer {
- *
- * @Override
- * protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
- * messages.simpDestMatchers("/user/queue/errors").permitAll()
- * .simpDestMatchers("/admin/**").hasRole("ADMIN").anyMessage()
- * .authenticated();
- * }
- * }
- *
- *
- * @author Rob Winch
- * @since 4.0
- * @see WebSocketMessageBrokerSecurityConfiguration
- * @deprecated Use {@link EnableWebSocketSecurity} instead
- */
-@Order(Ordered.HIGHEST_PRECEDENCE + 100)
-@Import(ObjectPostProcessorConfiguration.class)
-@Deprecated
-public abstract class AbstractSecurityWebSocketMessageBrokerConfigurer
- implements WebSocketMessageBrokerConfigurer, SmartInitializingSingleton {
-
- private final WebSocketMessageSecurityMetadataSourceRegistry inboundRegistry = new WebSocketMessageSecurityMetadataSourceRegistry();
-
- private SecurityExpressionHandler> defaultExpressionHandler = new DefaultMessageSecurityExpressionHandler<>();
-
- private SecurityExpressionHandler> expressionHandler;
-
- private ApplicationContext context;
-
- @Override
- public void registerStompEndpoints(StompEndpointRegistry registry) {
- }
-
- @Override
- public void addArgumentResolvers(List argumentResolvers) {
- argumentResolvers.add(new AuthenticationPrincipalArgumentResolver());
- }
-
- @Override
- public final void configureClientInboundChannel(ChannelRegistration registration) {
- ChannelSecurityInterceptor inboundChannelSecurity = this.context.getBean(ChannelSecurityInterceptor.class);
- registration.interceptors(this.context.getBean(SecurityContextChannelInterceptor.class));
- if (!sameOriginDisabled()) {
- registration.interceptors(this.context.getBean(CsrfChannelInterceptor.class));
- }
- if (this.inboundRegistry.containsMapping()) {
- registration.interceptors(inboundChannelSecurity);
- }
- customizeClientInboundChannel(registration);
- }
-
- private PathMatcher getDefaultPathMatcher() {
- try {
- return this.context.getBean(SimpAnnotationMethodMessageHandler.class).getPathMatcher();
- }
- catch (NoSuchBeanDefinitionException ex) {
- return new AntPathMatcher();
- }
- }
-
- /**
- *
- * Determines if a CSRF token is required for connecting. This protects against remote
- * sites from connecting to the application and being able to read/write data over the
- * connection. The default is false (the token is required).
- *
- *
- * Subclasses can override this method to disable CSRF protection
- *
- * @return false if a CSRF token is required for connecting, else true
- */
- protected boolean sameOriginDisabled() {
- return false;
- }
-
- /**
- * Allows subclasses to customize the configuration of the {@link ChannelRegistration}
- * .
- * @param registration the {@link ChannelRegistration} to customize
- */
- protected void customizeClientInboundChannel(ChannelRegistration registration) {
- }
-
- @Bean
- public CsrfChannelInterceptor csrfChannelInterceptor() {
- return new CsrfChannelInterceptor();
- }
-
- @Bean
- public ChannelSecurityInterceptor inboundChannelSecurity(
- MessageSecurityMetadataSource messageSecurityMetadataSource) {
- ChannelSecurityInterceptor channelSecurityInterceptor = new ChannelSecurityInterceptor(
- messageSecurityMetadataSource);
- MessageExpressionVoter voter = new MessageExpressionVoter<>();
- voter.setExpressionHandler(getMessageExpressionHandler());
- List> voters = new ArrayList<>();
- voters.add(voter);
- AffirmativeBased manager = new AffirmativeBased(voters);
- channelSecurityInterceptor.setAccessDecisionManager(manager);
- return channelSecurityInterceptor;
- }
-
- @Bean
- public SecurityContextChannelInterceptor securityContextChannelInterceptor() {
- return new SecurityContextChannelInterceptor();
- }
-
- @Bean
- public MessageSecurityMetadataSource inboundMessageSecurityMetadataSource() {
- this.inboundRegistry.expressionHandler(getMessageExpressionHandler());
- configureInbound(this.inboundRegistry);
- return this.inboundRegistry.createMetadataSource();
- }
-
- /**
- * @param messages
- */
- protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
- }
-
- @Autowired
- public void setApplicationContext(ApplicationContext context) {
- this.context = context;
- }
-
- @Deprecated
- public void setMessageExpessionHandler(List>> expressionHandlers) {
- setMessageExpressionHandler(expressionHandlers);
- }
-
- @Autowired(required = false)
- public void setMessageExpressionHandler(List>> expressionHandlers) {
- if (expressionHandlers.size() == 1) {
- this.expressionHandler = expressionHandlers.get(0);
- }
- }
-
- @Autowired(required = false)
- public void setObjectPostProcessor(ObjectPostProcessor objectPostProcessor) {
- this.defaultExpressionHandler = objectPostProcessor.postProcess(this.defaultExpressionHandler);
- }
-
- private SecurityExpressionHandler> getMessageExpressionHandler() {
- if (this.expressionHandler == null) {
- return this.defaultExpressionHandler;
- }
- return this.expressionHandler;
- }
-
- @Override
- public void afterSingletonsInstantiated() {
- if (sameOriginDisabled()) {
- return;
- }
- String beanName = "stompWebSocketHandlerMapping";
- SimpleUrlHandlerMapping mapping = this.context.getBean(beanName, SimpleUrlHandlerMapping.class);
- Map 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 " + beanName + " is expected to contain mappings to either a "
- + "SockJsHttpRequestHandler or a WebSocketHttpRequestHandler but got " + object);
- }
- }
- if (this.inboundRegistry.containsMapping() && !this.inboundRegistry.isSimpDestPathMatcherConfigured()) {
- PathMatcher pathMatcher = getDefaultPathMatcher();
- this.inboundRegistry.simpDestPathMatcher(pathMatcher);
- }
- }
-
- 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 handshakeInterceptors = transportHandlingSockJsService.getHandshakeInterceptors();
- List interceptorsToSet = new ArrayList<>(handshakeInterceptors.size() + 1);
- interceptorsToSet.add(new CsrfTokenHandshakeInterceptor());
- interceptorsToSet.addAll(handshakeInterceptors);
- transportHandlingSockJsService.setHandshakeInterceptors(interceptorsToSet);
- }
-
- private void setHandshakeInterceptors(WebSocketHttpRequestHandler handler) {
- List handshakeInterceptors = handler.getHandshakeInterceptors();
- List interceptorsToSet = new ArrayList<>(handshakeInterceptors.size() + 1);
- interceptorsToSet.add(new CsrfTokenHandshakeInterceptor());
- interceptorsToSet.addAll(handshakeInterceptors);
- handler.setHandshakeInterceptors(interceptorsToSet);
- }
-
- private static class WebSocketMessageSecurityMetadataSourceRegistry extends MessageSecurityMetadataSourceRegistry {
-
- @Override
- public MessageSecurityMetadataSource createMetadataSource() {
- return super.createMetadataSource();
- }
-
- @Override
- protected boolean containsMapping() {
- return super.containsMapping();
- }
-
- @Override
- protected boolean isSimpDestPathMatcherConfigured() {
- return super.isSimpDestPathMatcherConfigured();
- }
-
- }
-
-}
diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/socket/AbstractSecurityWebSocketMessageBrokerConfigurerDocTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/socket/AbstractSecurityWebSocketMessageBrokerConfigurerDocTests.java
deleted file mode 100644
index 6c3849d55ff..00000000000
--- a/config/src/test/java/org/springframework/security/config/annotation/web/socket/AbstractSecurityWebSocketMessageBrokerConfigurerDocTests.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.
- * 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.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry;
-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 AbstractSecurityWebSocketMessageBrokerConfigurerDocTests {
-
- 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 message(String destination, SimpMessageType type) {
- SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create(type);
- return message(headers, destination);
- }
-
- private Message 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
- static class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
-
- @Override
- protected void configureInbound(MessageSecurityMetadataSourceRegistry 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>
- }
-
- }
-
- @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();
- }
-
- }
-
-}
diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/socket/AbstractSecurityWebSocketMessageBrokerConfigurerTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/socket/AbstractSecurityWebSocketMessageBrokerConfigurerTests.java
deleted file mode 100644
index 89af68e9da4..00000000000
--- a/config/src/test/java/org/springframework/security/config/annotation/web/socket/AbstractSecurityWebSocketMessageBrokerConfigurerTests.java
+++ /dev/null
@@ -1,733 +0,0 @@
-/*
- * Copyright 2002-2023 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.Map;
-
-import jakarta.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.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.access.expression.SecurityExpressionHandler;
-import org.springframework.security.access.expression.SecurityExpressionOperations;
-import org.springframework.security.authentication.TestingAuthenticationToken;
-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.expression.DefaultMessageSecurityExpressionHandler;
-import org.springframework.security.messaging.access.expression.MessageSecurityExpressionRoot;
-import org.springframework.security.messaging.access.intercept.ChannelSecurityInterceptor;
-import org.springframework.security.messaging.access.intercept.MessageSecurityMetadataSource;
-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.DeferredCsrfToken;
-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.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.springframework.security.web.csrf.CsrfTokenAssert.assertThatCsrfToken;
-
-public class AbstractSecurityWebSocketMessageBrokerConfigurerTests {
-
- 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 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 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();
- CsrfChannelInterceptor csrfChannelInterceptor = this.context.getBean(CsrfChannelInterceptor.class);
- assertThat(((AbstractMessageChannel) messageChannel).getInterceptors()).contains(csrfChannelInterceptor);
- }
-
- @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);
- ChannelSecurityInterceptor channelSecurityInterceptor = this.context.getBean(ChannelSecurityInterceptor.class);
- MessageSecurityMetadataSource messageSecurityMetadataSource = this.context
- .getBean(MessageSecurityMetadataSource.class);
- assertThat(channelSecurityInterceptor.obtainSecurityMetadataSource()).isSameAs(messageSecurityMetadataSource);
- }
-
- @Test
- public void securityContextChannelInterceptorDefinedByBean() {
- loadConfig(SockJsProxylessSecurityConfig.class);
- MessageChannel messageChannel = clientInboundChannel();
- SecurityContextChannelInterceptor securityContextChannelInterceptor = this.context
- .getBean(SecurityContextChannelInterceptor.class);
- assertThat(((AbstractMessageChannel) messageChannel).getInterceptors())
- .contains(securityContextChannelInterceptor);
- }
-
- @Test
- public void inboundChannelSecurityDefinedByBean() {
- loadConfig(SockJsProxylessSecurityConfig.class);
- MessageChannel messageChannel = clientInboundChannel();
- ChannelSecurityInterceptor inboundChannelSecurity = this.context.getBean(ChannelSecurityInterceptor.class);
- assertThat(((AbstractMessageChannel) messageChannel).getInterceptors()).contains(inboundChannelSecurity);
- }
-
- private void assertHandshake(HttpServletRequest request) {
- TestHandshakeHandler handshakeHandler = this.context.getBean(TestHandshakeHandler.class);
- assertThatCsrfToken(handshakeHandler.attributes.get(CsrfToken.class.getName())).isEqualTo(this.token);
- assertThat(handshakeHandler.attributes).containsEntry(this.sessionAttr,
- 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(DeferredCsrfToken.class.getName(), new TestDeferredCsrfToken(this.token));
- return request;
- }
-
- private Message message(String destination) {
- SimpMessageHeaderAccessor headers = SimpMessageHeaderAccessor.create();
- return message(headers, destination);
- }
-
- private Message 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 MessageChannel clientInboundChannel() {
- return 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
- @Import(SyncExecutorConfig.class)
- static class MsmsRegistryCustomPatternMatcherConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
-
- // @formatter:off
- @Override
- public void registerStompEndpoints(StompEndpointRegistry registry) {
- registry
- .addEndpoint("/other")
- .setHandshakeHandler(testHandshakeHandler());
- }
- // @formatter:on
- // @formatter:off
- @Override
- protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
- messages
- .simpDestMatchers("/app/a.*").permitAll()
- .anyMessage().denyAll();
- }
- // @formatter:on
- @Override
- public void configureMessageBroker(MessageBrokerRegistry registry) {
- registry.setPathMatcher(new AntPathMatcher("."));
- registry.enableSimpleBroker("/queue/", "/topic/");
- registry.setApplicationDestinationPrefixes("/app");
- }
-
- @Bean
- TestHandshakeHandler testHandshakeHandler() {
- return new TestHandshakeHandler();
- }
-
- }
-
- @Configuration
- @EnableWebSocketMessageBroker
- @Import(SyncExecutorConfig.class)
- static class OverrideMsmsRegistryCustomPatternMatcherConfig
- extends AbstractSecurityWebSocketMessageBrokerConfigurer {
-
- // @formatter:off
- @Override
- public void registerStompEndpoints(StompEndpointRegistry registry) {
- registry
- .addEndpoint("/other")
- .setHandshakeHandler(testHandshakeHandler());
- }
- // @formatter:on
- // @formatter:off
- @Override
- protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
- messages
- .simpDestPathMatcher(new AntPathMatcher())
- .simpDestMatchers("/app/a/*").permitAll()
- .anyMessage().denyAll();
- }
- // @formatter:on
- @Override
- public void configureMessageBroker(MessageBrokerRegistry registry) {
- registry.setPathMatcher(new AntPathMatcher("."));
- registry.enableSimpleBroker("/queue/", "/topic/");
- registry.setApplicationDestinationPrefixes("/app");
- }
-
- @Bean
- TestHandshakeHandler testHandshakeHandler() {
- return new TestHandshakeHandler();
- }
-
- }
-
- @Configuration
- @EnableWebSocketMessageBroker
- @Import(SyncExecutorConfig.class)
- static class DefaultPatternMatcherConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
-
- // @formatter:off
- @Override
- public void registerStompEndpoints(StompEndpointRegistry registry) {
- registry
- .addEndpoint("/other")
- .setHandshakeHandler(testHandshakeHandler());
- }
- // @formatter:on
- // @formatter:off
- @Override
- protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
- messages
- .simpDestMatchers("/app/a/*").permitAll()
- .anyMessage().denyAll();
- }
- // @formatter:on
- @Override
- public void configureMessageBroker(MessageBrokerRegistry registry) {
- registry.enableSimpleBroker("/queue/", "/topic/");
- registry.setApplicationDestinationPrefixes("/app");
- }
-
- @Bean
- TestHandshakeHandler testHandshakeHandler() {
- return new TestHandshakeHandler();
- }
-
- }
-
- @Configuration
- @EnableWebSocketMessageBroker
- @Import(SyncExecutorConfig.class)
- static class CustomExpressionConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
-
- // @formatter:off
- @Override
- public void registerStompEndpoints(StompEndpointRegistry registry) {
- registry
- .addEndpoint("/other")
- .setHandshakeHandler(testHandshakeHandler());
- }
- // @formatter:on
- // @formatter:off
- @Override
- protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
- messages
- .anyMessage().access("denyRob()");
- }
- // @formatter:on
- @Bean
- static SecurityExpressionHandler> messageSecurityExpressionHandler() {
- return new DefaultMessageSecurityExpressionHandler() {
- @Override
- protected SecurityExpressionOperations createSecurityExpressionRoot(Authentication authentication,
- Message invocation) {
- return new MessageSecurityExpressionRoot(authentication, invocation) {
- public boolean denyRob() {
- Authentication auth = getAuthentication();
- return auth != null && !"rob".equals(auth.getName());
- }
- };
- }
- };
- }
-
- @Override
- public void configureMessageBroker(MessageBrokerRegistry registry) {
- registry.enableSimpleBroker("/queue/", "/topic/");
- registry.setApplicationDestinationPrefixes("/app");
- }
-
- @Bean
- public TestHandshakeHandler testHandshakeHandler() {
- return new TestHandshakeHandler();
- }
-
- }
-
- @Controller
- static class MyController {
-
- String authenticationPrincipal;
-
- MyCustomArgument myCustomArgument;
-
- @MessageMapping("/authentication")
- public void authentication(@AuthenticationPrincipal String un) {
- this.authenticationPrincipal = un;
- }
-
- @MessageMapping("/myCustom")
- public 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 attributes;
-
- @Override
- public boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
- Map 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
- @EnableWebSocketMessageBroker
- @Import(SyncExecutorConfig.class)
- static class SockJsSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
-
- @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
- @Override
- protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
- messages
- .simpDestMatchers("/permitAll/**").permitAll()
- .simpDestMatchers("/beanResolver/**").access("@security.check()")
- .anyMessage().denyAll();
- }
- // @formatter:on
- @Override
- public void configureMessageBroker(MessageBrokerRegistry registry) {
- registry.enableSimpleBroker("/queue/", "/topic/");
- registry.setApplicationDestinationPrefixes("/permitAll", "/denyAll");
- }
-
- @Bean
- public MyController myController() {
- return new MyController();
- }
-
- @Bean
- public TestHandshakeHandler testHandshakeHandler() {
- return new TestHandshakeHandler();
- }
-
- @Bean
- public SecurityCheck security() {
- return new SecurityCheck();
- }
-
- static class SecurityCheck {
-
- private boolean check;
-
- public boolean check() {
- this.check = !this.check;
- return this.check;
- }
-
- }
-
- }
-
- @Configuration
- @EnableWebSocketMessageBroker
- @Import(SyncExecutorConfig.class)
- static class NoInboundSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
-
- @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
- protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
- }
-
- @Override
- public void configureMessageBroker(MessageBrokerRegistry registry) {
- registry.enableSimpleBroker("/queue/", "/topic/");
- registry.setApplicationDestinationPrefixes("/permitAll", "/denyAll");
- }
-
- @Bean
- public MyController myController() {
- return new MyController();
- }
-
- }
-
- @Configuration
- static class CsrfDisabledSockJsSecurityConfig extends SockJsSecurityConfig {
-
- @Override
- protected boolean sameOriginDisabled() {
- return true;
- }
-
- }
-
- @Configuration
- @EnableWebSocketMessageBroker
- @Import(SyncExecutorConfig.class)
- static class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
-
- @Override
- public void registerStompEndpoints(StompEndpointRegistry registry) {
- // @formatter:off
- registry.addEndpoint("/websocket")
- .setHandshakeHandler(testHandshakeHandler())
- .addInterceptors(new HttpSessionHandshakeInterceptor());
- // @formatter:on
- }
-
- @Override
- protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
- // @formatter:off
- messages
- .simpDestMatchers("/permitAll/**").permitAll()
- .simpDestMatchers("/customExpression/**").access("denyRob")
- .anyMessage().denyAll();
- // @formatter:on
- }
-
- @Bean
- public TestHandshakeHandler testHandshakeHandler() {
- return new TestHandshakeHandler();
- }
-
- }
-
- @Configuration(proxyBeanMethods = false)
- @EnableWebSocketMessageBroker
- @Import(SyncExecutorConfig.class)
- static class SockJsProxylessSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
-
- 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
- public void setContext(ApplicationContext context) {
- this.context = context;
- }
-
- // @formatter:off
- @Override
- protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
- messages
- .anyMessage().denyAll();
- }
- // @formatter:on
- @Bean
- public TestHandshakeHandler testHandshakeHandler() {
- return new TestHandshakeHandler();
- }
-
- }
-
- @Configuration
- static class SyncExecutorConfig {
-
- @Bean
- public static SyncExecutorSubscribableChannelPostProcessor postProcessor() {
- return new SyncExecutorSubscribableChannelPostProcessor();
- }
-
- }
-
-}
diff --git a/config/src/test/java/org/springframework/security/config/annotation/web/socket/WebSocketMessageBrokerSecurityConfigurationTests.java b/config/src/test/java/org/springframework/security/config/annotation/web/socket/WebSocketMessageBrokerSecurityConfigurationTests.java
index cf2d0358069..7e7c4420805 100644
--- a/config/src/test/java/org/springframework/security/config/annotation/web/socket/WebSocketMessageBrokerSecurityConfigurationTests.java
+++ b/config/src/test/java/org/springframework/security/config/annotation/web/socket/WebSocketMessageBrokerSecurityConfigurationTests.java
@@ -69,7 +69,6 @@
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.config.annotation.SecurityContextChangedListenerConfig;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.messaging.MessageSecurityMetadataSourceRegistry;
import org.springframework.security.config.observation.SecurityObservationSettings;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AnnotationTemplateExpressionDefaults;
@@ -878,37 +877,6 @@ TestHandshakeHandler testHandshakeHandler() {
}
- @Configuration
- @EnableWebSocketSecurity
- @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)
@EnableWebSocketSecurity
@EnableWebSocketMessageBroker
diff --git a/docs/modules/ROOT/pages/servlet/integrations/websocket.adoc b/docs/modules/ROOT/pages/servlet/integrations/websocket.adoc
index 736e5b15f43..a4827bac7b1 100644
--- a/docs/modules/ROOT/pages/servlet/integrations/websocket.adoc
+++ b/docs/modules/ROOT/pages/servlet/integrations/websocket.adoc
@@ -492,43 +492,6 @@ Xml::
----
======
-On the other hand, if you are using the <> and you want to allow other domains to access your site, you can disable Spring Security's protection.
-For example, in Java Configuration you can use the following:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Configuration
-public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer {
-
- ...
-
- @Override
- protected boolean sameOriginDisabled() {
- return true;
- }
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Configuration
-open class WebSocketSecurityConfig : AbstractSecurityWebSocketMessageBrokerConfigurer() {
-
- // ...
-
- override fun sameOriginDisabled(): Boolean {
- return true
- }
-}
-----
-======
-
[[websocket-expression-handler]]
=== Custom Expression Handler
@@ -742,50 +705,3 @@ If we use XML-based configuration, we can use thexref:servlet/appendix/namespace
----
-
-[[legacy-websocket-configuration]]
-== Legacy WebSocket Configuration
-
-Before Spring Security 5.8, the way to configure messaging authorization using Java Configuration, was to extend the `AbstractSecurityWebSocketMessageBrokerConfigurer` and configure the `MessageSecurityMetadataSourceRegistry`.
-For example:
-
-[tabs]
-======
-Java::
-+
-[source,java,role="primary"]
-----
-@Configuration
-public class WebSocketSecurityConfig
- extends AbstractSecurityWebSocketMessageBrokerConfigurer { // <1> <2>
-
- protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) {
- messages
- .simpDestMatchers("/user/**").authenticated() // <3>
- }
-}
-----
-
-Kotlin::
-+
-[source,kotlin,role="secondary"]
-----
-@Configuration
-open class WebSocketSecurityConfig : AbstractSecurityWebSocketMessageBrokerConfigurer() { // <1> <2>
- override fun configureInbound(messages: MessageSecurityMetadataSourceRegistry) {
- messages.simpDestMatchers("/user/**").authenticated() // <3>
- }
-}
-----
-======
-
-This will ensure that:
-
-<1> Any inbound CONNECT message requires a valid CSRF token to enforce <>
-<2> The SecurityContextHolder is populated with the user within the simpUser header attribute for any inbound request.
-<3> Our messages require the proper authorization. Specifically, any inbound message that starts with "/user/" will require ROLE_USER. Additional details on authorization can be found in <>
-
-Using the legacy configuration is helpful in the event that you have a custom `SecurityExpressionHandler` that extends `AbstractSecurityExpressionHandler` and overrides `createEvaluationContextInternal` or `createSecurityExpressionRoot`.
-In order to defer `Authorization` lookup, the new `AuthorizationManager` API does not invoke these when evaluating expressions.
-
-If you are using XML, you can use the legacy APIs simply by not using the `use-authorization-manager` element or setting it to `false`.
diff --git a/etc/checkstyle/checkstyle-suppressions.xml b/etc/checkstyle/checkstyle-suppressions.xml
index c1c5baf08a3..6bc4e305925 100644
--- a/etc/checkstyle/checkstyle-suppressions.xml
+++ b/etc/checkstyle/checkstyle-suppressions.xml
@@ -17,7 +17,6 @@
-