From 0f7a6d45fd31308c218fed57b9a8c0369392994a Mon Sep 17 00:00:00 2001 From: Tran Ngoc Nhan Date: Sat, 7 Mar 2026 13:13:27 +0700 Subject: [PATCH] Polish websocket Signed-off-by: Tran Ngoc Nhan --- .../pages/servlet/integrations/websocket.adoc | 407 +----------------- docs/spring-security-docs.gradle | 2 + .../AdvancedWebSocketSecurityConfig.java | 46 ++ .../WebSocketSecurityConfig.java | 38 ++ .../WebSocketSecurityConfig.java | 42 ++ .../WebSocketSecurityConfig.java | 38 ++ .../WebSocketSecurityConfig.java | 61 +++ .../WebSecurityConfig.java | 50 +++ .../WebSecurityConfig.java | 42 ++ .../AdvancedWebSocketSecurityConfig.kt | 46 ++ .../WebSocketSecurityConfig.kt | 38 ++ .../WebSocketSecurityConfig.kt | 42 ++ .../WebSocketSecurityConfig.kt | 38 ++ .../WebSocketSecurityConfig.kt | 50 +++ .../websocketsockjscsrf/WebSecurityConfig.kt | 53 +++ .../WebSecurityConfig.kt | 45 ++ .../AdvancedWebSocketSecurityConfig.xml | 49 +++ .../WebSocketSecurityConfig.xml | 36 ++ .../WebSocketSecurityConfig.xml | 33 ++ .../WebSocketSecurityConfig.xml | 33 ++ .../WebSocketSecurityConfig.xml | 55 +++ 21 files changed, 854 insertions(+), 390 deletions(-) create mode 100644 docs/src/test/java/org/springframework/security/docs/servlet/integrations/customauthorization/AdvancedWebSocketSecurityConfig.java create mode 100644 docs/src/test/java/org/springframework/security/docs/servlet/integrations/customauthorization/WebSocketSecurityConfig.java create mode 100644 docs/src/test/java/org/springframework/security/docs/servlet/integrations/migratingspelexpressions/WebSocketSecurityConfig.java create mode 100644 docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketauthorization/WebSocketSecurityConfig.java create mode 100644 docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketsameorigindisable/WebSocketSecurityConfig.java create mode 100644 docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketsockjscsrf/WebSecurityConfig.java create mode 100644 docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketsockjssameorigin/WebSecurityConfig.java create mode 100644 docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/customauthorization/AdvancedWebSocketSecurityConfig.kt create mode 100644 docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/customauthorization/WebSocketSecurityConfig.kt create mode 100644 docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/migratingspelexpressions/WebSocketSecurityConfig.kt create mode 100644 docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketauthorization/WebSocketSecurityConfig.kt create mode 100644 docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketsameorigindisable/WebSocketSecurityConfig.kt create mode 100644 docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketsockjscsrf/WebSecurityConfig.kt create mode 100644 docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketsockjssameorigin/WebSecurityConfig.kt create mode 100644 docs/src/test/resources/org/springframework/security/docs/servlet/integrations/customauthorization/AdvancedWebSocketSecurityConfig.xml create mode 100644 docs/src/test/resources/org/springframework/security/docs/servlet/integrations/customauthorization/WebSocketSecurityConfig.xml create mode 100644 docs/src/test/resources/org/springframework/security/docs/servlet/integrations/websocketauthorization/WebSocketSecurityConfig.xml create mode 100644 docs/src/test/resources/org/springframework/security/docs/servlet/integrations/websocketsameorigindisable/WebSocketSecurityConfig.xml create mode 100644 docs/src/test/resources/org/springframework/security/docs/servlet/integrations/websocketsockjscsrf/WebSocketSecurityConfig.xml diff --git a/docs/modules/ROOT/pages/servlet/integrations/websocket.adoc b/docs/modules/ROOT/pages/servlet/integrations/websocket.adoc index 2649c89095..91e841f155 100644 --- a/docs/modules/ROOT/pages/servlet/integrations/websocket.adoc +++ b/docs/modules/ROOT/pages/servlet/integrations/websocket.adoc @@ -31,179 +31,31 @@ In Spring Security 5.8, this support has been refreshed to use the `Authorizatio To configure authorization using Java Configuration, simply include the `@EnableWebSocketSecurity` annotation and publish an `AuthorizationManager>` bean or in xref:servlet/appendix/namespace/websocket.adoc#nsa-websocket-security[XML] use the `use-authorization-manager` attribute. One way to do this is by using the `AuthorizationManagerMessageMatcherRegistry` to specify endpoint patterns like so: -[tabs] -====== -Java:: -+ -[source,java,role="primary"] ----- -@Configuration -@EnableWebSocketSecurity // <1> <2> -public class WebSocketSecurityConfig { +include-code::./WebSocketSecurityConfig[tag=snippet,indent=0] - @Bean - AuthorizationManager> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) { - messages - .simpDestMatchers("/user/**").hasRole("USER"); // <3> - - return messages.build(); - } -} ----- - -Kotlin:: -+ -[source,kotlin,role="secondary"] ----- -@Configuration -@EnableWebSocketSecurity // <1> <2> -open class WebSocketSecurityConfig { // <1> <2> - @Bean - fun messageAuthorizationManager(messages: MessageMatcherDelegatingAuthorizationManager.Builder): AuthorizationManager> { - messages.simpDestMatchers("/user/**").hasRole("USER") // <3> - return messages.build() - } -} ----- - -Xml:: -+ -[source,xml,role="secondary"] ----- - <1> <2> - <3> - ----- -====== <1> Any inbound CONNECT message requires a valid CSRF token to enforce the <>. <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`. You can find additional details on authorization in <> +[[custom-authorization]] === Custom Authorization When using `AuthorizationManager`, customization is quite simple. -For example, you can publish an `AuthorizationManager` that requires that all messages have a role of "USER" using `AuthorityAuthorizationManager`, as seen below: +For example, you can publish an `AuthorizationManager` that requires that all messages have a role of `"USER"` using `AuthorityAuthorizationManager`, as seen below: -[tabs] -====== -Java:: -+ -[source,java,role="primary"] ----- -@Configuration -@EnableWebSocketSecurity // <1> <2> -public class WebSocketSecurityConfig { - - @Bean - AuthorizationManager> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) { - return AuthorityAuthorizationManager.hasRole("USER"); - } -} ----- - -Kotlin:: -+ -[source,kotlin,role="secondary"] ----- -@Configuration -@EnableWebSocketSecurity // <1> <2> -open class WebSocketSecurityConfig { - @Bean - fun messageAuthorizationManager(messages: MessageMatcherDelegatingAuthorizationManager.Builder): AuthorizationManager> { - return AuthorityAuthorizationManager.hasRole("USER") // <3> - } -} ----- - -Xml:: -+ -[source,xml,role="secondary"] ----- - - - ----- -====== +include-code::./WebSocketSecurityConfig[tag=snippet,indent=0] There are several ways to further match messages, as can be seen in a more advanced example below: -[tabs] -====== -Java:: -+ -[source,java,role="primary"] ----- -@Configuration -public class WebSocketSecurityConfig { - - @Bean - public AuthorizationManager> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) { - messages - .nullDestMatcher().authenticated() // <1> - .simpSubscribeDestMatchers("/user/queue/errors").permitAll() // <2> - .simpDestMatchers("/app/**").hasRole("USER") // <3> - .simpSubscribeDestMatchers("/user/**", "/topic/friends/*").hasRole("USER") // <4> - .simpTypeMatchers(MESSAGE, SUBSCRIBE).denyAll() // <5> - .anyMessage().denyAll(); // <6> - - return messages.build(); - } -} ----- - -Kotlin:: -+ -[source,kotlin,role="secondary"] ----- -@Configuration -open class WebSocketSecurityConfig { - fun messageAuthorizationManager(messages: MessageMatcherDelegatingAuthorizationManager.Builder): AuthorizationManager> { - messages - .nullDestMatcher().authenticated() // <1> - .simpSubscribeDestMatchers("/user/queue/errors").permitAll() // <2> - .simpDestMatchers("/app/**").hasRole("USER") // <3> - .simpSubscribeDestMatchers("/user/**", "/topic/friends/*").hasRole("USER") // <4> - .simpTypeMatchers(MESSAGE, SUBSCRIBE).denyAll() // <5> - .anyMessage().denyAll() // <6> - - return messages.build(); - } -} ----- - -Xml:: -+ -[source,kotlin,role="secondary"] ----- - - - - - - - - - - - - - - - - - - - ----- -====== +include-code::./AdvancedWebSocketSecurityConfig[tag=snippet,indent=0] This will ensure that: -<1> Any message without a destination (i.e. anything other than Message type of MESSAGE or SUBSCRIBE) will require the user to be authenticated -<2> Anyone can subscribe to /user/queue/errors -<3> Any message that has a destination starting with "/app/" will be require the user to have the role ROLE_USER -<4> Any message that starts with "/user/" or "/topic/friends/" that is of type SUBSCRIBE will require ROLE_USER -<5> Any other message of type MESSAGE or SUBSCRIBE is rejected. Due to 6 we do not need this step, but it illustrates how one can match on specific message types. +<1> Any message without a destination (i.e. anything other than Message type of `MESSAGE` or `SUBSCRIBE`) will require the user to be authenticated +<2> Anyone can subscribe to `/user/queue/errors` +<3> Any message that has a destination starting with `"/app/"` will be required the user to have the role `ROLE_USER` +<4> Any message that starts with `"/user/"` or `"/topic/friends/"` that is of type SUBSCRIBE will require `ROLE_USER` +<5> Any other message of type `MESSAGE` or `SUBSCRIBE` is rejected. Due to 6 we do not need this step, but it illustrates how one can match on specific message types. <6> Any other Message is rejected. This is a good idea to ensure that you do not miss any messages. [[migrating-spel-expressions]] @@ -217,46 +69,7 @@ However, to ease migration, you can use And specify an instance for each matcher that you cannot yet migrate: -[tabs] -====== -Java:: -+ -[source,java,role="primary"] ----- -@Configuration -public class WebSocketSecurityConfig { - - @Bean - public AuthorizationManager> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) { - messages - // ... - .simpSubscribeDestMatchers("/topic/friends/{friend}") - .access(new MessageExpressionAuthorizationManager("#friend == 'john'")); - // ... - - return messages.build(); - } -} ----- - -Kotlin:: -+ -[source,kotlin,role="secondary"] ----- -@Configuration -open class WebSocketSecurityConfig { - fun messageAuthorizationManager(messages: MessageMatcherDelegatingAuthorizationManager.Builder): AuthorizationManager { - messages - // .. - .simpSubscribeDestMatchers("/topic/friends/{friend}") - .access(MessageExpressionAuthorizationManager("#friend == 'john'")) - // ... - - return messages.build() - } -} ----- -====== +include-code::./WebSocketSecurityConfig[tag=snippet,indent=0] [[websocket-authorization-notes]] === WebSocket Authorization Notes @@ -380,6 +193,7 @@ Kotlin:: ---- @RestController class CsrfController { + @RequestMapping("/csrf") fun csrf(token: CsrfToken): CsrfToken { return token @@ -409,69 +223,7 @@ NOTE: At this point, CSRF is not configurable when using `@EnableWebSocketSecuri To disable CSRF, instead of using `@EnableWebSocketSecurity`, you can use XML support or add the Spring Security components yourself, like so: -[tabs] -====== -Java:: -+ -[source,java,role="primary"] ----- -@Configuration -public class WebSocketSecurityConfig implements WebSocketMessageBrokerConfigurer { - - private final ApplicationContext applicationContext; - - private final AuthorizationManager> authorizationManager; - - public WebSocketSecurityConfig(ApplicationContext applicationContext, AuthorizationManager> authorizationManager) { - this.applicationContext = applicationContext; - this.authorizationManager = authorizationManager; - } - - @Override - public void addArgumentResolvers(List argumentResolvers) { - argumentResolvers.add(new AuthenticationPrincipalArgumentResolver()); - } - - @Override - public void configureClientInboundChannel(ChannelRegistration registration) { - AuthorizationChannelInterceptor authz = new AuthorizationChannelInterceptor(authorizationManager); - AuthorizationEventPublisher publisher = new SpringAuthorizationEventPublisher(applicationContext); - authz.setAuthorizationEventPublisher(publisher); - registration.interceptors(new SecurityContextChannelInterceptor(), authz); - } -} ----- - -Kotlin:: -+ -[source,kotlin,role="secondary"] ----- -@Configuration -open class WebSocketSecurityConfig(val applicationContext: ApplicationContext, val authorizationManager: AuthorizationManager>) : WebSocketMessageBrokerConfigurer { - @Override - override fun addArgumentResolvers(argumentResolvers: List) { - argumentResolvers.add(AuthenticationPrincipalArgumentResolver()) - } - - @Override - override fun configureClientInboundChannel(registration: ChannelRegistration) { - var authz: AuthorizationChannelInterceptor = AuthorizationChannelInterceptor(authorizationManager) - var publisher: AuthorizationEventPublisher = SpringAuthorizationEventPublisher(applicationContext) - authz.setAuthorizationEventPublisher(publisher) - registration.interceptors(SecurityContextChannelInterceptor(), authz) - } -} ----- - -Xml:: -+ -[source,xml,role="secondary"] ----- - - - ----- -====== +include-code::./WebSocketSecurityConfig[tag=snippet,indent=0] [[websocket-expression-handler]] === Custom Expression Handler @@ -537,52 +289,7 @@ For example, the following instructs Spring Security to use `X-Frame-Options: SA Similarly, you can customize frame options to use the same origin within Java Configuration by using the following: -[tabs] -====== -Java:: -+ -[source,java,role="primary"] ----- -@Configuration -@EnableWebSecurity -public class WebSecurityConfig { - - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http - // ... - .headers((headers) -> headers - .frameOptions((frameOptions) -> frameOptions - .sameOrigin() - ) - ); - return http.build(); - } -} ----- - -Kotlin:: -+ -[source,kotlin,role="secondary"] ----- -@Configuration -@EnableWebSecurity -open class WebSecurityConfig { - @Bean - open fun filterChain(http: HttpSecurity): SecurityFilterChain { - http { - // ... - headers { - frameOptions { - sameOrigin = true - } - } - } - return http.build() - } -} ----- -====== +include-code::./WebSecurityConfig[tag=snippet,indent=0] [[websocket-sockjs-csrf]] === SockJS & Relaxing CSRF @@ -601,91 +308,11 @@ We can easily achieve this by providing a CSRF `RequestMatcher`. Our Java configuration makes this easy. For example, if our stomp endpoint is `/chat`, we can disable CSRF protection only for URLs that start with `/chat/` by using the following configuration: -[tabs] -====== -Java:: -+ -[source,java,role="primary"] ----- -@Configuration -@EnableWebSecurity -public class WebSecurityConfig { +include-code::./WebSecurityConfig[tag=snippet,indent=0] - @Bean - public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http - .csrf((csrf) -> csrf - // ignore our stomp endpoints since they are protected using Stomp headers - .ignoringRequestMatchers("/chat/**") - ) - .headers((headers) -> headers - // allow same origin to frame our site to support iframe SockJS - .frameOptions((frameOptions) -> frameOptions - .sameOrigin() - ) - ) - .authorizeHttpRequests((authorize) -> authorize - ... - ); - ... - } -} ----- +If we use XML-based configuration, we can use the xref:servlet/appendix/namespace/http.adoc#nsa-csrf-request-matcher-ref[csrf@request-matcher-ref]. -Kotlin:: -+ -[source,kotlin,role="secondary"] ----- -@Configuration -@EnableWebSecurity -open class WebSecurityConfig { - @Bean - open fun filterChain(http: HttpSecurity): SecurityFilterChain { - http { - csrf { - ignoringRequestMatchers("/chat/**") - } - headers { - frameOptions { - sameOrigin = true - } - } - authorizeHttpRequests { - // ... - } - // ... - } - } -} ----- -====== - -If we use XML-based configuration, we can use thexref:servlet/appendix/namespace/http.adoc#nsa-csrf-request-matcher-ref[csrf@request-matcher-ref]. - -[source,xml] ----- - - - - - - - - ... - - - - - - - - - - - - ----- +include-code::./WebSocketSecurityConfig[tag=snippet,indent=0] [[legacy-websocket-configuration]] == Legacy WebSocket Configuration diff --git a/docs/spring-security-docs.gradle b/docs/spring-security-docs.gradle index cfffe38d0c..d32a956ac2 100644 --- a/docs/spring-security-docs.gradle +++ b/docs/spring-security-docs.gradle @@ -43,6 +43,7 @@ dependencies { testImplementation project(':spring-security-test') testImplementation project(':spring-security-oauth2-client') testImplementation project(':spring-security-oauth2-resource-server') + testImplementation project(':spring-security-messaging') testImplementation 'com.squareup.okhttp3:mockwebserver' testImplementation libs.com.password4j.password4j testImplementation 'com.unboundid:unboundid-ldapsdk' @@ -51,6 +52,7 @@ dependencies { testImplementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' testImplementation 'org.springframework:spring-core' testImplementation 'org.springframework:spring-test' + testImplementation 'org.springframework:spring-websocket' testImplementation 'org.springframework:spring-webmvc' testImplementation 'jakarta.servlet:jakarta.servlet-api' diff --git a/docs/src/test/java/org/springframework/security/docs/servlet/integrations/customauthorization/AdvancedWebSocketSecurityConfig.java b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/customauthorization/AdvancedWebSocketSecurityConfig.java new file mode 100644 index 0000000000..1be17b2622 --- /dev/null +++ b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/customauthorization/AdvancedWebSocketSecurityConfig.java @@ -0,0 +1,46 @@ +/* + * Copyright 2026-present 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.docs.servlet.integrations.customauthorization; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.Message; +import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager; + +import static org.springframework.messaging.simp.SimpMessageType.MESSAGE; +import static org.springframework.messaging.simp.SimpMessageType.SUBSCRIBE; + +// tag::snippet[] +@Configuration +public class AdvancedWebSocketSecurityConfig { + + @Bean + public AuthorizationManager> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) { + messages + .nullDestMatcher().authenticated() // <1> + .simpSubscribeDestMatchers("/user/queue/errors").permitAll() // <2> + .simpDestMatchers("/app/**").hasRole("USER") // <3> + .simpSubscribeDestMatchers("/user/**", "/topic/friends/*").hasRole("USER") // <4> + .simpTypeMatchers(MESSAGE, SUBSCRIBE).denyAll() // <5> + .anyMessage().denyAll(); // <6> + + return messages.build(); + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/java/org/springframework/security/docs/servlet/integrations/customauthorization/WebSocketSecurityConfig.java b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/customauthorization/WebSocketSecurityConfig.java new file mode 100644 index 0000000000..20674d302c --- /dev/null +++ b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/customauthorization/WebSocketSecurityConfig.java @@ -0,0 +1,38 @@ +/* + * Copyright 2026-present 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.docs.servlet.integrations.customauthorization; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.Message; +import org.springframework.security.authorization.AuthorityAuthorizationManager; +import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.config.annotation.web.socket.EnableWebSocketSecurity; +import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager; + +// tag::snippet[] +@Configuration +@EnableWebSocketSecurity +public class WebSocketSecurityConfig { + + @Bean + AuthorizationManager> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) { + return AuthorityAuthorizationManager.hasRole("USER"); + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/java/org/springframework/security/docs/servlet/integrations/migratingspelexpressions/WebSocketSecurityConfig.java b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/migratingspelexpressions/WebSocketSecurityConfig.java new file mode 100644 index 0000000000..d07cfdb154 --- /dev/null +++ b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/migratingspelexpressions/WebSocketSecurityConfig.java @@ -0,0 +1,42 @@ +/* + * Copyright 2026-present 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.docs.servlet.integrations.migratingspelexpressions; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.Message; +import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.messaging.access.expression.MessageExpressionAuthorizationManager; +import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager; + +// tag::snippet[] +@Configuration +public class WebSocketSecurityConfig { + + @Bean + public AuthorizationManager> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) { + messages + // ... + .simpSubscribeDestMatchers("/topic/friends/{friend}") + .access(new MessageExpressionAuthorizationManager("#friend == 'john'")); + // ... + + return messages.build(); + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketauthorization/WebSocketSecurityConfig.java b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketauthorization/WebSocketSecurityConfig.java new file mode 100644 index 0000000000..59a6726c94 --- /dev/null +++ b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketauthorization/WebSocketSecurityConfig.java @@ -0,0 +1,38 @@ +/* + * Copyright 2026-present 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.docs.servlet.integrations.websocketauthorization; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.Message; +import org.springframework.security.authorization.AuthorizationManager; +import org.springframework.security.config.annotation.web.socket.EnableWebSocketSecurity; +import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager; + +// tag::snippet[] +@Configuration +@EnableWebSocketSecurity // <1> <2> +public class WebSocketSecurityConfig { + + @Bean + AuthorizationManager> messageAuthorizationManager(MessageMatcherDelegatingAuthorizationManager.Builder messages) { + messages.simpDestMatchers("/user/**").hasRole("USER"); // <3> + return messages.build(); + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketsameorigindisable/WebSocketSecurityConfig.java b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketsameorigindisable/WebSocketSecurityConfig.java new file mode 100644 index 0000000000..bc7cdd552b --- /dev/null +++ b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketsameorigindisable/WebSocketSecurityConfig.java @@ -0,0 +1,61 @@ +/* + * Copyright 2026-present 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.docs.servlet.integrations.websocketsameorigindisable; + +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.Message; +import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver; +import org.springframework.messaging.simp.config.ChannelRegistration; +import org.springframework.security.authorization.AuthorizationEventPublisher; +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.context.AuthenticationPrincipalArgumentResolver; +import org.springframework.security.messaging.context.SecurityContextChannelInterceptor; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +import java.util.List; + +// tag::snippet[] +@Configuration +public class WebSocketSecurityConfig implements WebSocketMessageBrokerConfigurer { + + private final ApplicationContext applicationContext; + + private final AuthorizationManager> authorizationManager; + + public WebSocketSecurityConfig(ApplicationContext applicationContext, AuthorizationManager> authorizationManager) { + this.applicationContext = applicationContext; + this.authorizationManager = authorizationManager; + } + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(new AuthenticationPrincipalArgumentResolver()); + } + + @Override + public void configureClientInboundChannel(ChannelRegistration registration) { + AuthorizationChannelInterceptor authz = new AuthorizationChannelInterceptor(authorizationManager); + AuthorizationEventPublisher publisher = new SpringAuthorizationEventPublisher(applicationContext); + authz.setAuthorizationEventPublisher(publisher); + registration.interceptors(new SecurityContextChannelInterceptor(), authz); + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketsockjscsrf/WebSecurityConfig.java b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketsockjscsrf/WebSecurityConfig.java new file mode 100644 index 0000000000..b4801cbc5c --- /dev/null +++ b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketsockjscsrf/WebSecurityConfig.java @@ -0,0 +1,50 @@ +/* + * Copyright 2026-present 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.docs.servlet.integrations.websocketsockjscsrf; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; +import org.springframework.security.web.SecurityFilterChain; + +// tag::snippet[] +@Configuration +@EnableWebSecurity +public class WebSecurityConfig { + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http + .csrf((csrf) -> csrf + // ignore our stomp endpoints since they are protected using Stomp headers + .ignoringRequestMatchers("/chat/**") + ) + .headers((headers) -> headers + // allow same origin to frame our site to support iframe SockJS + .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin) + ) + .authorizeHttpRequests((authorize) -> authorize + /* @chomp:line // ... */.anyRequest().permitAll() + ) + /* @chomp:line // ... */; + return http.build(); + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketsockjssameorigin/WebSecurityConfig.java b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketsockjssameorigin/WebSecurityConfig.java new file mode 100644 index 0000000000..a02d7feedf --- /dev/null +++ b/docs/src/test/java/org/springframework/security/docs/servlet/integrations/websocketsockjssameorigin/WebSecurityConfig.java @@ -0,0 +1,42 @@ +/* + * Copyright 2026-present 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.docs.servlet.integrations.websocketsockjssameorigin; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer; +import org.springframework.security.web.SecurityFilterChain; + +// tag::snippet[] +@Configuration +@EnableWebSecurity +public class WebSecurityConfig { + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http + // ... + .headers((headers) -> headers + .frameOptions(HeadersConfigurer.FrameOptionsConfig::sameOrigin) + ); + return http.build(); + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/customauthorization/AdvancedWebSocketSecurityConfig.kt b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/customauthorization/AdvancedWebSocketSecurityConfig.kt new file mode 100644 index 0000000000..bcc47f7af9 --- /dev/null +++ b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/customauthorization/AdvancedWebSocketSecurityConfig.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2026-present 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.kt.docs.servlet.integrations.customauthorization + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.messaging.Message +import org.springframework.security.authorization.AuthorizationManager +import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager + +import org.springframework.messaging.simp.SimpMessageType.MESSAGE +import org.springframework.messaging.simp.SimpMessageType.SUBSCRIBE + +// tag::snippet[] +@Configuration +open class AdvancedWebSocketSecurityConfig { + + @Bean + open fun messageAuthorizationManager(messages: MessageMatcherDelegatingAuthorizationManager.Builder): AuthorizationManager> { + messages + .nullDestMatcher().authenticated() // <1> + .simpSubscribeDestMatchers("/user/queue/errors").permitAll() // <2> + .simpDestMatchers("/app/**").hasRole("USER") // <3> + .simpSubscribeDestMatchers("/user/**", "/topic/friends/*").hasRole("USER") // <4> + .simpTypeMatchers(MESSAGE, SUBSCRIBE).denyAll() // <5> + .anyMessage().denyAll() // <6> + + return messages.build() + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/customauthorization/WebSocketSecurityConfig.kt b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/customauthorization/WebSocketSecurityConfig.kt new file mode 100644 index 0000000000..14cf00dcdd --- /dev/null +++ b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/customauthorization/WebSocketSecurityConfig.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2026-present 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.kt.docs.servlet.integrations.customauthorization + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.messaging.Message +import org.springframework.security.authorization.AuthorityAuthorizationManager +import org.springframework.security.authorization.AuthorizationManager +import org.springframework.security.config.annotation.web.socket.EnableWebSocketSecurity +import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager + +// tag::snippet[] +@Configuration +@EnableWebSocketSecurity +open class WebSocketSecurityConfig { + + @Bean + open fun messageAuthorizationManager(messages: MessageMatcherDelegatingAuthorizationManager.Builder): AuthorizationManager> { + return AuthorityAuthorizationManager.hasRole("USER") + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/migratingspelexpressions/WebSocketSecurityConfig.kt b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/migratingspelexpressions/WebSocketSecurityConfig.kt new file mode 100644 index 0000000000..1ea5809541 --- /dev/null +++ b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/migratingspelexpressions/WebSocketSecurityConfig.kt @@ -0,0 +1,42 @@ +/* + * Copyright 2026-present 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.kt.docs.servlet.integrations.migratingspelexpressions + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.messaging.Message +import org.springframework.security.authorization.AuthorizationManager +import org.springframework.security.messaging.access.expression.MessageExpressionAuthorizationManager +import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager + +// tag::snippet[] +@Configuration +open class WebSocketSecurityConfig { + + @Bean + open fun messageAuthorizationManager(messages: MessageMatcherDelegatingAuthorizationManager.Builder): AuthorizationManager> { + messages + // ... + .simpSubscribeDestMatchers("/topic/friends/{friend}") + .access(MessageExpressionAuthorizationManager("#friend == 'john'")) + // ... + + return messages.build() + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketauthorization/WebSocketSecurityConfig.kt b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketauthorization/WebSocketSecurityConfig.kt new file mode 100644 index 0000000000..4f0b405c57 --- /dev/null +++ b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketauthorization/WebSocketSecurityConfig.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2026-present 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.kt.docs.servlet.integrations.websocketauthorization + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.messaging.Message +import org.springframework.security.authorization.AuthorizationManager +import org.springframework.security.config.annotation.web.socket.EnableWebSocketSecurity +import org.springframework.security.messaging.access.intercept.MessageMatcherDelegatingAuthorizationManager + +// tag::snippet[] +@Configuration +@EnableWebSocketSecurity // <1> <2> +open class WebSocketSecurityConfig { + + @Bean + open fun messageAuthorizationManager(messages: MessageMatcherDelegatingAuthorizationManager.Builder): AuthorizationManager> { + messages.simpDestMatchers("/user/**").hasRole("USER") // <3> + return messages.build() + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketsameorigindisable/WebSocketSecurityConfig.kt b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketsameorigindisable/WebSocketSecurityConfig.kt new file mode 100644 index 0000000000..279193da7d --- /dev/null +++ b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketsameorigindisable/WebSocketSecurityConfig.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2026-present 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.kt.docs.servlet.integrations.websocketsameorigindisable + +import org.springframework.context.ApplicationContext +import org.springframework.context.annotation.Configuration +import org.springframework.messaging.Message +import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver +import org.springframework.messaging.simp.config.ChannelRegistration +import org.springframework.security.authorization.AuthorizationEventPublisher +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.context.AuthenticationPrincipalArgumentResolver +import org.springframework.security.messaging.context.SecurityContextChannelInterceptor +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer + +// tag::snippet[] +@Configuration +open class WebSocketSecurityConfig(val applicationContext: ApplicationContext, val authorizationManager: AuthorizationManager>): WebSocketMessageBrokerConfigurer { + + @Override + override fun addArgumentResolvers(argumentResolvers: MutableList) { + argumentResolvers.add(AuthenticationPrincipalArgumentResolver()) + } + + @Override + override fun configureClientInboundChannel(registration: ChannelRegistration) { + val authz = AuthorizationChannelInterceptor(authorizationManager) + val publisher: AuthorizationEventPublisher = SpringAuthorizationEventPublisher(applicationContext) + authz.setAuthorizationEventPublisher(publisher) + registration.interceptors(SecurityContextChannelInterceptor(), authz) + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketsockjscsrf/WebSecurityConfig.kt b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketsockjscsrf/WebSecurityConfig.kt new file mode 100644 index 0000000000..4a871ff949 --- /dev/null +++ b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketsockjscsrf/WebSecurityConfig.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2026-present 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.kt.docs.servlet.integrations.websocketsockjscsrf + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.security.config.annotation.web.builders.HttpSecurity +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity +import org.springframework.security.config.annotation.web.invoke +import org.springframework.security.web.SecurityFilterChain + +// tag::snippet[] +@Configuration +@EnableWebSecurity +open class WebSecurityConfig { + + @Bean + open fun filterChain(http: HttpSecurity): SecurityFilterChain { + http { + csrf { + // ignore our stomp endpoints since they are protected using Stomp headers + ignoringRequestMatchers("/chat/**") + } + headers { + frameOptions { + // allow same origin to frame our site to support iframe SockJS + sameOrigin = true + } + } + authorizeHttpRequests { + // ... + } + // ... + } + return http.build() + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketsockjssameorigin/WebSecurityConfig.kt b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketsockjssameorigin/WebSecurityConfig.kt new file mode 100644 index 0000000000..41950fc4cc --- /dev/null +++ b/docs/src/test/kotlin/org/springframework/security/kt/docs/servlet/integrations/websocketsockjssameorigin/WebSecurityConfig.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2026-present 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.kt.docs.servlet.integrations.websocketsockjssameorigin + +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.security.config.annotation.web.builders.HttpSecurity +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity +import org.springframework.security.config.annotation.web.invoke +import org.springframework.security.web.SecurityFilterChain + +// tag::snippet[] +@Configuration +@EnableWebSecurity +open class WebSecurityConfig { + + @Bean + open fun filterChain(http: HttpSecurity): SecurityFilterChain { + http { + // ... + headers { + frameOptions { + sameOrigin = true + } + } + } + return http.build() + } + +} +// end::snippet[] \ No newline at end of file diff --git a/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/customauthorization/AdvancedWebSocketSecurityConfig.xml b/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/customauthorization/AdvancedWebSocketSecurityConfig.xml new file mode 100644 index 0000000000..7d3c9f0987 --- /dev/null +++ b/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/customauthorization/AdvancedWebSocketSecurityConfig.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/customauthorization/WebSocketSecurityConfig.xml b/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/customauthorization/WebSocketSecurityConfig.xml new file mode 100644 index 0000000000..d7cae6a105 --- /dev/null +++ b/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/customauthorization/WebSocketSecurityConfig.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + diff --git a/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/websocketauthorization/WebSocketSecurityConfig.xml b/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/websocketauthorization/WebSocketSecurityConfig.xml new file mode 100644 index 0000000000..de5aa1f47d --- /dev/null +++ b/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/websocketauthorization/WebSocketSecurityConfig.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/websocketsameorigindisable/WebSocketSecurityConfig.xml b/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/websocketsameorigindisable/WebSocketSecurityConfig.xml new file mode 100644 index 0000000000..f4ca6ab848 --- /dev/null +++ b/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/websocketsameorigindisable/WebSocketSecurityConfig.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/websocketsockjscsrf/WebSocketSecurityConfig.xml b/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/websocketsockjscsrf/WebSocketSecurityConfig.xml new file mode 100644 index 0000000000..9bfe8212a2 --- /dev/null +++ b/docs/src/test/resources/org/springframework/security/docs/servlet/integrations/websocketsockjscsrf/WebSocketSecurityConfig.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +