Master One-Time Token Login in Spring Boot 3: A Step‑by‑Step Guide
This article explains how to implement One-Time Token (OTT) authentication in Spring Boot 3.4 using Spring Security, covering environment setup, required dependencies, security configuration, token generation handlers, custom storage options, custom login pages, and testing procedures with complete code examples.
1. Introduction
One-Time Token (OTT) is a security mechanism that can be used only once, preventing replay attacks. Spring Security provides the oneTimeTokenLogin() DSL to support OTT authentication, allowing users to log in without additional account setup.
2. Practical Example
2.1 Environment Preparation
Spring Boot version: 3.4.0
Add the following dependencies:
<code><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency></code>2.2 Security Configuration with OTT
Create two simple controllers:
<code>@RestController
@RequestMapping("/api")
public class ApiController {
@GetMapping("/query")
public String query() { return "query"; }
}
@RestController
@RequestMapping("/sent")
public class SendController {
@GetMapping("/ott")
public String ott() {
return "Authentication info has been sent to your email";
}
}</code>Configure the security filter chain to permit the /sent/** endpoint and enable OTT:
<code>@Configuration
public class SecurityConfig {
@Bean
SecurityFilterChain ottFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(registry -> {
registry.requestMatchers("/sent/**").permitAll();
registry.anyRequest().authenticated();
})
.formLogin(Customizer.withDefaults())
.oneTimeTokenLogin(Customizer.withDefaults());
return http.build();
}
}</code>2.3 OTT Success Handler
Implement a bean that builds a magic link and sends it by email:
<code>@Component
public class PackOneTimeTokenGenerationSuccessHandler implements OneTimeTokenGenerationSuccessHandler {
private final OneTimeTokenGenerationSuccessHandler redirectHandler =
new RedirectOneTimeTokenGenerationSuccessHandler("/sent/ott");
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, OneTimeToken ott)
throws IOException, ServletException {
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(UrlUtils.buildFullRequestUrl(request))
.replacePath(request.getContextPath())
.replaceQuery(null)
.fragment(null)
.path("/login/ott")
.queryParam("token", ott.getTokenValue());
String magicLink = builder.toUriString();
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setSubject("Spring Boot OTT Login");
mailMessage.setFrom("[email protected]");
mailMessage.setTo("[email protected]");
mailMessage.setText("OTT authentication, <a href=\"" + magicLink + "\">click to login</a>");
try { this.mailSender.send(mailMessage); } catch (MailException ex) { System.err.println("Mail error: " + ex.getMessage()); }
this.redirectHandler.handle(request, response, ott);
}
}</code>Note: The default token is stored in memory and expires after 5 minutes.
2.4 Custom Token Storage
Spring Security offers two implementations of OneTimeTokenService : InMemoryOneTimeTokenService (default) and JdbcOneTimeTokenService . To use a JDBC store, define a bean and create the table:
<code>@Bean
public JdbcOneTimeTokenService jdbcOneTimeTokenService(JdbcTemplate jdbcTemplate) {
return new JdbcOneTimeTokenService(jdbcTemplate);
}
CREATE TABLE `one_time_tokens` (
`token_value` varchar(36) NOT NULL,
`username` varchar(50) NOT NULL,
`expires_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`token_value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
</code>The service automatically schedules an hourly cleanup job.
2.5 Custom OTT Page
Create a custom HTML form that posts to /ott/generate and allow it through the security configuration:
<code><form id="ott-form" method="post" action="/ott/generate">
<h2>OTT Login</h2>
<p>
<label for="ott-username">Username</label>
<input type="text" id="ott-username" name="username" placeholder="Enter username" required>
</p>
<button type="submit">Send Token</button>
</form>
</code>Update the security matcher to permit *.html files:
<code>http.authorizeHttpRequests(registry -> {
registry.requestMatchers("/sent/**", "*.html").permitAll();
});
</code>2.6 Testing the OTT Flow
1. Access a protected endpoint such as /api/query . You will be redirected to the login page with two forms (username/password and OTT). 2. Enter the username and click “Send Token”. 3. Check the email, click the magic link, and then click “Sign in” on the token verification page. The whole process completes with minimal code.
All the above steps demonstrate how to integrate One-Time Token authentication into a Spring Boot 3 application.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.