diff --git a/spring-boot-autoconfigure/pom.xml b/spring-boot-autoconfigure/pom.xml
index 070a4ad44b..a8ce696c03 100755
--- a/spring-boot-autoconfigure/pom.xml
+++ b/spring-boot-autoconfigure/pom.xml
@@ -527,6 +527,11 @@
spring-security-data
true
+
+ org.springframework.security
+ spring-security-webflux
+ true
+
org.springframework.session
spring-session-core
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveAuthenticationManagerConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveAuthenticationManagerConfiguration.java
new file mode 100644
index 0000000000..650b2f7f5a
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveAuthenticationManagerConfiguration.java
@@ -0,0 +1,64 @@
+/*
+ * 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 org.springframework.boot.autoconfigure.security.reactive;
+
+import java.util.UUID;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.security.authentication.ReactiveAuthenticationManager;
+import org.springframework.security.core.userdetails.MapUserDetailsRepository;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsRepository;
+
+/**
+ * Default user {@link Configuration} for a reactive web application.
+ * Configures a {@link UserDetailsRepository} with a default user and generated password.
+ * This backs-off completely if there is a bean of type {@link UserDetailsRepository}
+ * or {@link ReactiveAuthenticationManager}.
+ *
+ * @author Madhura Bhave
+ * @since 2.0.0
+ */
+@Configuration
+@ConditionalOnClass({ReactiveAuthenticationManager.class})
+@ConditionalOnMissingBean({ReactiveAuthenticationManager.class, UserDetailsRepository.class })
+@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
+public class ReactiveAuthenticationManagerConfiguration {
+
+ private static final Log logger = LogFactory
+ .getLog(ReactiveAuthenticationManagerConfiguration.class);
+
+ @Bean
+ public MapUserDetailsRepository userDetailsRepository() {
+ String password = UUID.randomUUID().toString();
+ logger.info(
+ String.format("%n%nUsing default security password: %s%n", password));
+ UserDetails user = User.withUsername("user")
+ .password(password)
+ .roles()
+ .build();
+ return new MapUserDetailsRepository(user);
+ }
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveSecurityAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveSecurityAutoConfiguration.java
new file mode 100644
index 0000000000..f7cf2cc3f9
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveSecurityAutoConfiguration.java
@@ -0,0 +1,41 @@
+/*
+ * 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 org.springframework.boot.autoconfigure.security.reactive;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
+import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
+import org.springframework.security.web.reactive.result.method.annotation.AuthenticationPrincipalArgumentResolver;
+
+/**
+ * {@link EnableAutoConfiguration Auto-configuration} for Spring Security in a
+ * reactive application. This auto-configuration adds {@link EnableWebFluxSecurity}
+ * and delegates to Spring Security's content-negotiation mechanism for authentication.
+ * In a webapp this configuration also secures all web endpoints.
+ *
+ * @author Madhura Bhave
+ * @since 2.0.0
+ */
+@Configuration
+@ConditionalOnClass({EnableWebFluxSecurity.class, AuthenticationPrincipalArgumentResolver.class})
+@Import({ WebfluxSecurityConfiguration.class,
+ ReactiveAuthenticationManagerConfiguration.class })
+public class ReactiveSecurityAutoConfiguration {
+
+}
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/WebfluxSecurityConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/WebfluxSecurityConfiguration.java
new file mode 100644
index 0000000000..8e0f7b1afe
--- /dev/null
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/security/reactive/WebfluxSecurityConfiguration.java
@@ -0,0 +1,38 @@
+/*
+ * 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 org.springframework.boot.autoconfigure.security.reactive;
+
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
+import org.springframework.security.config.annotation.web.reactive.WebFluxSecurityConfiguration;
+
+/**
+ * Switches on {@link EnableWebFluxSecurity} for a reactive web application
+ * if this annotation has not been added by the user.
+ *
+ * @author Madhura Bhave
+ * @since 2.0.0
+ */
+@ConditionalOnClass(EnableWebFluxSecurity.class)
+@ConditionalOnMissingBean(WebFluxSecurityConfiguration.class)
+@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)
+@EnableWebFluxSecurity
+public class WebfluxSecurityConfiguration {
+
+}
diff --git a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
index dc62226cd2..6d6a28959a 100644
--- a/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
+++ b/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories
@@ -99,6 +99,7 @@ org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\
+org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveSecurityAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveSecurityAutoConfigurationTests.java
new file mode 100644
index 0000000000..b875e214b4
--- /dev/null
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/reactive/ReactiveSecurityAutoConfigurationTests.java
@@ -0,0 +1,139 @@
+/*
+ * 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 org.springframework.boot.autoconfigure.security.reactive;
+
+import org.junit.Test;
+import reactor.core.publisher.Mono;
+
+import org.springframework.boot.autoconfigure.AutoConfigurations;
+import org.springframework.boot.autoconfigure.web.reactive.MockReactiveWebServerFactory;
+import org.springframework.boot.test.context.runner.ApplicationContextRunner;
+import org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext;
+import org.springframework.boot.web.reactive.server.ReactiveWebServerFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.server.reactive.HttpHandler;
+import org.springframework.security.authentication.ReactiveAuthenticationManager;
+import org.springframework.security.config.annotation.web.reactive.HttpSecurityConfiguration;
+import org.springframework.security.config.annotation.web.reactive.WebFluxSecurityConfiguration;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.userdetails.MapUserDetailsRepository;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsRepository;
+import org.springframework.security.web.server.WebFilterChainFilter;
+import org.springframework.web.reactive.config.EnableWebFlux;
+import org.springframework.web.server.adapter.WebHttpHandlerBuilder;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link ReactiveSecurityAutoConfiguration}.
+ *
+ * @author Madhura Bhave
+ */
+public class ReactiveSecurityAutoConfigurationTests {
+
+ private ApplicationContextRunner contextRunner = new ApplicationContextRunner(ReactiveWebServerApplicationContext::new);
+
+ @Test
+ public void enablesWebFluxSecurity() {
+ this.contextRunner.withUserConfiguration(TestConfig.class)
+ .withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class))
+ .run(context -> {
+ assertThat(context).getBean(HttpSecurityConfiguration.class).isNotNull();
+ assertThat(context).getBean(WebFluxSecurityConfiguration.class).isNotNull();
+ assertThat(context).getBean(WebFilterChainFilter.class).isNotNull();
+ });
+ }
+
+ @Test
+ public void configuresADefaultUser() {
+ this.contextRunner.withUserConfiguration(TestConfig.class)
+ .withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class))
+ .run(context -> {
+ UserDetailsRepository userDetailsRepository = context.getBean(UserDetailsRepository.class);
+ assertThat(userDetailsRepository.findByUsername("user").block()).isNotNull();
+ });
+ }
+
+ @Test
+ public void doesNotConfigureDefaultUserIfUserDetailsRepositoryAvailable() {
+ this.contextRunner.withUserConfiguration(UserConfig.class, TestConfig.class)
+ .withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class))
+ .run(context -> {
+ UserDetailsRepository userDetailsRepository = context.getBean(UserDetailsRepository.class);
+ assertThat(userDetailsRepository.findByUsername("user").block()).isNull();
+ assertThat(userDetailsRepository.findByUsername("foo").block()).isNotNull();
+ assertThat(userDetailsRepository.findByUsername("admin").block()).isNotNull();
+ });
+ }
+
+ @Test
+ public void doesNotConfigureDefaultUserIfAuthenticationManagerAvailable() {
+ this.contextRunner.withUserConfiguration(AuthenticationManagerConfig.class, TestConfig.class)
+ .withConfiguration(AutoConfigurations.of(ReactiveSecurityAutoConfiguration.class))
+ .run(context -> {
+ assertThat(context).getBean(UserDetailsRepository.class).isNull();
+ });
+ }
+
+ @Configuration
+ @EnableWebFlux
+ static class TestConfig {
+
+ @Bean
+ public HttpHandler httpHandler(ApplicationContext applicationContext) {
+ return WebHttpHandlerBuilder.applicationContext(applicationContext).build();
+ }
+
+ @Bean
+ public ReactiveWebServerFactory reactiveWebServerFactory() {
+ return new MockReactiveWebServerFactory();
+ }
+
+ }
+
+ @Configuration
+ static class UserConfig {
+
+ @Bean
+ public MapUserDetailsRepository userDetailsRepository() {
+ UserDetails foo = User.withUsername("foo").password("foo").roles("USER").build();
+ UserDetails admin = User.withUsername("admin").password("admin").roles("USER", "ADMIN").build();
+ return new MapUserDetailsRepository(foo, admin);
+ }
+
+ }
+
+ @Configuration
+ static class AuthenticationManagerConfig {
+
+ @Bean
+ public ReactiveAuthenticationManager reactiveAuthenticationManager() {
+ return new ReactiveAuthenticationManager() {
+ @Override
+ public Mono authenticate(Authentication authentication) {
+ return null;
+ }
+ };
+ }
+
+ }
+
+}
diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml
index 78d710678e..b510c7e6a0 100644
--- a/spring-boot-dependencies/pom.xml
+++ b/spring-boot-dependencies/pom.xml
@@ -506,6 +506,11 @@
spring-boot-starter-security
2.0.0.BUILD-SNAPSHOT
+
+ org.springframework.boot
+ spring-boot-starter-security-reactive
+ 2.0.0.BUILD-SNAPSHOT
+
org.springframework.boot
spring-boot-starter-social-facebook
diff --git a/spring-boot-samples/pom.xml b/spring-boot-samples/pom.xml
index 4c652f926e..e29d7b0207 100644
--- a/spring-boot-samples/pom.xml
+++ b/spring-boot-samples/pom.xml
@@ -67,6 +67,7 @@
spring-boot-sample-property-validation
spring-boot-sample-quartz
spring-boot-sample-secure
+ spring-boot-sample-secure-webflux
spring-boot-sample-servlet
spring-boot-sample-session
spring-boot-sample-simple
diff --git a/spring-boot-samples/spring-boot-sample-secure-webflux/pom.xml b/spring-boot-samples/spring-boot-sample-secure-webflux/pom.xml
new file mode 100644
index 0000000000..d1681faaeb
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-secure-webflux/pom.xml
@@ -0,0 +1,64 @@
+
+
+ 4.0.0
+
+
+ org.springframework.boot
+ spring-boot-samples
+ 2.0.0.BUILD-SNAPSHOT
+
+ spring-boot-sample-secure-webflux
+ Spring Boot Secure WebFlux Sample
+ Spring Boot Secure WebFlux Sample
+ http://projects.spring.io/spring-boot/
+
+ Pivotal Software, Inc.
+ http://www.spring.io
+
+
+ ${basedir}/../..
+ /
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-webflux
+
+
+ org.springframework.boot
+ spring-boot-starter-actuator
+
+
+ org.springframework.boot
+ spring-boot-starter-security-reactive
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ io.projectreactor
+ reactor-test
+ test
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+ generate build info
+
+ build-info
+
+
+
+
+
+
+
diff --git a/spring-boot-samples/spring-boot-sample-secure-webflux/src/main/java/sample/secure/webflux/EchoHandler.java b/spring-boot-samples/spring-boot-sample-secure-webflux/src/main/java/sample/secure/webflux/EchoHandler.java
new file mode 100644
index 0000000000..62f53e2e01
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-secure-webflux/src/main/java/sample/secure/webflux/EchoHandler.java
@@ -0,0 +1,32 @@
+/*
+ * 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.secure.webflux;
+
+import reactor.core.publisher.Mono;
+
+import org.springframework.stereotype.Component;
+import org.springframework.web.reactive.function.server.ServerRequest;
+import org.springframework.web.reactive.function.server.ServerResponse;
+
+@Component
+public class EchoHandler {
+
+ public Mono echo(ServerRequest request) {
+ return ServerResponse.ok().body(request.bodyToMono(String.class), String.class);
+ }
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-secure-webflux/src/main/java/sample/secure/webflux/SampleSecureWebFluxApplication.java b/spring-boot-samples/spring-boot-sample-secure-webflux/src/main/java/sample/secure/webflux/SampleSecureWebFluxApplication.java
new file mode 100644
index 0000000000..2da5698fe2
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-secure-webflux/src/main/java/sample/secure/webflux/SampleSecureWebFluxApplication.java
@@ -0,0 +1,50 @@
+/*
+ * 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.secure.webflux;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.security.core.userdetails.MapUserDetailsRepository;
+import org.springframework.security.core.userdetails.User;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.security.core.userdetails.UserDetailsRepository;
+import org.springframework.web.reactive.function.server.RouterFunction;
+import org.springframework.web.reactive.function.server.ServerResponse;
+
+import static org.springframework.web.reactive.function.server.RequestPredicates.POST;
+import static org.springframework.web.reactive.function.server.RouterFunctions.route;
+
+@SpringBootApplication
+public class SampleSecureWebFluxApplication {
+
+ public static void main(String[] args) throws Exception {
+ SpringApplication.run(SampleSecureWebFluxApplication.class);
+ }
+
+ @Bean
+ public RouterFunction monoRouterFunction(EchoHandler echoHandler) {
+ return route(POST("/echo"), echoHandler::echo);
+ }
+
+ @Bean
+ public UserDetailsRepository userDetailsRepository() {
+ UserDetails user = User.withUsername("foo").password("password").roles("USER").build();
+ return new MapUserDetailsRepository(user);
+ }
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-secure-webflux/src/main/java/sample/secure/webflux/WelcomeController.java b/spring-boot-samples/spring-boot-sample-secure-webflux/src/main/java/sample/secure/webflux/WelcomeController.java
new file mode 100644
index 0000000000..b5a14ad3b0
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-secure-webflux/src/main/java/sample/secure/webflux/WelcomeController.java
@@ -0,0 +1,32 @@
+/*
+ * 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.secure.webflux;
+
+import java.security.Principal;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class WelcomeController {
+
+ @GetMapping("/")
+ public String welcome(Principal principal) {
+ return "Hello " + principal.getName();
+ }
+
+}
diff --git a/spring-boot-samples/spring-boot-sample-secure-webflux/src/main/resources/application.properties b/spring-boot-samples/spring-boot-sample-secure-webflux/src/main/resources/application.properties
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/spring-boot-samples/spring-boot-sample-secure-webflux/src/test/java/sample/secure/webflux/SampleSecureWebFluxApplicationTests.java b/spring-boot-samples/spring-boot-sample-secure-webflux/src/test/java/sample/secure/webflux/SampleSecureWebFluxApplicationTests.java
new file mode 100644
index 0000000000..4ff0f3a442
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-secure-webflux/src/test/java/sample/secure/webflux/SampleSecureWebFluxApplicationTests.java
@@ -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.secure.webflux;
+
+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.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.test.web.reactive.server.WebTestClient;
+
+/**
+ * Integration tests for a secure reactive application.
+ *
+ * @author Madhura Bhave
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
+@DirtiesContext
+public class SampleSecureWebFluxApplicationTests {
+
+ @Autowired
+ private WebTestClient webClient;
+
+ @Test
+ public void userDefinedMappingsSecureByDefault() {
+ this.webClient.get().uri("/").accept(MediaType.APPLICATION_JSON).exchange()
+ .expectStatus().isEqualTo(HttpStatus.UNAUTHORIZED);
+ }
+
+ @Test
+ public void actuatorsSecureByDefault() {
+ this.webClient.get().uri("/application/status").accept(MediaType.APPLICATION_JSON)
+ .exchange().expectStatus().isUnauthorized();
+ }
+
+ @Test
+ public void userDefinedMappingsAccessibleOnLogin() {
+ this.webClient.get().uri("/").accept(MediaType.APPLICATION_JSON)
+ .header("Authorization", "basic " + getBasicAuth())
+ .exchange()
+ .expectBody(String.class).isEqualTo("Hello foo");
+ }
+
+ @Test
+ public void actuatorsAccessibleOnLogin() {
+ this.webClient.get().uri("/application/status").accept(MediaType.APPLICATION_JSON)
+ .header("Authorization", "basic " + getBasicAuth())
+ .exchange()
+ .expectBody(String.class).isEqualTo("{\"status\":\"UP\"}");
+ }
+
+ private String getBasicAuth() {
+ return new String(Base64.getEncoder().encode(("foo:password").getBytes()));
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-starters/pom.xml b/spring-boot-starters/pom.xml
index 59821bbf52..c60fb8c16b 100644
--- a/spring-boot-starters/pom.xml
+++ b/spring-boot-starters/pom.xml
@@ -63,6 +63,7 @@
spring-boot-starter-quartz
spring-boot-starter-reactor-netty
spring-boot-starter-security
+ spring-boot-starter-security-reactive
spring-boot-starter-social-facebook
spring-boot-starter-social-twitter
spring-boot-starter-social-linkedin
diff --git a/spring-boot-starters/spring-boot-starter-security-reactive/pom.xml b/spring-boot-starters/spring-boot-starter-security-reactive/pom.xml
new file mode 100644
index 0000000000..e6b797b7f0
--- /dev/null
+++ b/spring-boot-starters/spring-boot-starter-security-reactive/pom.xml
@@ -0,0 +1,50 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starters
+ 2.0.0.BUILD-SNAPSHOT
+
+ spring-boot-starter-security-reactive
+ Spring Boot Security Reactive Starter
+ Starter for using reactive Spring Security
+ http://projects.spring.io/spring-boot/
+
+ Pivotal Software, Inc.
+ http://www.spring.io
+
+
+ ${basedir}/../..
+
+
+
+ org.springframework.boot
+ spring-boot-starter
+
+
+ org.springframework
+ spring-aop
+
+
+ org.springframework.security
+ spring-security-config
+
+
+ aopalliance
+ aopalliance
+
+
+
+
+ org.springframework.security
+ spring-security-webflux
+
+
+ aopalliance
+ aopalliance
+
+
+
+
+
diff --git a/spring-boot-starters/spring-boot-starter-security-reactive/src/main/resources/META-INF/spring.provides b/spring-boot-starters/spring-boot-starter-security-reactive/src/main/resources/META-INF/spring.provides
new file mode 100644
index 0000000000..5001b7f780
--- /dev/null
+++ b/spring-boot-starters/spring-boot-starter-security-reactive/src/main/resources/META-INF/spring.provides
@@ -0,0 +1 @@
+provides: spring-security-webflux,spring-security-config
\ No newline at end of file