| 
					
				 | 
			
			
				@@ -65,7 +65,7 @@ Java:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 public class SecurityConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     @Bean 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    public SecurityWebFilterChain filterChain(ServerHttpSecurity http, MagicLinkGeneratedOneTimeTokenHandler magicLinkSender) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    public SecurityWebFilterChain filterChain(ServerHttpSecurity http) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         http 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             .formLogin(Customizer.withDefaults()) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -79,11 +79,11 @@ import org.springframework.mail.SimpleMailMessage; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 import org.springframework.mail.javamail.JavaMailSender; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @Component <1> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-public class MagicLinkGeneratedOneTimeTokenHandler implements ServerGeneratedOneTimeTokenHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class MagicLinkOneTimeTokenGenerationSuccessHandler implements ServerOneTimeTokenGenerationSuccessHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     private final MailSender mailSender; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    private final ServerGeneratedOneTimeTokenHandler redirectHandler = new ServerRedirectGeneratedOneTimeTokenHandler("/ott/sent"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private final ServerOneTimeTokenGenerationSuccessHandler redirectHandler = new ServerRedirectOneTimeTokenGenerationSuccessHandler("/ott/sent"); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // constructor omitted 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -119,14 +119,72 @@ class PageController { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Kotlin:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+[source,kotlin,role="secondary"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Configuration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@EnableWebFluxSecurity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class SecurityConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         open fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             return http { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                authorizeExchange { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    authorize(anyExchange, authenticated) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 oneTimeTokenLogin { } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Component (1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class MagicLinkOneTimeTokenGenerationSuccessHandler(val mailSender: MailSender): ServerOneTimeTokenGenerationSuccessHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    private val redirectStrategy: ServerRedirectStrategy = DefaultServerRedirectStrategy() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    override fun handle(exchange: ServerWebExchange, oneTimeToken: OneTimeToken): Mono<Void> { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        val builder = UriComponentsBuilder.fromUri(exchange.request.uri) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .replacePath(null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .replaceQuery(null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .fragment(null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .path("/login/ott") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .queryParam("token", oneTimeToken.getTokenValue()) (2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        val magicLink = builder.toUriString() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        builder.replacePath(null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .replaceQuery(null) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            .path("/ott/sent") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        val redirectLink = builder.toUriString() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return this.mailSender.send( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            getUserEmail(oneTimeToken.getUsername()), (3) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            "Use the following link to sign in into the application: $magicLink") (4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        .then(this.redirectStrategy.sendRedirect(exchange, URI.create(redirectLink))) (5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        private String getUserEmail() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Controller 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class PageController { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @GetMapping("/ott/sent") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fun ottSent(): String { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return "my-template" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ====== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-<1> Make the `MagicLinkGeneratedOneTimeTokenHandler` a Spring bean 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+<1> Make the `MagicLinkOneTimeTokenGenerationSuccessHandler` a Spring bean 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <2> Create a login processing URL with the `token` as a query param 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 <3> Retrieve the user's email based on the username 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-<4> Use the `JavaMailSender` API to send the email to the user with the magic link 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-<5> Use the `ServerRedirectOneTimeTokenGenerationSuccessHandler` to perform a redirect to your desired URL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+<4> Use the `MailSender` API to send the email to the user with the magic link 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+<5> Use the `ServerRedirectStrategy` to perform a redirect to your desired URL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 The email content will look similar to: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -165,9 +223,36 @@ public class SecurityConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-public class MagicLinkGeneratedOneTimeTokenHandler implements ServerGeneratedOneTimeTokenHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class MagicLinkOneTimeTokenGenerationSuccessHandler implements ServerOneTimeTokenGenerationSuccessHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Kotlin:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+[source,kotlin,role="secondary"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Configuration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@EnableWebFluxSecurity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class SecurityConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         open fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             return http { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 formLogin { } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 oneTimeTokenLogin { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    generateTokenUrl = "/ott/my-generate-url" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class MagicLinkOneTimeTokenGenerationSuccessHandler(val mailSender: MailSender): ServerOneTimeTokenGenerationSuccessHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ====== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -202,9 +287,36 @@ public class SecurityConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-public class MagicLinkGeneratedOneTimeTokenHandler implements ServerGeneratedOneTimeTokenHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class MagicLinkOneTimeTokenGenerationSuccessHandler implements ServerOneTimeTokenGenerationSuccessHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Kotlin:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+[source,kotlin,role="secondary"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Configuration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@EnableWebFluxSecurity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class SecurityConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         open fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             return http { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 formLogin { } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 oneTimeTokenLogin { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    submitPageUrl = "/ott/submit" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class MagicLinkOneTimeTokenGenerationSuccessHandler(val mailSender: MailSender): ServerOneTimeTokenGenerationSuccessHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ====== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -251,9 +363,48 @@ public class MyController { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-public class MagicLinkGeneratedOneTimeTokenHandler implements ServerGeneratedOneTimeTokenHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class MagicLinkOneTimeTokenGenerationSuccessHandler implements ServerOneTimeTokenGenerationSuccessHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Kotlin:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+[source,kotlin,role="secondary"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Configuration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@EnableWebFluxSecurity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class SecurityConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         open fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             return http { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                authorizeExchange { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    authorize(pathMatchers("/my-ott-submit"), permitAll) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    authorize(anyExchange, authenticated) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 .formLogin { } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 oneTimeTokenLogin { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    showDefaultSubmitPage = false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Controller 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class MyController { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    @GetMapping("/my-ott-submit") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fun ottSubmitPage(): String { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return "my-ott-submit" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class MagicLinkOneTimeTokenGenerationSuccessHandler(val mailSender: MailSender): ServerOneTimeTokenGenerationSuccessHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ====== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -301,9 +452,39 @@ public class SecurityConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-public class MagicLinkGeneratedOneTimeTokenHandler implements ServerGeneratedOneTimeTokenHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class MagicLinkOneTimeTokenGenerationSuccessHandler implements ServerOneTimeTokenGenerationSuccessHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Kotlin:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+[source,kotlin,role="secondary"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Configuration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@EnableWebFluxSecurity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class SecurityConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         open fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             return http { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 //.. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 .formLogin { } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 oneTimeTokenLogin { } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         @Bean 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         open fun oneTimeTokenService():ReactiveOneTimeTokenService { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             return MyCustomReactiveOneTimeTokenService(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class MagicLinkOneTimeTokenGenerationSuccessHandler(val mailSender: MailSender): ServerOneTimeTokenGenerationSuccessHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ====== 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -334,8 +515,34 @@ public class SecurityConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 @Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-public class MagicLinkGeneratedOneTimeTokenHandler implements ServerGeneratedOneTimeTokenHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+public class MagicLinkOneTimeTokenGenerationSuccessHandler implements ServerOneTimeTokenGenerationSuccessHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Kotlin:: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+[source,kotlin,role="secondary"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Configuration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@EnableWebFluxSecurity 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class SecurityConfig { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         open fun springWebFilterChain(http: ServerHttpSecurity): SecurityWebFilterChain { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             return http { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 //.. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 .formLogin { } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 oneTimeTokenLogin { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    oneTimeTokenService = MyCustomReactiveOneTimeTokenService() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@Component 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+class MagicLinkOneTimeTokenGenerationSuccessHandler(val mailSender: MailSender): ServerOneTimeTokenGenerationSuccessHandler { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // ... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ---- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 ====== 
			 |