diff --git a/reactive/webflux/java/authentication/one-time-token/magic-link/build.gradle b/reactive/webflux/java/authentication/one-time-token/magic-link/build.gradle index fad1294..22a7f1c 100644 --- a/reactive/webflux/java/authentication/one-time-token/magic-link/build.gradle +++ b/reactive/webflux/java/authentication/one-time-token/magic-link/build.gradle @@ -11,7 +11,6 @@ java { } repositories { - mavenLocal() mavenCentral() maven { url "https://repo.spring.io/milestone" } maven { url "https://repo.spring.io/snapshot" } diff --git a/reactive/webflux/java/authentication/one-time-token/magic-link/src/main/java/org/example/magiclink/MagicLinkOneTimeTokenGenerationSuccessHandler.java b/reactive/webflux/java/authentication/one-time-token/magic-link/src/main/java/org/example/magiclink/MagicLinkOneTimeTokenGenerationSuccessHandler.java index a302003..dec0498 100644 --- a/reactive/webflux/java/authentication/one-time-token/magic-link/src/main/java/org/example/magiclink/MagicLinkOneTimeTokenGenerationSuccessHandler.java +++ b/reactive/webflux/java/authentication/one-time-token/magic-link/src/main/java/org/example/magiclink/MagicLinkOneTimeTokenGenerationSuccessHandler.java @@ -48,13 +48,12 @@ public class MagicLinkOneTimeTokenGenerationSuccessHandler implements ServerOneT .path("/login/ott") .queryParam("token", oneTimeToken.getTokenValue()); String magicLink = builder.toUriString(); - builder - .replacePath(null) - .replaceQuery(null) - .path("/ott/sent"); + builder.replacePath(null).replaceQuery(null).path("/ott/sent"); String redirectLink = builder.toUriString(); - return this.mailSender.send("johndoe@example.com", "Your Spring Security One Time Token", - "Use the following link to sign in into the application: " + magicLink) + return this.mailSender + .send("johndoe@example.com", "Your Spring Security One Time Token", + "Use the following link to sign in into the application: " + magicLink) .then(this.redirectStrategy.sendRedirect(exchange, URI.create(redirectLink))); } + } diff --git a/reactive/webflux/java/authentication/one-time-token/magic-link/src/main/java/org/example/magiclink/SecurityConfig.java b/reactive/webflux/java/authentication/one-time-token/magic-link/src/main/java/org/example/magiclink/SecurityConfig.java index a123587..ed93f68 100644 --- a/reactive/webflux/java/authentication/one-time-token/magic-link/src/main/java/org/example/magiclink/SecurityConfig.java +++ b/reactive/webflux/java/authentication/one-time-token/magic-link/src/main/java/org/example/magiclink/SecurityConfig.java @@ -20,7 +20,6 @@ import org.springframework.boot.autoconfigure.security.reactive.PathRequest; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.Customizer; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; import org.springframework.security.config.web.server.ServerHttpSecurity; import org.springframework.security.core.userdetails.MapReactiveUserDetailsService; diff --git a/reactive/webflux/java/authentication/one-time-token/magic-link/src/test/java/org/example/magiclink/MagicLinkApplicationTests.java b/reactive/webflux/java/authentication/one-time-token/magic-link/src/test/java/org/example/magiclink/MagicLinkApplicationTests.java index fbde702..7741a8d 100644 --- a/reactive/webflux/java/authentication/one-time-token/magic-link/src/test/java/org/example/magiclink/MagicLinkApplicationTests.java +++ b/reactive/webflux/java/authentication/one-time-token/magic-link/src/test/java/org/example/magiclink/MagicLinkApplicationTests.java @@ -24,34 +24,37 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.util.UriComponents; import org.springframework.web.util.UriComponentsBuilder; import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; -import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated; -import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.unauthenticated; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import static org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers.csrf; -@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@AutoConfigureMockMvc +@SpringBootTest +@AutoConfigureWebTestClient(timeout = "30s") class MagicLinkApplicationTests { @RegisterExtension static GreenMailExtension greenMail = new GreenMailExtension(ServerSetupTest.SMTP); @Autowired - MockMvc mockMvc; + WebTestClient web; @Test void ottLoginWhenUserExistsThenSendEmailAndAuthenticate() throws Exception { - this.mockMvc.perform(post("/ott/generate").param("username", "user").with(csrf())) - .andExpectAll(status().isFound(), redirectedUrl("/ott/sent")); + this.web.mutateWith(csrf()) + .post() + .uri("/ott/generate") + .body(BodyInserters.fromFormData("username", "user")) + .exchange() + .expectStatus() + .isFound() + .expectHeader() + .location("/ott/sent"); greenMail.waitForIncomingEmail(1); MimeMessage receivedMessage = greenMail.getReceivedMessages()[0]; @@ -62,19 +65,40 @@ class MagicLinkApplicationTests { assertThat(token).isNotEmpty(); - this.mockMvc.perform(post("/login/ott").param("token", token).with(csrf())) - .andExpectAll(status().isFound(), redirectedUrl("/"), authenticated()); + this.web.mutateWith(csrf()) + .post() + .uri("/login/ott") + .body(BodyInserters.fromFormData("token", token)) + .exchange() + .expectStatus() + .isFound() + .expectHeader() + .location("/"); } @Test void ottLoginWhenInvalidTokenThenFails() throws Exception { - this.mockMvc.perform(post("/ott/generate").param("username", "user").with(csrf())) - .andExpectAll(status().isFound(), redirectedUrl("/ott/sent")); + this.web.mutateWith(csrf()) + .post() + .uri("/ott/generate") + .body(BodyInserters.fromFormData("username", "user")) + .exchange() + .expectStatus() + .isFound() + .expectHeader() + .location("/ott/sent"); String token = "1234;"; - this.mockMvc.perform(post("/login/ott").param("token", token).with(csrf())) - .andExpectAll(status().isFound(), redirectedUrl("/login?error"), unauthenticated()); + this.web.mutateWith(csrf()) + .post() + .uri("/login/ott") + .body(BodyInserters.fromFormData("token", token)) + .exchange() + .expectStatus() + .isFound() + .expectHeader() + .location("/login?error"); } }