Polish One-Time Token Component Names

Aligning parts of speech so that names are using nouns/verbs
where comparable components are using nouns/verbs.

Issue gh-15114
This commit is contained in:
Josh Cummings 2024-10-14 13:58:23 -06:00
parent b8aa78829c
commit c40334317d
No known key found for this signature in database
GPG Key ID: A306A51F43B8E5A5
19 changed files with 158 additions and 142 deletions

View File

@ -41,8 +41,8 @@ import org.springframework.security.web.authentication.AuthenticationSuccessHand
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.ott.GenerateOneTimeTokenFilter;
import org.springframework.security.web.authentication.ott.GeneratedOneTimeTokenHandler;
import org.springframework.security.web.authentication.ott.OneTimeTokenAuthenticationConverter;
import org.springframework.security.web.authentication.ott.OneTimeTokenGenerationSuccessHandler;
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
import org.springframework.security.web.authentication.ui.DefaultOneTimeTokenSubmitPageGeneratingFilter;
import org.springframework.security.web.authentication.ui.DefaultResourcesFilter;
@ -73,9 +73,9 @@ public final class OneTimeTokenLoginConfigurer<H extends HttpSecurityBuilder<H>>
private String loginProcessingUrl = "/login/ott";
private String generateTokenUrl = "/ott/generate";
private String tokenGeneratingUrl = "/ott/generate";
private GeneratedOneTimeTokenHandler generatedOneTimeTokenHandler;
private OneTimeTokenGenerationSuccessHandler oneTimeTokenGenerationSuccessHandler;
private AuthenticationProvider authenticationProvider;
@ -97,7 +97,7 @@ public final class OneTimeTokenLoginConfigurer<H extends HttpSecurityBuilder<H>>
return;
}
loginPageGeneratingFilter.setOneTimeTokenEnabled(true);
loginPageGeneratingFilter.setGenerateOneTimeTokenUrl(this.generateTokenUrl);
loginPageGeneratingFilter.setOneTimeTokenGenerationUrl(this.tokenGeneratingUrl);
if (this.authenticationFailureHandler == null
&& StringUtils.hasText(loginPageGeneratingFilter.getLoginPageUrl())) {
this.authenticationFailureHandler = new SimpleUrlAuthenticationFailureHandler(
@ -134,22 +134,22 @@ public final class OneTimeTokenLoginConfigurer<H extends HttpSecurityBuilder<H>>
private void configureOttGenerateFilter(H http) {
GenerateOneTimeTokenFilter generateFilter = new GenerateOneTimeTokenFilter(getOneTimeTokenService(http),
getGeneratedOneTimeTokenHandler(http));
generateFilter.setRequestMatcher(antMatcher(HttpMethod.POST, this.generateTokenUrl));
generateFilter.setRequestMatcher(antMatcher(HttpMethod.POST, this.tokenGeneratingUrl));
http.addFilter(postProcess(generateFilter));
http.addFilter(DefaultResourcesFilter.css());
}
private GeneratedOneTimeTokenHandler getGeneratedOneTimeTokenHandler(H http) {
if (this.generatedOneTimeTokenHandler == null) {
this.generatedOneTimeTokenHandler = getBeanOrNull(http, GeneratedOneTimeTokenHandler.class);
private OneTimeTokenGenerationSuccessHandler getGeneratedOneTimeTokenHandler(H http) {
if (this.oneTimeTokenGenerationSuccessHandler == null) {
this.oneTimeTokenGenerationSuccessHandler = getBeanOrNull(http, OneTimeTokenGenerationSuccessHandler.class);
}
if (this.generatedOneTimeTokenHandler == null) {
if (this.oneTimeTokenGenerationSuccessHandler == null) {
throw new IllegalStateException("""
A GeneratedOneTimeTokenHandler is required to enable oneTimeTokenLogin().
Please provide it as a bean or pass it to the oneTimeTokenLogin() DSL.
""");
}
return this.generatedOneTimeTokenHandler;
return this.oneTimeTokenGenerationSuccessHandler;
}
private void configureSubmitPage(H http) {
@ -186,22 +186,22 @@ public final class OneTimeTokenLoginConfigurer<H extends HttpSecurityBuilder<H>>
/**
* Specifies the URL that a One-Time Token generate request will be processed.
* Defaults to {@code /ott/generate}.
* @param generateTokenUrl
* @param tokenGeneratingUrl
*/
public OneTimeTokenLoginConfigurer<H> generateTokenUrl(String generateTokenUrl) {
Assert.hasText(generateTokenUrl, "generateTokenUrl cannot be null or empty");
this.generateTokenUrl = generateTokenUrl;
public OneTimeTokenLoginConfigurer<H> tokenGeneratingUrl(String tokenGeneratingUrl) {
Assert.hasText(tokenGeneratingUrl, "tokenGeneratingUrl cannot be null or empty");
this.tokenGeneratingUrl = tokenGeneratingUrl;
return this;
}
/**
* Specifies strategy to be used to handle generated one-time tokens.
* @param generatedOneTimeTokenHandler
* @param oneTimeTokenGenerationSuccessHandler
*/
public OneTimeTokenLoginConfigurer<H> generatedOneTimeTokenHandler(
GeneratedOneTimeTokenHandler generatedOneTimeTokenHandler) {
Assert.notNull(generatedOneTimeTokenHandler, "generatedOneTimeTokenHandler cannot be null");
this.generatedOneTimeTokenHandler = generatedOneTimeTokenHandler;
public OneTimeTokenLoginConfigurer<H> tokenGenerationSuccessHandler(
OneTimeTokenGenerationSuccessHandler oneTimeTokenGenerationSuccessHandler) {
Assert.notNull(oneTimeTokenGenerationSuccessHandler, "generatedOneTimeTokenHandler cannot be null");
this.oneTimeTokenGenerationSuccessHandler = oneTimeTokenGenerationSuccessHandler;
return this;
}
@ -248,7 +248,7 @@ public final class OneTimeTokenLoginConfigurer<H extends HttpSecurityBuilder<H>>
* {@link OneTimeToken}
* @param oneTimeTokenService
*/
public OneTimeTokenLoginConfigurer<H> oneTimeTokenService(OneTimeTokenService oneTimeTokenService) {
public OneTimeTokenLoginConfigurer<H> tokenService(OneTimeTokenService oneTimeTokenService) {
Assert.notNull(oneTimeTokenService, "oneTimeTokenService cannot be null");
this.oneTimeTokenService = oneTimeTokenService;
return this;

View File

@ -157,8 +157,8 @@ import org.springframework.security.web.server.authentication.logout.SecurityCon
import org.springframework.security.web.server.authentication.logout.ServerLogoutHandler;
import org.springframework.security.web.server.authentication.logout.ServerLogoutSuccessHandler;
import org.springframework.security.web.server.authentication.ott.GenerateOneTimeTokenWebFilter;
import org.springframework.security.web.server.authentication.ott.ServerGeneratedOneTimeTokenHandler;
import org.springframework.security.web.server.authentication.ott.ServerOneTimeTokenAuthenticationConverter;
import org.springframework.security.web.server.authentication.ott.ServerOneTimeTokenGenerationSuccessHandler;
import org.springframework.security.web.server.authorization.AuthorizationContext;
import org.springframework.security.web.server.authorization.AuthorizationWebFilter;
import org.springframework.security.web.server.authorization.DelegatingReactiveAuthorizationManager;
@ -5922,7 +5922,7 @@ public class ServerHttpSecurity {
private ReactiveAuthenticationManager authenticationManager;
private ReactiveOneTimeTokenService oneTimeTokenService;
private ReactiveOneTimeTokenService tokenService;
private ServerAuthenticationConverter authenticationConverter = new ServerOneTimeTokenAuthenticationConverter();
@ -5936,7 +5936,7 @@ public class ServerHttpSecurity {
private final List<ServerAuthenticationSuccessHandler> authenticationSuccessHandlers = new ArrayList<>();
private ServerGeneratedOneTimeTokenHandler generatedOneTimeTokenHandler;
private ServerOneTimeTokenGenerationSuccessHandler tokenGenerationSuccessHandler;
private ServerSecurityContextRepository securityContextRepository;
@ -5944,7 +5944,7 @@ public class ServerHttpSecurity {
private String defaultSubmitPageUrl = "/login/ott";
private String generateTokenUrl = "/ott/generate";
private String tokenGeneratingUrl = "/ott/generate";
private boolean submitPageEnabled = true;
@ -5981,10 +5981,10 @@ public class ServerHttpSecurity {
}
private void configureOttGenerateFilter(ServerHttpSecurity http) {
GenerateOneTimeTokenWebFilter generateFilter = new GenerateOneTimeTokenWebFilter(getOneTimeTokenService(),
getGeneratedOneTimeTokenHandler());
GenerateOneTimeTokenWebFilter generateFilter = new GenerateOneTimeTokenWebFilter(getTokenService(),
getTokenGenerationSuccessHandler());
generateFilter
.setRequestMatcher(ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, this.generateTokenUrl));
.setRequestMatcher(ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, this.tokenGeneratingUrl));
http.addFilterAt(generateFilter, SecurityWebFiltersOrder.ONE_TIME_TOKEN);
}
@ -5994,7 +5994,7 @@ public class ServerHttpSecurity {
OrderedWebFilter orderedWebFilter = (OrderedWebFilter) webFilter;
if (orderedWebFilter.webFilter instanceof LoginPageGeneratingWebFilter loginPageGeneratingFilter) {
loginPageGeneratingFilter.setOneTimeTokenEnabled(true);
loginPageGeneratingFilter.setGenerateOneTimeTokenUrl(this.generateTokenUrl);
loginPageGeneratingFilter.setGenerateOneTimeTokenUrl(this.tokenGeneratingUrl);
break;
}
}
@ -6072,7 +6072,7 @@ public class ServerHttpSecurity {
ReactiveAuthenticationManager getAuthenticationManager() {
if (this.authenticationManager == null) {
ReactiveUserDetailsService userDetailsService = getBean(ReactiveUserDetailsService.class);
return new OneTimeTokenReactiveAuthenticationManager(getOneTimeTokenService(), userDetailsService);
return new OneTimeTokenReactiveAuthenticationManager(getTokenService(), userDetailsService);
}
return this.authenticationManager;
}
@ -6082,22 +6082,22 @@ public class ServerHttpSecurity {
* {@link OneTimeToken}
* @param oneTimeTokenService
*/
public OneTimeTokenLoginSpec oneTimeTokenService(ReactiveOneTimeTokenService oneTimeTokenService) {
public OneTimeTokenLoginSpec tokenService(ReactiveOneTimeTokenService oneTimeTokenService) {
Assert.notNull(oneTimeTokenService, "oneTimeTokenService cannot be null");
this.oneTimeTokenService = oneTimeTokenService;
this.tokenService = oneTimeTokenService;
return this;
}
ReactiveOneTimeTokenService getOneTimeTokenService() {
if (this.oneTimeTokenService != null) {
return this.oneTimeTokenService;
ReactiveOneTimeTokenService getTokenService() {
if (this.tokenService != null) {
return this.tokenService;
}
ReactiveOneTimeTokenService oneTimeTokenService = getBeanOrNull(ReactiveOneTimeTokenService.class);
if (oneTimeTokenService != null) {
return oneTimeTokenService;
}
this.oneTimeTokenService = new InMemoryReactiveOneTimeTokenService();
return this.oneTimeTokenService;
this.tokenService = new InMemoryReactiveOneTimeTokenService();
return this.tokenService;
}
/**
@ -6153,21 +6153,21 @@ public class ServerHttpSecurity {
* Specifies strategy to be used to handle generated one-time tokens.
* @param generatedOneTimeTokenHandler
*/
public OneTimeTokenLoginSpec generatedOneTimeTokenHandler(
ServerGeneratedOneTimeTokenHandler generatedOneTimeTokenHandler) {
public OneTimeTokenLoginSpec tokenGenerationSuccessHandler(
ServerOneTimeTokenGenerationSuccessHandler generatedOneTimeTokenHandler) {
Assert.notNull(generatedOneTimeTokenHandler, "generatedOneTimeTokenHandler cannot be null");
this.generatedOneTimeTokenHandler = generatedOneTimeTokenHandler;
this.tokenGenerationSuccessHandler = generatedOneTimeTokenHandler;
return this;
}
/**
* Specifies the URL that a One-Time Token generate request will be processed.
* Defaults to {@code /ott/generate}.
* @param generateTokenUrl
* @param tokenGeneratingUrl
*/
public OneTimeTokenLoginSpec generateTokenUrl(String generateTokenUrl) {
Assert.hasText(generateTokenUrl, "generateTokenUrl cannot be null or empty");
this.generateTokenUrl = generateTokenUrl;
public OneTimeTokenLoginSpec tokenGeneratingUrl(String tokenGeneratingUrl) {
Assert.hasText(tokenGeneratingUrl, "tokenGeneratingUrl cannot be null or empty");
this.tokenGeneratingUrl = tokenGeneratingUrl;
return this;
}
@ -6187,17 +6187,17 @@ public class ServerHttpSecurity {
return this;
}
private ServerGeneratedOneTimeTokenHandler getGeneratedOneTimeTokenHandler() {
if (this.generatedOneTimeTokenHandler == null) {
this.generatedOneTimeTokenHandler = getBeanOrNull(ServerGeneratedOneTimeTokenHandler.class);
private ServerOneTimeTokenGenerationSuccessHandler getTokenGenerationSuccessHandler() {
if (this.tokenGenerationSuccessHandler == null) {
this.tokenGenerationSuccessHandler = getBeanOrNull(ServerOneTimeTokenGenerationSuccessHandler.class);
}
if (this.generatedOneTimeTokenHandler == null) {
if (this.tokenGenerationSuccessHandler == null) {
throw new IllegalStateException("""
A ServerGeneratedOneTimeTokenHandler is required to enable oneTimeTokenLogin().
Please provide it as a bean or pass it to the oneTimeTokenLogin() DSL.
""");
}
return this.generatedOneTimeTokenHandler;
return this.tokenGenerationSuccessHandler;
}
}

View File

@ -23,40 +23,40 @@ import org.springframework.security.config.annotation.web.configurers.ott.OneTim
import org.springframework.security.web.authentication.AuthenticationConverter
import org.springframework.security.web.authentication.AuthenticationFailureHandler
import org.springframework.security.web.authentication.AuthenticationSuccessHandler
import org.springframework.security.web.authentication.ott.GeneratedOneTimeTokenHandler
import org.springframework.security.web.authentication.ott.OneTimeTokenGenerationSuccessHandler
/**
* A Kotlin DSL to configure [HttpSecurity] OAuth 2.0 login using idiomatic Kotlin code.
*
* @author Max Batischev
* @since 6.4
* @property oneTimeTokenService configures the [OneTimeTokenService] used to generate and consume
* @property tokenService configures the [OneTimeTokenService] used to generate and consume
* @property authenticationConverter Use this [AuthenticationConverter] when converting incoming requests to an authentication
* @property authenticationFailureHandler the [AuthenticationFailureHandler] to use when authentication
* @property authenticationSuccessHandler the [AuthenticationSuccessHandler] to be used
* @property defaultSubmitPageUrl sets the URL that the default submit page will be generated
* @property showDefaultSubmitPage configures whether the default one-time token submit page should be shown
* @property loginProcessingUrl the URL to process the login request
* @property generateTokenUrl the URL that a One-Time Token generate request will be processed
* @property generatedOneTimeTokenHandler the strategy to be used to handle generated one-time tokens
* @property tokenGeneratingUrl the URL that a One-Time Token generate request will be processed
* @property oneTimeTokenGenerationSuccessHandler the strategy to be used to handle generated one-time tokens
* @property authenticationProvider the [AuthenticationProvider] to use when authenticating the user
*/
@SecurityMarker
class OneTimeTokenLoginDsl {
var oneTimeTokenService: OneTimeTokenService? = null
var tokenService: OneTimeTokenService? = null
var authenticationConverter: AuthenticationConverter? = null
var authenticationFailureHandler: AuthenticationFailureHandler? = null
var authenticationSuccessHandler: AuthenticationSuccessHandler? = null
var defaultSubmitPageUrl: String? = null
var loginProcessingUrl: String? = null
var generateTokenUrl: String? = null
var tokenGeneratingUrl: String? = null
var showDefaultSubmitPage: Boolean? = true
var generatedOneTimeTokenHandler: GeneratedOneTimeTokenHandler? = null
var oneTimeTokenGenerationSuccessHandler: OneTimeTokenGenerationSuccessHandler? = null
var authenticationProvider: AuthenticationProvider? = null
internal fun get(): (OneTimeTokenLoginConfigurer<HttpSecurity>) -> Unit {
return { oneTimeTokenLoginConfigurer ->
oneTimeTokenService?.also { oneTimeTokenLoginConfigurer.oneTimeTokenService(oneTimeTokenService) }
tokenService?.also { oneTimeTokenLoginConfigurer.tokenService(tokenService) }
authenticationConverter?.also { oneTimeTokenLoginConfigurer.authenticationConverter(authenticationConverter) }
authenticationFailureHandler?.also {
oneTimeTokenLoginConfigurer.authenticationFailureHandler(
@ -71,10 +71,10 @@ class OneTimeTokenLoginDsl {
defaultSubmitPageUrl?.also { oneTimeTokenLoginConfigurer.defaultSubmitPageUrl(defaultSubmitPageUrl) }
showDefaultSubmitPage?.also { oneTimeTokenLoginConfigurer.showDefaultSubmitPage(showDefaultSubmitPage!!) }
loginProcessingUrl?.also { oneTimeTokenLoginConfigurer.loginProcessingUrl(loginProcessingUrl) }
generateTokenUrl?.also { oneTimeTokenLoginConfigurer.generateTokenUrl(generateTokenUrl) }
generatedOneTimeTokenHandler?.also {
oneTimeTokenLoginConfigurer.generatedOneTimeTokenHandler(
generatedOneTimeTokenHandler
tokenGeneratingUrl?.also { oneTimeTokenLoginConfigurer.tokenGeneratingUrl(tokenGeneratingUrl) }
oneTimeTokenGenerationSuccessHandler?.also {
oneTimeTokenLoginConfigurer.tokenGenerationSuccessHandler(
oneTimeTokenGenerationSuccessHandler
)
}
authenticationProvider?.also { oneTimeTokenLoginConfigurer.authenticationProvider(authenticationProvider) }

View File

@ -40,8 +40,8 @@ import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.ott.GeneratedOneTimeTokenHandler;
import org.springframework.security.web.authentication.ott.RedirectGeneratedOneTimeTokenHandler;
import org.springframework.security.web.authentication.ott.OneTimeTokenGenerationSuccessHandler;
import org.springframework.security.web.authentication.ott.RedirectOneTimeTokenGenerationSuccessHandler;
import org.springframework.security.web.csrf.CsrfToken;
import org.springframework.security.web.csrf.DefaultCsrfToken;
import org.springframework.security.web.csrf.HttpSessionCsrfTokenRepository;
@ -72,7 +72,7 @@ public class OneTimeTokenLoginConfigurerTests {
this.mvc.perform(post("/ott/generate").param("username", "user").with(csrf()))
.andExpectAll(status().isFound(), redirectedUrl("/login/ott"));
String token = TestGeneratedOneTimeTokenHandler.lastToken.getTokenValue();
String token = TestOneTimeTokenGenerationSuccessHandler.lastToken.getTokenValue();
this.mvc.perform(post("/login/ott").param("token", token).with(csrf()))
.andExpectAll(status().isFound(), redirectedUrl("/"), authenticated());
@ -84,7 +84,7 @@ public class OneTimeTokenLoginConfigurerTests {
this.mvc.perform(post("/generateurl").param("username", "user").with(csrf()))
.andExpectAll(status().isFound(), redirectedUrl("/redirected"));
String token = TestGeneratedOneTimeTokenHandler.lastToken.getTokenValue();
String token = TestOneTimeTokenGenerationSuccessHandler.lastToken.getTokenValue();
this.mvc.perform(post("/loginprocessingurl").param("token", token).with(csrf()))
.andExpectAll(status().isFound(), redirectedUrl("/authenticated"), authenticated());
@ -96,7 +96,7 @@ public class OneTimeTokenLoginConfigurerTests {
this.mvc.perform(post("/ott/generate").param("username", "user").with(csrf()))
.andExpectAll(status().isFound(), redirectedUrl("/login/ott"));
String token = TestGeneratedOneTimeTokenHandler.lastToken.getTokenValue();
String token = TestOneTimeTokenGenerationSuccessHandler.lastToken.getTokenValue();
this.mvc.perform(post("/login/ott").param("token", token).with(csrf()))
.andExpectAll(status().isFound(), redirectedUrl("/"), authenticated());
@ -183,7 +183,7 @@ public class OneTimeTokenLoginConfigurerTests {
}
@Test
void oneTimeTokenWhenNoGeneratedOneTimeTokenHandlerThenException() {
void oneTimeTokenWhenNoTokenGenerationSuccessHandlerThenException() {
assertThatException()
.isThrownBy(() -> this.spring.register(OneTimeTokenNoGeneratedOttHandlerConfig.class).autowire())
.havingRootCause()
@ -207,7 +207,7 @@ public class OneTimeTokenLoginConfigurerTests {
.anyRequest().authenticated()
)
.oneTimeTokenLogin((ott) -> ott
.generatedOneTimeTokenHandler(new TestGeneratedOneTimeTokenHandler())
.tokenGenerationSuccessHandler(new TestOneTimeTokenGenerationSuccessHandler())
);
// @formatter:on
return http.build();
@ -228,8 +228,8 @@ public class OneTimeTokenLoginConfigurerTests {
.anyRequest().authenticated()
)
.oneTimeTokenLogin((ott) -> ott
.generateTokenUrl("/generateurl")
.generatedOneTimeTokenHandler(new TestGeneratedOneTimeTokenHandler("/redirected"))
.tokenGeneratingUrl("/generateurl")
.tokenGenerationSuccessHandler(new TestOneTimeTokenGenerationSuccessHandler("/redirected"))
.loginProcessingUrl("/loginprocessingurl")
.authenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler("/authenticated"))
);
@ -253,7 +253,7 @@ public class OneTimeTokenLoginConfigurerTests {
)
.formLogin(Customizer.withDefaults())
.oneTimeTokenLogin((ott) -> ott
.generatedOneTimeTokenHandler(new TestGeneratedOneTimeTokenHandler())
.tokenGenerationSuccessHandler(new TestOneTimeTokenGenerationSuccessHandler())
);
// @formatter:on
return http.build();
@ -280,18 +280,18 @@ public class OneTimeTokenLoginConfigurerTests {
}
static class TestGeneratedOneTimeTokenHandler implements GeneratedOneTimeTokenHandler {
static class TestOneTimeTokenGenerationSuccessHandler implements OneTimeTokenGenerationSuccessHandler {
private static OneTimeToken lastToken;
private final GeneratedOneTimeTokenHandler delegate;
private final OneTimeTokenGenerationSuccessHandler delegate;
TestGeneratedOneTimeTokenHandler() {
this.delegate = new RedirectGeneratedOneTimeTokenHandler("/login/ott");
TestOneTimeTokenGenerationSuccessHandler() {
this.delegate = new RedirectOneTimeTokenGenerationSuccessHandler("/login/ott");
}
TestGeneratedOneTimeTokenHandler(String redirectUrl) {
this.delegate = new RedirectGeneratedOneTimeTokenHandler(redirectUrl);
TestOneTimeTokenGenerationSuccessHandler(String redirectUrl) {
this.delegate = new RedirectOneTimeTokenGenerationSuccessHandler(redirectUrl);
}
@Override

View File

@ -40,8 +40,8 @@ import org.springframework.security.core.userdetails.User;
import org.springframework.security.test.web.reactive.server.SecurityMockServerConfigurers;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.authentication.RedirectServerAuthenticationSuccessHandler;
import org.springframework.security.web.server.authentication.ott.ServerGeneratedOneTimeTokenHandler;
import org.springframework.security.web.server.authentication.ott.ServerRedirectGeneratedOneTimeTokenHandler;
import org.springframework.security.web.server.authentication.ott.ServerOneTimeTokenGenerationSuccessHandler;
import org.springframework.security.web.server.authentication.ott.ServerRedirectOneTimeTokenGenerationSuccessHandler;
import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.reactive.config.EnableWebFlux;
import org.springframework.web.reactive.function.BodyInserters;
@ -107,7 +107,7 @@ public class OneTimeTokenLoginSpecTests {
.expectHeader().valueEquals("Location", "/login/ott");
// @formatter:on
String token = TestServerGeneratedOneTimeTokenHandler.lastToken.getTokenValue();
String token = TestServerOneTimeTokenGenerationSuccessHandler.lastToken.getTokenValue();
// @formatter:off
this.client.mutateWith(SecurityMockServerConfigurers.csrf())
@ -143,7 +143,7 @@ public class OneTimeTokenLoginSpecTests {
.expectHeader().valueEquals("Location", "/redirected");
// @formatter:on
String token = TestServerGeneratedOneTimeTokenHandler.lastToken.getTokenValue();
String token = TestServerOneTimeTokenGenerationSuccessHandler.lastToken.getTokenValue();
// @formatter:off
this.client.mutateWith(SecurityMockServerConfigurers.csrf())
@ -179,7 +179,7 @@ public class OneTimeTokenLoginSpecTests {
.expectHeader().valueEquals("Location", "/login/ott");
// @formatter:on
String token = TestServerGeneratedOneTimeTokenHandler.lastToken.getTokenValue();
String token = TestServerOneTimeTokenGenerationSuccessHandler.lastToken.getTokenValue();
// @formatter:off
this.client.mutateWith(SecurityMockServerConfigurers.csrf())
@ -295,7 +295,7 @@ public class OneTimeTokenLoginSpecTests {
.authenticated()
)
.oneTimeTokenLogin((ott) -> ott
.generatedOneTimeTokenHandler(new TestServerGeneratedOneTimeTokenHandler())
.tokenGenerationSuccessHandler(new TestServerOneTimeTokenGenerationSuccessHandler())
);
// @formatter:on
return http.build();
@ -318,8 +318,8 @@ public class OneTimeTokenLoginSpecTests {
.authenticated()
)
.oneTimeTokenLogin((ott) -> ott
.generateTokenUrl("/generateurl")
.generatedOneTimeTokenHandler(new TestServerGeneratedOneTimeTokenHandler("/redirected"))
.tokenGeneratingUrl("/generateurl")
.tokenGenerationSuccessHandler(new TestServerOneTimeTokenGenerationSuccessHandler("/redirected"))
.loginProcessingUrl("/loginprocessingurl")
.authenticationSuccessHandler(new RedirectServerAuthenticationSuccessHandler("/authenticated"))
);
@ -345,7 +345,7 @@ public class OneTimeTokenLoginSpecTests {
)
.formLogin(Customizer.withDefaults())
.oneTimeTokenLogin((ott) -> ott
.generatedOneTimeTokenHandler(new TestServerGeneratedOneTimeTokenHandler())
.tokenGenerationSuccessHandler(new TestServerOneTimeTokenGenerationSuccessHandler())
);
// @formatter:on
return http.build();
@ -385,18 +385,19 @@ public class OneTimeTokenLoginSpecTests {
}
private static class TestServerGeneratedOneTimeTokenHandler implements ServerGeneratedOneTimeTokenHandler {
private static class TestServerOneTimeTokenGenerationSuccessHandler
implements ServerOneTimeTokenGenerationSuccessHandler {
private static OneTimeToken lastToken;
private final ServerGeneratedOneTimeTokenHandler delegate;
private final ServerOneTimeTokenGenerationSuccessHandler delegate;
TestServerGeneratedOneTimeTokenHandler() {
this.delegate = new ServerRedirectGeneratedOneTimeTokenHandler("/login/ott");
TestServerOneTimeTokenGenerationSuccessHandler() {
this.delegate = new ServerRedirectOneTimeTokenGenerationSuccessHandler("/login/ott");
}
TestServerGeneratedOneTimeTokenHandler(String redirectUrl) {
this.delegate = new ServerRedirectGeneratedOneTimeTokenHandler(redirectUrl);
TestServerOneTimeTokenGenerationSuccessHandler(String redirectUrl) {
this.delegate = new ServerRedirectOneTimeTokenGenerationSuccessHandler(redirectUrl);
}
@Override

View File

@ -36,8 +36,8 @@ import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequ
import org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers
import org.springframework.security.web.SecurityFilterChain
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler
import org.springframework.security.web.authentication.ott.GeneratedOneTimeTokenHandler
import org.springframework.security.web.authentication.ott.RedirectGeneratedOneTimeTokenHandler
import org.springframework.security.web.authentication.ott.OneTimeTokenGenerationSuccessHandler
import org.springframework.security.web.authentication.ott.RedirectOneTimeTokenGenerationSuccessHandler
import org.springframework.test.web.servlet.MockMvc
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders
import org.springframework.test.web.servlet.result.MockMvcResultMatchers
@ -117,7 +117,7 @@ class OneTimeTokenLoginDslTests {
authorize(anyRequest, authenticated)
}
oneTimeTokenLogin {
generatedOneTimeTokenHandler = TestGeneratedOneTimeTokenHandler()
oneTimeTokenGenerationSuccessHandler = TestGeneratedOneTimeTokenHandler()
}
}
// @formatter:on
@ -137,8 +137,8 @@ class OneTimeTokenLoginDslTests {
authorize(anyRequest, authenticated)
}
oneTimeTokenLogin {
generateTokenUrl = "/generateurl"
generatedOneTimeTokenHandler = TestGeneratedOneTimeTokenHandler("/redirected")
tokenGeneratingUrl = "/generateurl"
oneTimeTokenGenerationSuccessHandler = TestGeneratedOneTimeTokenHandler("/redirected")
loginProcessingUrl = "/loginprocessingurl"
authenticationSuccessHandler = SimpleUrlAuthenticationSuccessHandler("/authenticated")
}
@ -156,15 +156,22 @@ class OneTimeTokenLoginDslTests {
InMemoryUserDetailsManager(PasswordEncodedUser.user(), PasswordEncodedUser.admin())
}
private class TestGeneratedOneTimeTokenHandler : GeneratedOneTimeTokenHandler {
private val delegate: GeneratedOneTimeTokenHandler
private class TestGeneratedOneTimeTokenHandler :
OneTimeTokenGenerationSuccessHandler {
private val delegate: OneTimeTokenGenerationSuccessHandler
constructor() {
this.delegate = RedirectGeneratedOneTimeTokenHandler("/login/ott")
this.delegate =
RedirectOneTimeTokenGenerationSuccessHandler(
"/login/ott"
)
}
constructor(redirectUrl: String?) {
this.delegate = RedirectGeneratedOneTimeTokenHandler(redirectUrl)
this.delegate =
RedirectOneTimeTokenGenerationSuccessHandler(
redirectUrl
)
}
override fun handle(request: HttpServletRequest, response: HttpServletResponse, oneTimeToken: OneTimeToken) {

View File

@ -16,7 +16,7 @@ For clarity, we'll assume OTP refers to https://en.wikipedia.org/wiki/Time-based
=== Token Delivery
- OTT: Usually a custom javadoc:org.springframework.security.web.server.authentication.ott.ServerGeneratedOneTimeTokenHandler[] must be implemented, responsible for delivering the token to the end user.
- OTT: Usually a custom javadoc:org.springframework.security.web.server.authentication.ott.ServerOneTimeTokenGenerationSuccessHandler[] must be implemented, responsible for delivering the token to the end user.
- OTP: The token is often generated by an external tool, so there's no need to send it to the user via the application.
=== Token Generation
@ -49,7 +49,7 @@ It will also set up the javadoc:org.springframework.security.web.server.ui.OneTi
== Sending the Token to the User
It is not possible for Spring Security to reasonably determine the way the token should be delivered to your users.
Therefore, a custom javadoc:org.springframework.security.web.server.authentication.ott.ServerGeneratedOneTimeTokenHandler[] must be provided to deliver the token to the user based on your needs.
Therefore, a custom javadoc:org.springframework.security.web.server.authentication.ott.ServerOneTimeTokenGenerationSuccessHandler[] must be provided to deliver the token to the user based on your needs.
One of the most common delivery strategies is a Magic Link, via e-mail, SMS, etc.
In the following example, we are going to create a magic link and sent it to the user's email.
@ -126,7 +126,7 @@ class PageController {
<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 `ServerRedirectGeneratedOneTimeTokenHandler` to perform a redirect to your desired URL
<5> Use the `ServerRedirectOneTimeTokenGenerationSuccessHandler` to perform a redirect to your desired URL
The email content will look similar to:

View File

@ -16,7 +16,7 @@ For clarity, we'll assume OTP refers to https://en.wikipedia.org/wiki/Time-based
=== Token Delivery
- OTT: Usually a custom javadoc:org.springframework.security.web.authentication.ott.GeneratedOneTimeTokenHandler[] must be implemented, responsible for delivering the token to the end user.
- OTT: Usually a custom javadoc:org.springframework.security.web.authentication.ott.OneTimeTokenGenerationSuccessHandler[] must be implemented, responsible for delivering the token to the end user.
- OTP: The token is often generated by an external tool, so there's no need to send it to the user via the application.
=== Token Generation
@ -49,7 +49,7 @@ It will also set up the javadoc:org.springframework.security.web.authentication.
== Sending the Token to the User
It is not possible for Spring Security to reasonably determine the way the token should be delivered to your users.
Therefore, a custom javadoc:org.springframework.security.web.authentication.ott.GeneratedOneTimeTokenHandler[] must be provided to deliver the token to the user based on your needs.
Therefore, a custom javadoc:org.springframework.security.web.authentication.ott.OneTimeTokenGenerationSuccessHandler[] must be provided to deliver the token to the user based on your needs.
One of the most common delivery strategies is a Magic Link, via e-mail, SMS, etc.
In the following example, we are going to create a magic link and sent it to the user's email.
@ -183,7 +183,7 @@ class PageController {
<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 `RedirectGeneratedOneTimeTokenHandler` to perform a redirect to your desired URL
<5> Use the `RedirectOneTimeTokenGenerationSuccessHandler` to perform a redirect to your desired URL
The email content will look similar to:

View File

@ -43,18 +43,18 @@ import static org.springframework.security.web.util.matcher.AntPathRequestMatche
*/
public final class GenerateOneTimeTokenFilter extends OncePerRequestFilter {
private final OneTimeTokenService oneTimeTokenService;
private final OneTimeTokenService tokenService;
private final GeneratedOneTimeTokenHandler generatedOneTimeTokenHandler;
private final OneTimeTokenGenerationSuccessHandler tokenGenerationSuccessHandler;
private RequestMatcher requestMatcher = antMatcher(HttpMethod.POST, "/ott/generate");
public GenerateOneTimeTokenFilter(OneTimeTokenService oneTimeTokenService,
GeneratedOneTimeTokenHandler generatedOneTimeTokenHandler) {
Assert.notNull(oneTimeTokenService, "oneTimeTokenService cannot be null");
Assert.notNull(generatedOneTimeTokenHandler, "generatedOneTimeTokenHandler cannot be null");
this.oneTimeTokenService = oneTimeTokenService;
this.generatedOneTimeTokenHandler = generatedOneTimeTokenHandler;
public GenerateOneTimeTokenFilter(OneTimeTokenService tokenService,
OneTimeTokenGenerationSuccessHandler tokenGenerationSuccessHandler) {
Assert.notNull(tokenService, "tokenService cannot be null");
Assert.notNull(tokenGenerationSuccessHandler, "tokenGenerationSuccessHandler cannot be null");
this.tokenService = tokenService;
this.tokenGenerationSuccessHandler = tokenGenerationSuccessHandler;
}
@Override
@ -70,8 +70,8 @@ public final class GenerateOneTimeTokenFilter extends OncePerRequestFilter {
return;
}
GenerateOneTimeTokenRequest generateRequest = new GenerateOneTimeTokenRequest(username);
OneTimeToken ott = this.oneTimeTokenService.generate(generateRequest);
this.generatedOneTimeTokenHandler.handle(request, response, ott);
OneTimeToken ott = this.tokenService.generate(generateRequest);
this.tokenGenerationSuccessHandler.handle(request, response, ott);
}
/**

View File

@ -31,7 +31,7 @@ import org.springframework.security.authentication.ott.OneTimeToken;
* @since 6.4
*/
@FunctionalInterface
public interface GeneratedOneTimeTokenHandler {
public interface OneTimeTokenGenerationSuccessHandler {
/**
* Handles generated one-time tokens

View File

@ -27,12 +27,13 @@ import org.springframework.security.web.RedirectStrategy;
import org.springframework.util.Assert;
/**
* A {@link GeneratedOneTimeTokenHandler} that performs a redirect to a specific location
* A {@link OneTimeTokenGenerationSuccessHandler} that performs a redirect to a specific
* location
*
* @author Marcus da Coregio
* @since 6.4
*/
public final class RedirectGeneratedOneTimeTokenHandler implements GeneratedOneTimeTokenHandler {
public final class RedirectOneTimeTokenGenerationSuccessHandler implements OneTimeTokenGenerationSuccessHandler {
private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
@ -42,7 +43,7 @@ public final class RedirectGeneratedOneTimeTokenHandler implements GeneratedOneT
* Constructs an instance of this class that redirects to the specified URL.
* @param redirectUrl
*/
public RedirectGeneratedOneTimeTokenHandler(String redirectUrl) {
public RedirectOneTimeTokenGenerationSuccessHandler(String redirectUrl) {
Assert.hasText(redirectUrl, "redirectUrl cannot be empty or null");
this.redirectUrl = redirectUrl;
}

View File

@ -157,7 +157,7 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean {
this.authenticationUrl = authenticationUrl;
}
public void setGenerateOneTimeTokenUrl(String generateOneTimeTokenUrl) {
public void setOneTimeTokenGenerationUrl(String generateOneTimeTokenUrl) {
this.generateOneTimeTokenUrl = generateOneTimeTokenUrl;
}

View File

@ -43,10 +43,10 @@ public final class GenerateOneTimeTokenWebFilter implements WebFilter {
private ServerWebExchangeMatcher matcher = ServerWebExchangeMatchers.pathMatchers(HttpMethod.POST, "/ott/generate");
private final ServerGeneratedOneTimeTokenHandler generatedOneTimeTokenHandler;
private final ServerOneTimeTokenGenerationSuccessHandler generatedOneTimeTokenHandler;
public GenerateOneTimeTokenWebFilter(ReactiveOneTimeTokenService oneTimeTokenService,
ServerGeneratedOneTimeTokenHandler generatedOneTimeTokenHandler) {
ServerOneTimeTokenGenerationSuccessHandler generatedOneTimeTokenHandler) {
Assert.notNull(generatedOneTimeTokenHandler, "generatedOneTimeTokenHandler cannot be null");
Assert.notNull(oneTimeTokenService, "oneTimeTokenService cannot be null");
this.generatedOneTimeTokenHandler = generatedOneTimeTokenHandler;

View File

@ -28,7 +28,7 @@ import org.springframework.web.server.ServerWebExchange;
* @since 6.4
*/
@FunctionalInterface
public interface ServerGeneratedOneTimeTokenHandler {
public interface ServerOneTimeTokenGenerationSuccessHandler {
/**
* Handles generated one-time tokens

View File

@ -27,19 +27,20 @@ import org.springframework.util.Assert;
import org.springframework.web.server.ServerWebExchange;
/**
* A {@link ServerGeneratedOneTimeTokenHandler} that performs a redirect to a specific
* location
* A {@link ServerOneTimeTokenGenerationSuccessHandler} that performs a redirect to a
* specific location
*
* @author Max Batischev
* @since 6.4
*/
public final class ServerRedirectGeneratedOneTimeTokenHandler implements ServerGeneratedOneTimeTokenHandler {
public final class ServerRedirectOneTimeTokenGenerationSuccessHandler
implements ServerOneTimeTokenGenerationSuccessHandler {
private final ServerRedirectStrategy redirectStrategy = new DefaultServerRedirectStrategy();
private final URI redirectUri;
public ServerRedirectGeneratedOneTimeTokenHandler(String redirectUri) {
public ServerRedirectOneTimeTokenGenerationSuccessHandler(String redirectUri) {
Assert.hasText(redirectUri, "redirectUri cannot be empty or null");
this.redirectUri = URI.create(redirectUri);
}

View File

@ -192,7 +192,7 @@ public class DefaultLoginPageGeneratingFilterTests {
DefaultLoginPageGeneratingFilter filter = new DefaultLoginPageGeneratingFilter();
filter.setLoginPageUrl(DefaultLoginPageGeneratingFilter.DEFAULT_LOGIN_PAGE_URL);
filter.setOneTimeTokenEnabled(true);
filter.setGenerateOneTimeTokenUrl("/ott/authenticate");
filter.setOneTimeTokenGenerationUrl("/ott/authenticate");
MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(new MockHttpServletRequest("GET", "/login"), response, this.chain);
assertThat(response.getContentAsString()).contains("Request a One-Time Token");

View File

@ -29,15 +29,16 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* Tests for {@link RedirectGeneratedOneTimeTokenHandler}
* Tests for {@link RedirectOneTimeTokenGenerationSuccessHandler}
*
* @author Marcus da Coregio
*/
class RedirectGeneratedOneTimeTokenHandlerTests {
class RedirectOneTimeTokenGenerationSuccessHandlerTests {
@Test
void handleThenRedirectToDefaultLocation() throws IOException {
RedirectGeneratedOneTimeTokenHandler handler = new RedirectGeneratedOneTimeTokenHandler("/login/ott");
RedirectOneTimeTokenGenerationSuccessHandler handler = new RedirectOneTimeTokenGenerationSuccessHandler(
"/login/ott");
MockHttpServletResponse response = new MockHttpServletResponse();
handler.handle(new MockHttpServletRequest(), response, new DefaultOneTimeToken("token", "user", Instant.now()));
assertThat(response.getRedirectedUrl()).isEqualTo("/login/ott");
@ -46,16 +47,17 @@ class RedirectGeneratedOneTimeTokenHandlerTests {
@Test
void handleWhenUrlChangedThenRedirectToUrl() throws IOException {
MockHttpServletResponse response = new MockHttpServletResponse();
RedirectGeneratedOneTimeTokenHandler handler = new RedirectGeneratedOneTimeTokenHandler("/redirected");
RedirectOneTimeTokenGenerationSuccessHandler handler = new RedirectOneTimeTokenGenerationSuccessHandler(
"/redirected");
handler.handle(new MockHttpServletRequest(), response, new DefaultOneTimeToken("token", "user", Instant.now()));
assertThat(response.getRedirectedUrl()).isEqualTo("/redirected");
}
@Test
void setRedirectUrlWhenNullOrEmptyThenException() {
assertThatIllegalArgumentException().isThrownBy(() -> new RedirectGeneratedOneTimeTokenHandler(null))
assertThatIllegalArgumentException().isThrownBy(() -> new RedirectOneTimeTokenGenerationSuccessHandler(null))
.withMessage("redirectUrl cannot be empty or null");
assertThatIllegalArgumentException().isThrownBy(() -> new RedirectGeneratedOneTimeTokenHandler(""))
assertThatIllegalArgumentException().isThrownBy(() -> new RedirectOneTimeTokenGenerationSuccessHandler(""))
.withMessage("redirectUrl cannot be empty or null");
}

View File

@ -45,7 +45,7 @@ public class GenerateOneTimeTokenWebFilterTests {
private final ReactiveOneTimeTokenService oneTimeTokenService = mock(ReactiveOneTimeTokenService.class);
private final ServerRedirectGeneratedOneTimeTokenHandler generatedOneTimeTokenHandler = new ServerRedirectGeneratedOneTimeTokenHandler(
private final ServerRedirectOneTimeTokenGenerationSuccessHandler generatedOneTimeTokenHandler = new ServerRedirectOneTimeTokenGenerationSuccessHandler(
"/login/ott");
private static final String TOKEN = "token";

View File

@ -29,11 +29,11 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* Tests for {@link ServerRedirectGeneratedOneTimeTokenHandler}
* Tests for {@link ServerRedirectOneTimeTokenGenerationSuccessHandler}
*
* @author Max Batischev
*/
public class ServerRedirectGeneratedOneTimeTokenHandlerTests {
public class ServerRedirectOneTimeTokenGenerationSuccessHandlerTests {
private static final String TOKEN = "token";
@ -43,7 +43,8 @@ public class ServerRedirectGeneratedOneTimeTokenHandlerTests {
@Test
void handleThenRedirectToDefaultLocation() {
ServerGeneratedOneTimeTokenHandler handler = new ServerRedirectGeneratedOneTimeTokenHandler("/login/ott");
ServerOneTimeTokenGenerationSuccessHandler handler = new ServerRedirectOneTimeTokenGenerationSuccessHandler(
"/login/ott");
MockServerWebExchange webExchange = MockServerWebExchange.from(this.request);
handler.handle(webExchange, new DefaultOneTimeToken(TOKEN, USERNAME, Instant.now())).block();
@ -54,7 +55,8 @@ public class ServerRedirectGeneratedOneTimeTokenHandlerTests {
@Test
void handleWhenUrlChangedThenRedirectToUrl() {
ServerGeneratedOneTimeTokenHandler handler = new ServerRedirectGeneratedOneTimeTokenHandler("/redirected");
ServerOneTimeTokenGenerationSuccessHandler handler = new ServerRedirectOneTimeTokenGenerationSuccessHandler(
"/redirected");
MockServerWebExchange webExchange = MockServerWebExchange.from(this.request);
handler.handle(webExchange, new DefaultOneTimeToken(TOKEN, USERNAME, Instant.now())).block();
@ -65,9 +67,11 @@ public class ServerRedirectGeneratedOneTimeTokenHandlerTests {
@Test
void setRedirectUrlWhenNullOrEmptyThenException() {
assertThatIllegalArgumentException().isThrownBy(() -> new ServerRedirectGeneratedOneTimeTokenHandler(null))
assertThatIllegalArgumentException()
.isThrownBy(() -> new ServerRedirectOneTimeTokenGenerationSuccessHandler(null))
.withMessage("redirectUri cannot be empty or null");
assertThatIllegalArgumentException().isThrownBy(() -> new ServerRedirectGeneratedOneTimeTokenHandler(""))
assertThatIllegalArgumentException()
.isThrownBy(() -> new ServerRedirectOneTimeTokenGenerationSuccessHandler(""))
.withMessage("redirectUri cannot be empty or null");
}