parent
							
								
									31025d9f6c
								
							
						
					
					
						commit
						a8c027ba8e
					
				| 
						 | 
					@ -67,6 +67,7 @@
 | 
				
			||||||
		<module>spring-boot-sample-secure-webflux</module>
 | 
							<module>spring-boot-sample-secure-webflux</module>
 | 
				
			||||||
		<module>spring-boot-sample-servlet</module>
 | 
							<module>spring-boot-sample-servlet</module>
 | 
				
			||||||
		<module>spring-boot-sample-session</module>
 | 
							<module>spring-boot-sample-session</module>
 | 
				
			||||||
 | 
							<module>spring-boot-sample-session-webflux</module>
 | 
				
			||||||
		<module>spring-boot-sample-simple</module>
 | 
							<module>spring-boot-sample-simple</module>
 | 
				
			||||||
		<module>spring-boot-sample-test</module>
 | 
							<module>spring-boot-sample-test</module>
 | 
				
			||||||
		<module>spring-boot-sample-test-nomockito</module>
 | 
							<module>spring-boot-sample-test-nomockito</module>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,37 @@
 | 
				
			||||||
 | 
					= Spring Boot Spring Session Sample
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This sample demonstrates the Spring Session WebFlux auto-configuration support. Spring
 | 
				
			||||||
 | 
					Session supports multiple reactive session store types, including:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* `Redis`
 | 
				
			||||||
 | 
					* `MongoDB`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					== Using a different session store
 | 
				
			||||||
 | 
					Initially, the project uses MongoDB session store backed by an embedded MongoDB. You can
 | 
				
			||||||
 | 
					try out your favorite session store as explained below.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Redis
 | 
				
			||||||
 | 
					Add `org.springframework.session:spring-session-data-redis` and
 | 
				
			||||||
 | 
					`spring-boot-starter-data-redis-reactive` dependencies to the project and make sure it is
 | 
				
			||||||
 | 
					configured properly (by default, a Redis instance with the default settings is expected
 | 
				
			||||||
 | 
					on your local box).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TIP: Run sample application using Redis session store using
 | 
				
			||||||
 | 
					`$mvn spring-boot:run -Predis`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== MongoDB
 | 
				
			||||||
 | 
					Add `org.springframework.session:spring-session-data-mongodb` and
 | 
				
			||||||
 | 
					`spring-boot-starter-data-mongodb-reactive` and
 | 
				
			||||||
 | 
					`de.flapdoodle.embed:de.flapdoodle.embed.mongo` dependencies to the project. An embedded
 | 
				
			||||||
 | 
					MongoDB is automatically configured.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TIP: Run sample application using MongoDB session store using
 | 
				
			||||||
 | 
					`$mvn spring-boot:run -Pmongodb`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that this profile is active by default.
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,76 @@
 | 
				
			||||||
 | 
					<?xml version="1.0" encoding="UTF-8"?>
 | 
				
			||||||
 | 
					<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 | 
				
			||||||
 | 
						<modelVersion>4.0.0</modelVersion>
 | 
				
			||||||
 | 
						<parent>
 | 
				
			||||||
 | 
							<!-- Your own application should inherit from spring-boot-starter-parent -->
 | 
				
			||||||
 | 
							<groupId>org.springframework.boot</groupId>
 | 
				
			||||||
 | 
							<artifactId>spring-boot-samples</artifactId>
 | 
				
			||||||
 | 
							<version>${revision}</version>
 | 
				
			||||||
 | 
						</parent>
 | 
				
			||||||
 | 
						<artifactId>spring-boot-sample-session-webflux</artifactId>
 | 
				
			||||||
 | 
						<name>Spring Boot Session WebFlux Sample</name>
 | 
				
			||||||
 | 
						<description>Spring Boot Session WebFlux Sample</description>
 | 
				
			||||||
 | 
						<properties>
 | 
				
			||||||
 | 
							<main.basedir>${basedir}/../..</main.basedir>
 | 
				
			||||||
 | 
						</properties>
 | 
				
			||||||
 | 
						<dependencies>
 | 
				
			||||||
 | 
							<!-- Compile -->
 | 
				
			||||||
 | 
							<dependency>
 | 
				
			||||||
 | 
								<groupId>org.springframework.boot</groupId>
 | 
				
			||||||
 | 
								<artifactId>spring-boot-starter-webflux</artifactId>
 | 
				
			||||||
 | 
							</dependency>
 | 
				
			||||||
 | 
							<dependency>
 | 
				
			||||||
 | 
								<groupId>org.springframework.boot</groupId>
 | 
				
			||||||
 | 
								<artifactId>spring-boot-starter-security</artifactId>
 | 
				
			||||||
 | 
							</dependency>
 | 
				
			||||||
 | 
							<!-- Test -->
 | 
				
			||||||
 | 
							<dependency>
 | 
				
			||||||
 | 
								<groupId>org.springframework.boot</groupId>
 | 
				
			||||||
 | 
								<artifactId>spring-boot-starter-test</artifactId>
 | 
				
			||||||
 | 
								<scope>test</scope>
 | 
				
			||||||
 | 
							</dependency>
 | 
				
			||||||
 | 
						</dependencies>
 | 
				
			||||||
 | 
						<build>
 | 
				
			||||||
 | 
							<plugins>
 | 
				
			||||||
 | 
								<plugin>
 | 
				
			||||||
 | 
									<groupId>org.springframework.boot</groupId>
 | 
				
			||||||
 | 
									<artifactId>spring-boot-maven-plugin</artifactId>
 | 
				
			||||||
 | 
								</plugin>
 | 
				
			||||||
 | 
							</plugins>
 | 
				
			||||||
 | 
						</build>
 | 
				
			||||||
 | 
						<profiles>
 | 
				
			||||||
 | 
							<profile>
 | 
				
			||||||
 | 
								<id>redis</id>
 | 
				
			||||||
 | 
								<dependencies>
 | 
				
			||||||
 | 
									<dependency>
 | 
				
			||||||
 | 
										<groupId>org.springframework.session</groupId>
 | 
				
			||||||
 | 
										<artifactId>spring-session-data-redis</artifactId>
 | 
				
			||||||
 | 
									</dependency>
 | 
				
			||||||
 | 
									<dependency>
 | 
				
			||||||
 | 
										<groupId>org.springframework.boot</groupId>
 | 
				
			||||||
 | 
										<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
 | 
				
			||||||
 | 
									</dependency>
 | 
				
			||||||
 | 
								</dependencies>
 | 
				
			||||||
 | 
							</profile>
 | 
				
			||||||
 | 
							<profile>
 | 
				
			||||||
 | 
								<id>mongodb</id>
 | 
				
			||||||
 | 
								<activation>
 | 
				
			||||||
 | 
									<activeByDefault>true</activeByDefault>
 | 
				
			||||||
 | 
								</activation>
 | 
				
			||||||
 | 
								<dependencies>
 | 
				
			||||||
 | 
									<dependency>
 | 
				
			||||||
 | 
										<groupId>org.springframework.session</groupId>
 | 
				
			||||||
 | 
										<artifactId>spring-session-data-mongodb</artifactId>
 | 
				
			||||||
 | 
									</dependency>
 | 
				
			||||||
 | 
									<dependency>
 | 
				
			||||||
 | 
										<groupId>org.springframework.boot</groupId>
 | 
				
			||||||
 | 
										<artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
 | 
				
			||||||
 | 
									</dependency>
 | 
				
			||||||
 | 
									<dependency>
 | 
				
			||||||
 | 
										<groupId>de.flapdoodle.embed</groupId>
 | 
				
			||||||
 | 
										<artifactId>de.flapdoodle.embed.mongo</artifactId>
 | 
				
			||||||
 | 
									</dependency>
 | 
				
			||||||
 | 
								</dependencies>
 | 
				
			||||||
 | 
							</profile>
 | 
				
			||||||
 | 
						</profiles>
 | 
				
			||||||
 | 
					</project>
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-2017 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
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *      http://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 sample.session;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.springframework.web.bind.annotation.GetMapping;
 | 
				
			||||||
 | 
					import org.springframework.web.bind.annotation.RestController;
 | 
				
			||||||
 | 
					import org.springframework.web.server.WebSession;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@RestController
 | 
				
			||||||
 | 
					public class HelloRestController {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@GetMapping("/")
 | 
				
			||||||
 | 
						String sessionId(WebSession session) {
 | 
				
			||||||
 | 
							return session.getId();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,57 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-2017 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
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *      http://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 sample.session;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.springframework.boot.SpringApplication;
 | 
				
			||||||
 | 
					import org.springframework.boot.autoconfigure.SpringBootApplication;
 | 
				
			||||||
 | 
					import org.springframework.context.annotation.Bean;
 | 
				
			||||||
 | 
					import org.springframework.security.config.web.server.ServerHttpSecurity;
 | 
				
			||||||
 | 
					import org.springframework.security.core.userdetails.MapReactiveUserDetailsService;
 | 
				
			||||||
 | 
					import org.springframework.security.core.userdetails.ReactiveUserDetailsService;
 | 
				
			||||||
 | 
					import org.springframework.security.core.userdetails.User;
 | 
				
			||||||
 | 
					import org.springframework.security.web.server.SecurityWebFilterChain;
 | 
				
			||||||
 | 
					import org.springframework.security.web.server.context.WebSessionServerSecurityContextRepository;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@SpringBootApplication
 | 
				
			||||||
 | 
					public class SampleSessionWebFluxApplication {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static void main(String[] args) {
 | 
				
			||||||
 | 
							SpringApplication.run(SampleSessionWebFluxApplication.class);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Bean
 | 
				
			||||||
 | 
						public ReactiveUserDetailsService userDetailsRepository() {
 | 
				
			||||||
 | 
							return new MapReactiveUserDetailsService(User.withDefaultPasswordEncoder()
 | 
				
			||||||
 | 
									.username("user").password("password").roles("USER").build());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Bean
 | 
				
			||||||
 | 
						public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
 | 
				
			||||||
 | 
							// @formatter:off
 | 
				
			||||||
 | 
							return http
 | 
				
			||||||
 | 
								.authorizeExchange()
 | 
				
			||||||
 | 
									.anyExchange().authenticated()
 | 
				
			||||||
 | 
									.and()
 | 
				
			||||||
 | 
								.httpBasic().securityContextRepository(new WebSessionServerSecurityContextRepository())
 | 
				
			||||||
 | 
									.and()
 | 
				
			||||||
 | 
								.formLogin()
 | 
				
			||||||
 | 
									.and()
 | 
				
			||||||
 | 
								.build();
 | 
				
			||||||
 | 
							// @formatter:on
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,77 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright 2012-2017 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
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 *      http://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 sample.session;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.Base64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.junit.Test;
 | 
				
			||||||
 | 
					import org.junit.runner.RunWith;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.springframework.beans.factory.annotation.Autowired;
 | 
				
			||||||
 | 
					import org.springframework.boot.test.context.SpringBootTest;
 | 
				
			||||||
 | 
					import org.springframework.boot.web.server.LocalServerPort;
 | 
				
			||||||
 | 
					import org.springframework.http.HttpStatus;
 | 
				
			||||||
 | 
					import org.springframework.http.ResponseCookie;
 | 
				
			||||||
 | 
					import org.springframework.test.context.junit4.SpringRunner;
 | 
				
			||||||
 | 
					import org.springframework.web.reactive.function.client.ClientResponse;
 | 
				
			||||||
 | 
					import org.springframework.web.reactive.function.client.WebClient;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.assertj.core.api.Assertions.assertThat;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Integration tests for {@link SampleSessionWebFluxApplication}.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * @author Vedran Pavic
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					@RunWith(SpringRunner.class)
 | 
				
			||||||
 | 
					@SpringBootTest(properties = "server.session.timeout:1", webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
 | 
				
			||||||
 | 
					public class SampleSessionWebFluxApplicationTests {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@LocalServerPort
 | 
				
			||||||
 | 
						private int port;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Autowired
 | 
				
			||||||
 | 
						private WebClient.Builder webClientBuilder;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@Test
 | 
				
			||||||
 | 
						public void userDefinedMappingsSecureByDefault() throws Exception {
 | 
				
			||||||
 | 
							WebClient webClient = this.webClientBuilder
 | 
				
			||||||
 | 
									.baseUrl("http://localhost:" + this.port + "/").build();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ClientResponse response = webClient.get().header("Authorization", getBasicAuth())
 | 
				
			||||||
 | 
									.exchange().block();
 | 
				
			||||||
 | 
							assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
 | 
				
			||||||
 | 
							ResponseCookie sessionCookie = response.cookies().getFirst("SESSION");
 | 
				
			||||||
 | 
							String sessionId = response.bodyToMono(String.class).block();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 		response = webClient.get().cookie("SESSION", sessionCookie.getValue()).exchange()
 | 
				
			||||||
 | 
									.block();
 | 
				
			||||||
 | 
							assertThat(response.statusCode()).isEqualTo(HttpStatus.OK);
 | 
				
			||||||
 | 
							assertThat(response.bodyToMono(String.class).block()).isEqualTo(sessionId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Thread.sleep(1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							response = webClient.get().cookie("SESSION", sessionCookie.getValue()).exchange()
 | 
				
			||||||
 | 
									.block();
 | 
				
			||||||
 | 
							assertThat(response.statusCode()).isEqualTo(HttpStatus.UNAUTHORIZED);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						private String getBasicAuth() {
 | 
				
			||||||
 | 
							return "Basic " + Base64.getEncoder().encodeToString("user:password".getBytes());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue