mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-06-25 21:42:17 +00:00
Polish One-Time Token API Names and Doc
The names of variables and methods have been adjusted in accordance with the names of the one-time token login API components. Issue gh-15114
This commit is contained in:
parent
e9fe6360bc
commit
d37d41c130
@ -3003,8 +3003,8 @@ public final class HttpSecurity extends AbstractConfiguredSecurityBuilder<Defaul
|
||||
* }
|
||||
*
|
||||
* @Bean
|
||||
* public GeneratedOneTimeTokenHandler generatedOneTimeTokenHandler() {
|
||||
* return new MyMagicLinkGeneratedOneTimeTokenHandler();
|
||||
* public OneTimeTokenGenerationSuccessHandler oneTimeTokenGenerationSuccessHandler() {
|
||||
* return new MyMagicLinkOneTimeTokenGenerationSuccessHandler();
|
||||
* }
|
||||
*
|
||||
* }
|
||||
|
@ -133,19 +133,19 @@ public final class OneTimeTokenLoginConfigurer<H extends HttpSecurityBuilder<H>>
|
||||
|
||||
private void configureOttGenerateFilter(H http) {
|
||||
GenerateOneTimeTokenFilter generateFilter = new GenerateOneTimeTokenFilter(getOneTimeTokenService(http),
|
||||
getGeneratedOneTimeTokenHandler(http));
|
||||
getOneTimeTokenGenerationSuccessHandler(http));
|
||||
generateFilter.setRequestMatcher(antMatcher(HttpMethod.POST, this.tokenGeneratingUrl));
|
||||
http.addFilter(postProcess(generateFilter));
|
||||
http.addFilter(DefaultResourcesFilter.css());
|
||||
}
|
||||
|
||||
private OneTimeTokenGenerationSuccessHandler getGeneratedOneTimeTokenHandler(H http) {
|
||||
private OneTimeTokenGenerationSuccessHandler getOneTimeTokenGenerationSuccessHandler(H http) {
|
||||
if (this.oneTimeTokenGenerationSuccessHandler == null) {
|
||||
this.oneTimeTokenGenerationSuccessHandler = getBeanOrNull(http, OneTimeTokenGenerationSuccessHandler.class);
|
||||
}
|
||||
if (this.oneTimeTokenGenerationSuccessHandler == null) {
|
||||
throw new IllegalStateException("""
|
||||
A GeneratedOneTimeTokenHandler is required to enable oneTimeTokenLogin().
|
||||
A OneTimeTokenGenerationSuccessHandler is required to enable oneTimeTokenLogin().
|
||||
Please provide it as a bean or pass it to the oneTimeTokenLogin() DSL.
|
||||
""");
|
||||
}
|
||||
@ -200,7 +200,7 @@ public final class OneTimeTokenLoginConfigurer<H extends HttpSecurityBuilder<H>>
|
||||
*/
|
||||
public OneTimeTokenLoginConfigurer<H> tokenGenerationSuccessHandler(
|
||||
OneTimeTokenGenerationSuccessHandler oneTimeTokenGenerationSuccessHandler) {
|
||||
Assert.notNull(oneTimeTokenGenerationSuccessHandler, "generatedOneTimeTokenHandler cannot be null");
|
||||
Assert.notNull(oneTimeTokenGenerationSuccessHandler, "oneTimeTokenGenerationSuccessHandler cannot be null");
|
||||
this.oneTimeTokenGenerationSuccessHandler = oneTimeTokenGenerationSuccessHandler;
|
||||
return this;
|
||||
}
|
||||
|
@ -1578,8 +1578,8 @@ public class ServerHttpSecurity {
|
||||
* }
|
||||
*
|
||||
* @Bean
|
||||
* public ServerGeneratedOneTimeTokenHandler generatedOneTimeTokenHandler() {
|
||||
* return new MyMagicLinkServerGeneratedOneTimeTokenHandler();
|
||||
* public ServerOneTimeTokenGenerationSuccessHandler oneTimeTokenGenerationSuccessHandler() {
|
||||
* return new MyMagicLinkServerOneTimeTokenGenerationSuccessHandler();
|
||||
* }
|
||||
*
|
||||
* }
|
||||
@ -6151,12 +6151,12 @@ public class ServerHttpSecurity {
|
||||
|
||||
/**
|
||||
* Specifies strategy to be used to handle generated one-time tokens.
|
||||
* @param generatedOneTimeTokenHandler
|
||||
* @param oneTimeTokenGenerationSuccessHandler
|
||||
*/
|
||||
public OneTimeTokenLoginSpec tokenGenerationSuccessHandler(
|
||||
ServerOneTimeTokenGenerationSuccessHandler generatedOneTimeTokenHandler) {
|
||||
Assert.notNull(generatedOneTimeTokenHandler, "generatedOneTimeTokenHandler cannot be null");
|
||||
this.tokenGenerationSuccessHandler = generatedOneTimeTokenHandler;
|
||||
ServerOneTimeTokenGenerationSuccessHandler oneTimeTokenGenerationSuccessHandler) {
|
||||
Assert.notNull(oneTimeTokenGenerationSuccessHandler, "oneTimeTokenGenerationSuccessHandler cannot be null");
|
||||
this.tokenGenerationSuccessHandler = oneTimeTokenGenerationSuccessHandler;
|
||||
return this;
|
||||
}
|
||||
|
||||
@ -6193,7 +6193,7 @@ public class ServerHttpSecurity {
|
||||
}
|
||||
if (this.tokenGenerationSuccessHandler == null) {
|
||||
throw new IllegalStateException("""
|
||||
A ServerGeneratedOneTimeTokenHandler is required to enable oneTimeTokenLogin().
|
||||
A ServerOneTimeTokenGenerationSuccessHandler is required to enable oneTimeTokenLogin().
|
||||
Please provide it as a bean or pass it to the oneTimeTokenLogin() DSL.
|
||||
""");
|
||||
}
|
||||
|
@ -985,7 +985,7 @@ class HttpSecurityDsl(private val http: HttpSecurity, private val init: HttpSecu
|
||||
* fun securityFilterChain(http: HttpSecurity): SecurityFilterChain {
|
||||
* http {
|
||||
* oneTimeTokenLogin {
|
||||
* generatedOneTimeTokenHandler = MyMagicLinkGeneratedOneTimeTokenHandler()
|
||||
* oneTimeTokenGenerationSuccessHandler = MyMagicLinkOneTimeTokenGenerationSuccessHandler()
|
||||
* }
|
||||
* }
|
||||
* return http.build()
|
||||
|
@ -189,7 +189,7 @@ public class OneTimeTokenLoginConfigurerTests {
|
||||
.havingRootCause()
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.withMessage("""
|
||||
A GeneratedOneTimeTokenHandler is required to enable oneTimeTokenLogin().
|
||||
A OneTimeTokenGenerationSuccessHandler is required to enable oneTimeTokenLogin().
|
||||
Please provide it as a bean or pass it to the oneTimeTokenLogin() DSL.
|
||||
""");
|
||||
}
|
||||
|
@ -269,13 +269,13 @@ public class OneTimeTokenLoginSpecTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
void oneTimeTokenWhenNoGeneratedOneTimeTokenHandlerThenException() {
|
||||
void oneTimeTokenWhenNoOneTimeTokenGenerationSuccessHandlerThenException() {
|
||||
assertThatException()
|
||||
.isThrownBy(() -> this.spring.register(OneTimeTokenNotGeneratedOttHandlerConfig.class).autowire())
|
||||
.havingRootCause()
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.withMessage("""
|
||||
A ServerGeneratedOneTimeTokenHandler is required to enable oneTimeTokenLogin().
|
||||
A ServerOneTimeTokenGenerationSuccessHandler is required to enable oneTimeTokenLogin().
|
||||
Please provide it as a bean or pass it to the oneTimeTokenLogin() DSL.
|
||||
""");
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ class OneTimeTokenLoginDslTests {
|
||||
.redirectedUrl("/login/ott")
|
||||
)
|
||||
|
||||
val token = TestGeneratedOneTimeTokenHandler.lastToken?.tokenValue
|
||||
val token = TestOneTimeTokenGenerationSuccessHandler.lastToken?.tokenValue
|
||||
|
||||
this.mockMvc.perform(
|
||||
MockMvcRequestBuilders.post("/login/ott").param("token", token)
|
||||
@ -91,7 +91,7 @@ class OneTimeTokenLoginDslTests {
|
||||
)
|
||||
.andExpectAll(MockMvcResultMatchers.status().isFound(), MockMvcResultMatchers.redirectedUrl("/redirected"))
|
||||
|
||||
val token = TestGeneratedOneTimeTokenHandler.lastToken?.tokenValue
|
||||
val token = TestOneTimeTokenGenerationSuccessHandler.lastToken?.tokenValue
|
||||
|
||||
this.mockMvc.perform(
|
||||
MockMvcRequestBuilders.post("/loginprocessingurl").param("token", token)
|
||||
@ -117,7 +117,7 @@ class OneTimeTokenLoginDslTests {
|
||||
authorize(anyRequest, authenticated)
|
||||
}
|
||||
oneTimeTokenLogin {
|
||||
oneTimeTokenGenerationSuccessHandler = TestGeneratedOneTimeTokenHandler()
|
||||
oneTimeTokenGenerationSuccessHandler = TestOneTimeTokenGenerationSuccessHandler()
|
||||
}
|
||||
}
|
||||
// @formatter:on
|
||||
@ -138,7 +138,7 @@ class OneTimeTokenLoginDslTests {
|
||||
}
|
||||
oneTimeTokenLogin {
|
||||
tokenGeneratingUrl = "/generateurl"
|
||||
oneTimeTokenGenerationSuccessHandler = TestGeneratedOneTimeTokenHandler("/redirected")
|
||||
oneTimeTokenGenerationSuccessHandler = TestOneTimeTokenGenerationSuccessHandler("/redirected")
|
||||
loginProcessingUrl = "/loginprocessingurl"
|
||||
authenticationSuccessHandler = SimpleUrlAuthenticationSuccessHandler("/authenticated")
|
||||
}
|
||||
@ -156,7 +156,7 @@ class OneTimeTokenLoginDslTests {
|
||||
InMemoryUserDetailsManager(PasswordEncodedUser.user(), PasswordEncodedUser.admin())
|
||||
}
|
||||
|
||||
private class TestGeneratedOneTimeTokenHandler :
|
||||
private class TestOneTimeTokenGenerationSuccessHandler :
|
||||
OneTimeTokenGenerationSuccessHandler {
|
||||
private val delegate: OneTimeTokenGenerationSuccessHandler
|
||||
|
||||
|
@ -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 {
|
||||
// ...
|
||||
}
|
||||
|
||||
----
|
||||
======
|
||||
|
@ -65,7 +65,7 @@ Java::
|
||||
public class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain filterChain(HttpSecurity http, MagicLinkGeneratedOneTimeTokenHandler magicLinkSender) {
|
||||
public SecurityFilterChain filterChain(HttpSecurity 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 GeneratedOneTimeTokenSuccessHandler {
|
||||
public class MagicLinkOneTimeTokenGenerationSuccessHandler implements OneTimeTokenGenerationSuccessHandler {
|
||||
|
||||
private final MailSender mailSender;
|
||||
|
||||
private final GeneratedOneTimeTokenHandler redirectHandler = new RedirectGeneratedOneTimeTokenHandler("/ott/sent");
|
||||
private final OneTimeTokenGenerationSuccessHandler redirectHandler = new RedirectOneTimeTokenGenerationSuccessHandler("/ott/sent");
|
||||
|
||||
// constructor omitted
|
||||
|
||||
@ -128,10 +128,7 @@ Kotlin::
|
||||
class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
open fun filterChain(
|
||||
http: HttpSecurity,
|
||||
magicLinkSender: MagicLinkGeneratedOneTimeTokenSuccessHandler?
|
||||
): SecurityFilterChain {
|
||||
open fun filterChain(http: HttpSecurity): SecurityFilterChain {
|
||||
http{
|
||||
formLogin {}
|
||||
oneTimeTokenLogin { }
|
||||
@ -144,10 +141,10 @@ import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
|
||||
@Component (1)
|
||||
class MagicLinkGeneratedOneTimeTokenSuccessHandler(
|
||||
class MagicLinkOneTimeTokenGenerationSuccessHandler(
|
||||
private val mailSender: MailSender,
|
||||
private val redirectHandler: GeneratedOneTimeTokenHandler = RedirectGeneratedOneTimeTokenHandler("/ott/sent")
|
||||
) : GeneratedOneTimeTokenHandler {
|
||||
private val redirectHandler: OneTimeTokenGenerationSuccessHandler = RedirectOneTimeTokenGenerationSuccessHandler("/ott/sent")
|
||||
) : OneTimeTokenGenerationSuccessHandler {
|
||||
|
||||
override fun handle(request: HttpServletRequest, response: HttpServletResponse, oneTimeToken: OneTimeToken) {
|
||||
val builder = UriComponentsBuilder.fromHttpUrl(UrlUtils.buildFullRequestUrl(request))
|
||||
@ -179,7 +176,7 @@ class PageController {
|
||||
----
|
||||
======
|
||||
|
||||
<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
|
||||
@ -222,7 +219,7 @@ public class SecurityConfig {
|
||||
}
|
||||
|
||||
@Component
|
||||
public class MagicLinkGeneratedOneTimeTokenHandler implements GeneratedOneTimeTokenSuccessHandler {
|
||||
public class MagicLinkOneTimeTokenGenerationSuccessHandler implements OneTimeTokenGenerationSuccessHandler {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
@ -249,7 +246,7 @@ class SecurityConfig {
|
||||
}
|
||||
|
||||
@Component
|
||||
class MagicLinkGeneratedOneTimeTokenSuccessHandler : GeneratedOneTimeTokenHandler {
|
||||
class MagicLinkOneTimeTokenGenerationSuccessHandler : OneTimeTokenGenerationSuccessHandler {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
@ -286,7 +283,7 @@ public class SecurityConfig {
|
||||
}
|
||||
|
||||
@Component
|
||||
public class MagicLinkGeneratedOneTimeTokenHandler implements GeneratedOneTimeTokenSuccessHandler {
|
||||
public class MagicLinkGenerationSuccessHandler implements OneTimeTokenGenerationSuccessHandler {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
@ -313,7 +310,7 @@ class SecurityConfig {
|
||||
}
|
||||
|
||||
@Component
|
||||
class MagicLinkGeneratedOneTimeTokenSuccessHandler : GeneratedOneTimeTokenHandler {
|
||||
class MagicLinkOneTimeTokenGenerationSuccessHandler : OneTimeTokenGenerationSuccessHandler {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
@ -362,7 +359,7 @@ public class MyController {
|
||||
}
|
||||
|
||||
@Component
|
||||
public class MagicLinkGeneratedOneTimeTokenHandler implements GeneratedOneTimeTokenSuccessHandler {
|
||||
public class OneTimeTokenGenerationSuccessHandler implements OneTimeTokenGenerationSuccessHandler {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
@ -401,7 +398,7 @@ class MyController {
|
||||
}
|
||||
|
||||
@Component
|
||||
class MagicLinkGeneratedOneTimeTokenSuccessHandler : GeneratedOneTimeTokenHandler {
|
||||
class MagicLinkOneTimeTokenGenerationSuccessHandler : OneTimeTokenGenerationSuccessHandler {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
@ -452,7 +449,7 @@ public class SecurityConfig {
|
||||
}
|
||||
|
||||
@Component
|
||||
public class MagicLinkGeneratedOneTimeTokenHandler implements GeneratedOneTimeTokenSuccessHandler {
|
||||
public class MagicLinkOneTimeTokenGenerationSuccessHandler implements OneTimeTokenGenerationSuccessHandler {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
@ -482,7 +479,7 @@ class SecurityConfig {
|
||||
}
|
||||
|
||||
@Component
|
||||
class MagicLinkGeneratedOneTimeTokenSuccessHandler : GeneratedOneTimeTokenHandler {
|
||||
class MagicLinkOneTimeTokenGenerationSuccessHandler : OneTimeTokenGenerationSuccessHandler {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
@ -515,7 +512,7 @@ public class SecurityConfig {
|
||||
}
|
||||
|
||||
@Component
|
||||
public class MagicLinkGeneratedOneTimeTokenHandler implements GeneratedOneTimeTokenSuccessHandler {
|
||||
public class MagicLinkOneTimeTokenGenerationSuccessHandler implements OneTimeTokenGenerationSuccessHandler {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
@ -543,7 +540,7 @@ class SecurityConfig {
|
||||
}
|
||||
|
||||
@Component
|
||||
class MagicLinkGeneratedOneTimeTokenSuccessHandler : GeneratedOneTimeTokenHandler {
|
||||
class MagicLinkOneTimeTokenGenerationSuccessHandler : OneTimeTokenGenerationSuccessHandler {
|
||||
// ...
|
||||
}
|
||||
----
|
||||
|
@ -43,13 +43,13 @@ public final class GenerateOneTimeTokenWebFilter implements WebFilter {
|
||||
|
||||
private ServerWebExchangeMatcher matcher = ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, "/ott/generate");
|
||||
|
||||
private final ServerOneTimeTokenGenerationSuccessHandler generatedOneTimeTokenHandler;
|
||||
private final ServerOneTimeTokenGenerationSuccessHandler oneTimeTokenGenerationSuccessHandler;
|
||||
|
||||
public GenerateOneTimeTokenWebFilter(ReactiveOneTimeTokenService oneTimeTokenService,
|
||||
ServerOneTimeTokenGenerationSuccessHandler generatedOneTimeTokenHandler) {
|
||||
Assert.notNull(generatedOneTimeTokenHandler, "generatedOneTimeTokenHandler cannot be null");
|
||||
ServerOneTimeTokenGenerationSuccessHandler oneTimeTokenGenerationSuccessHandler) {
|
||||
Assert.notNull(oneTimeTokenGenerationSuccessHandler, "oneTimeTokenGenerationSuccessHandler cannot be null");
|
||||
Assert.notNull(oneTimeTokenService, "oneTimeTokenService cannot be null");
|
||||
this.generatedOneTimeTokenHandler = generatedOneTimeTokenHandler;
|
||||
this.oneTimeTokenGenerationSuccessHandler = oneTimeTokenGenerationSuccessHandler;
|
||||
this.oneTimeTokenService = oneTimeTokenService;
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ public final class GenerateOneTimeTokenWebFilter implements WebFilter {
|
||||
.mapNotNull((data) -> data.getFirst(USERNAME))
|
||||
.switchIfEmpty(chain.filter(exchange).then(Mono.empty()))
|
||||
.flatMap((username) -> this.oneTimeTokenService.generate(new GenerateOneTimeTokenRequest(username)))
|
||||
.flatMap((token) -> this.generatedOneTimeTokenHandler.handle(exchange, token));
|
||||
.flatMap((token) -> this.oneTimeTokenGenerationSuccessHandler.handle(exchange, token));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ public class GenerateOneTimeTokenWebFilterTests {
|
||||
|
||||
private final ReactiveOneTimeTokenService oneTimeTokenService = mock(ReactiveOneTimeTokenService.class);
|
||||
|
||||
private final ServerRedirectOneTimeTokenGenerationSuccessHandler generatedOneTimeTokenHandler = new ServerRedirectOneTimeTokenGenerationSuccessHandler(
|
||||
private final ServerRedirectOneTimeTokenGenerationSuccessHandler oneTimeTokenGenerationSuccessHandler = new ServerRedirectOneTimeTokenGenerationSuccessHandler(
|
||||
"/login/ott");
|
||||
|
||||
private static final String TOKEN = "token";
|
||||
@ -60,7 +60,7 @@ public class GenerateOneTimeTokenWebFilterTests {
|
||||
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
.body("username=user"));
|
||||
GenerateOneTimeTokenWebFilter filter = new GenerateOneTimeTokenWebFilter(this.oneTimeTokenService,
|
||||
this.generatedOneTimeTokenHandler);
|
||||
this.oneTimeTokenGenerationSuccessHandler);
|
||||
|
||||
filter.filter(exchange, (e) -> Mono.empty()).block();
|
||||
|
||||
@ -75,7 +75,7 @@ public class GenerateOneTimeTokenWebFilterTests {
|
||||
MockServerHttpRequest.BaseBuilder<?> request = MockServerHttpRequest.post("/ott/generate");
|
||||
MockServerWebExchange exchange = MockServerWebExchange.from(request);
|
||||
GenerateOneTimeTokenWebFilter filter = new GenerateOneTimeTokenWebFilter(this.oneTimeTokenService,
|
||||
this.generatedOneTimeTokenHandler);
|
||||
this.oneTimeTokenGenerationSuccessHandler);
|
||||
|
||||
filter.filter(exchange, (e) -> Mono.empty()).block();
|
||||
|
||||
@ -86,14 +86,14 @@ public class GenerateOneTimeTokenWebFilterTests {
|
||||
public void constructorWhenOneTimeTokenServiceNullThenIllegalArgumentException() {
|
||||
// @formatter:off
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new GenerateOneTimeTokenWebFilter(null, this.generatedOneTimeTokenHandler));
|
||||
.isThrownBy(() -> new GenerateOneTimeTokenWebFilter(null, this.oneTimeTokenGenerationSuccessHandler));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setWhenRequestMatcherNullThenIllegalArgumentException() {
|
||||
GenerateOneTimeTokenWebFilter filter = new GenerateOneTimeTokenWebFilter(this.oneTimeTokenService,
|
||||
this.generatedOneTimeTokenHandler);
|
||||
this.oneTimeTokenGenerationSuccessHandler);
|
||||
// @formatter:off
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> filter.setRequestMatcher(null));
|
||||
|
Loading…
x
Reference in New Issue
Block a user