Spring Security OneTimeToken
How can we use one time token with spring security and spring boot.
Starting from Spring Security 6.4 it now supports One-Time Token (OTT) authentication via the oneTimeTokenLogin()
DSL.
One-time token is a way where user can log in the system through EMAIL or SMS. They don't need to use a password to do it.
How does It work?
User enters his username/email and requests for one-time token.
Spring security validates the user's existence, generates token and sends a one-time token login link to their corresponding email or phone number.
The user receives the link and by clicking it, he redirects to the link, where he does login with the token provided.
The system validates the token, do the authentication process and allows him to view the secured content.
Classes involved in the token generation
oneTimeTokenLogin()
dsl
oneTimeTokenLogin()
dslIt is a functional method that is used to configure one time token login in spring security.
It takes
OneTimeTokenLoginConfigurer
customizer as parameter.
OneTimeTokenLoginConfigurer
It's a configurer class that is used to configure one time token login dsl.
It provides default methods and configuration properties that are helpful in defining the one time token login configuration.
Here are the classes and the properties defined-
private OneTimeTokenService oneTimeTokenService = new InMemoryOneTimeTokenService();
private AuthenticationConverter authenticationConverter = new OneTimeTokenAuthenticationConverter();
private AuthenticationFailureHandler authenticationFailureHandler = new SimpleUrlAuthenticationFailureHandler();
private AuthenticationSuccessHandler authenticationSuccessHandler = new SavedRequestAwareAuthenticationSuccessHandler();
private String defaultSubmitPageUrl = "/login/ott"; // default login page for ott, can be changed to custom one but need to handle csrf
private boolean submitPageEnabled = true; // enabled/disabled the submit page for ott
private String loginProcessingUrl = "/login/ott"; // url to process token, and gets called after varification
private String tokenGeneratingUrl = "/ott/generate"; // configured the ott token generator, in memory, jdbc
private OneTimeTokenGenerationSuccessHandler oneTimeTokenGenerationSuccessHandler = new RedirectOneTimeTokenGenerationSuccessHandler();
private AuthenticationProvider authenticationProvider = new OneTimeTokenAuthenticationProvider();
GenerateOneTimeTokenFilter
It's a filter that processes one-time token request with ant path matcher /ott/generate.
It has the
OneTimeTokenService
andOneTimeTokenGenerationSuccessHandler
configured that helps in filtering the request.It checks if request is for /ott/generate then validates the user and generates the one-time token and pass it to one time token success handler.
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
if (!this.requestMatcher.matches(request)) {
filterChain.doFilter(request, response);
return;
}
String username = request.getParameter("username");
if (!StringUtils.hasText(username)) {
filterChain.doFilter(request, response);
return;
}
GenerateOneTimeTokenRequest generateRequest = new GenerateOneTimeTokenRequest(username);
OneTimeToken ott = this.tokenService.generate(generateRequest);
this.tokenGenerationSuccessHandler.handle(request, response, ott);
}
OneTimeTokenAuthenticationProvider
It is an
AuthenticationProvider (I)
implementation class, responsible for authenticating users based on one-time tokens.It uses an
OneTimeTokenService
to consume tokens and anUserDetailsService
to fetch user authorities.It is configured by default when we will use
oneTimeTokenLogin()
dsl.It has
public Authentication authenticate(Authentication authentication){}
method.This method authenticates the user, validates the token and generates a
OneTimeTokenAuthenticationToken
with user details.
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
OneTimeTokenAuthenticationToken otpAuthenticationToken = (OneTimeTokenAuthenticationToken) authentication;
OneTimeToken consumed = this.oneTimeTokenService.consume(otpAuthenticationToken);
if (consumed == null) {
throw new InvalidOneTimeTokenException("Invalid token");
}
UserDetails user = this.userDetailsService.loadUserByUsername(consumed.getUsername());
OneTimeTokenAuthenticationToken authenticated = OneTimeTokenAuthenticationToken.authenticated(user,
user.getAuthorities());
authenticated.setDetails(otpAuthenticationToken.getDetails());
return authenticated;
}
DefaultLoginPageGeneratingFilter
It is a filter responsible for generating the HTML pages for various login request.
It generates templates for- login, token generation, token verification, ouath2 and passkeys.
It generates the pages based on the flag passed in security config like formLogin().
DefaultOneTimeTokenSubmitPageGeneratingFilter
It is the filter that creates a default one-time token submit page.
If the request contains a token query parameter, then the page will automatically fill the form with the token value.
It gets invoked on URL -
/login/ott
[default submit url]In the form it has the loggin processing url that url configured or to
/login/ott [post]
It generates the page by capturing token from query path and gives continue button to user to login in the system.
OneTimeTokenAuthenticationConverter
It is an implementation of AuthenticationConverter that detects if the request contains a token parameter and constructs a OneTimeTokenAuthenticationToken with it.
public Authentication convert(HttpServletRequest request) {
String token = request.getParameter("token");
if (!StringUtils.hasText(token)) {
this.logger.debug("No token found in request");
return null;
}
return OneTimeTokenAuthenticationToken.unauthenticated(token);
}
SimpleUrlAuthenticationSuccessHandler
It is an implementation class of
AuthenticationSuccessHandler (I)
.It gets invoked upon successful authentication of the token and then redirects to the page configured.
It checks for the URL that user configured and redirects to it.
SimpleUrlAuthenticationFailureHandler
It is an implementation class of
AuthenticationFailureHandler (I)
.It gets invoked upon authentication failure when
onAuthenticationFailure
and then redirects to the URL configured bydefaultFailureUrl
It checks for the URL that user configured and redirects to it.
OneTimeTokenService
It is an Interface for generating and consuming one-time tokens.
It has implementation as -
InMemoryOneTimeTokenService - Contains map of username and token.
JdbcOneTimeTokenService - Stores info in database.
We can also implement our own one time token service.
By default, it sets the expiry time as 5 minutes.
OneTimeTokenGenerationSuccessHandler
It is an interface that users need to implement and do the work after token generation.
It has one method -
public void handle(HttpServletRequest request, HttpServletResponse response, OneTimeToken oneTimeToken)
Once the token generated successfully, this method will get invoked where the user can send the token via mail or SMS.
After doing the process, the user can redirect to any success page that informs the user that the token got generated and delivered successfully.
Last updated