13. WebFlux Support

Spring Security provides test integration with Spring WebFlux for both method security and WebFlux. You can find a complete working sample at hellowebflux-method

13.1 Reactive Method Security

For example, we can test our example from ??? using the same setup and annotations we did in Chapter 11, Testing Method Security. Here is a minimal sample of what we can do:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = HelloWebfluxMethodApplication.class)
public class HelloWorldMessageServiceTests {
	@Autowired
	HelloWorldMessageService messages;

	@Test
	public void messagesWhenNotAuthenticatedThenDenied() {
		StepVerifier.create(this.messages.findMessage())
			.expectError(AccessDeniedException.class)
			.verify();
	}

	@Test
	@WithMockUser
	public void messagesWhenUserThenDenied() {
		StepVerifier.create(this.messages.findMessage())
			.expectError(AccessDeniedException.class)
			.verify();
	}

	@Test
	@WithMockUser(roles = "ADMIN")
	public void messagesWhenAdminThenOk() {
		StepVerifier.create(this.messages.findMessage())
			.expectNext("Hello World!")
			.verifyComplete();
	}
}

13.2 WebTestClientSupport

Spring Security provides integration with WebTestClient. The basic setup looks like this:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = HelloWebfluxMethodApplication.class)
public class HelloWebfluxMethodApplicationTests {
	@Autowired
	ApplicationContext context;

	WebTestClient rest;

	@Before
	public void setup() {
		this.rest = WebTestClient
			.bindToApplicationContext(this.context)
			// add Spring Security test Support
			.apply(springSecurity())
			.configureClient()
			.filter(basicAuthentication())
			.build();
	}
	// ...
}

13.2.1 Authentication

After applying the Spring Security support to WebTestClient we can use either annotations or mutateWith support. For example:

@Test
public void messageWhenNotAuthenticated() throws Exception {
	this.rest
		.get()
		.uri("/message")
		.exchange()
		.expectStatus().isUnauthorized();
}

// --- WithMockUser ---

@Test
@WithMockUser
public void messageWhenWithMockUserThenForbidden() throws Exception {
	this.rest
		.get()
		.uri("/message")
		.exchange()
		.expectStatus().isEqualTo(HttpStatus.FORBIDDEN);
}

@Test
@WithMockUser(roles = "ADMIN")
public void messageWhenWithMockAdminThenOk() throws Exception {
	this.rest
		.get()
		.uri("/message")
		.exchange()
		.expectStatus().isOk()
		.expectBody(String.class).isEqualTo("Hello World!");
}

// --- mutateWith mockUser ---

@Test
public void messageWhenMutateWithMockUserThenForbidden() throws Exception {
	this.rest
		.mutateWith(mockUser())
		.get()
		.uri("/message")
		.exchange()
		.expectStatus().isEqualTo(HttpStatus.FORBIDDEN);
}

@Test
public void messageWhenMutateWithMockAdminThenOk() throws Exception {
	this.rest
		.mutateWith(mockUser().roles("ADMIN"))
		.get()
		.uri("/message")
		.exchange()
		.expectStatus().isOk()
		.expectBody(String.class).isEqualTo("Hello World!");
}

13.2.2 CSRF Support

Spring Security also provides support for CSRF testing with WebTestClient. For example:

this.rest
	// provide a valid CSRF token
	.mutateWith(csrf())
	.post()
	.uri("/login")
	...