passkeys java spring bootPasskeys Implementation

How to Implement Passkeys in Java Spring Boot Apps

Java Spring Boot & Passkeys: This tutorial shows how to integrate passkeys into Java Spring Boot apps by implementing passkey-first auth & session management.

Blog-Post-Author

Nicolai

Created: September 19, 2023

Updated: October 11, 2024


We aim to make the Internet a safer place using passkeys. That's why we want to support developers with tutorials on how to implement passkeys.

1. Introduction#

In this blog post, we'll be walking through the process of building a sample application with passkey authentication using Java Spring Boot with Thymeleaf template engine. To make passkeys work, we use Corbado's passkey-first UI component that automatically connects to a passkeys backend.

If you want to see the finished code, please have a look at our sample application GitHub repository.

The result looks as follows:

java spring boot passkey component login

2. Java Spring Boot Passkey Project Prerequisites#

This tutorial assumes basic familiarity with HTML and Java Spring Boot. You will also need to install the Corbado Java SDK. Use latest version available. We will take 0.0.1 as an example. Add it as a dependency to your project's build/pom file:

2.1 Gradle Users#

implementation "com.corbado:corbado-java:0.0.1"

2.2 Maven Users#

Add this dependency to your project's pom.xml:

pom.xml
<dependency> <groupId>com.corbado</groupId> <artifactId>corbado-java</artifactId> <version>0.0.1</version> </dependency>

Let's dive in!

Ben Gould Testimonial

Ben Gould

Head of Engineering

I’ve built hundreds of integrations in my time, including quite a few with identity providers and I’ve never been so impressed with a developer experience as I have been with Corbado.

10,000+ devs trust Corbado & make the Internet safer with passkeys. Got questions? We’ve written 150+ blog posts on passkeys.

Join Passkeys Community

3. Repository Structure for Java Spring Boot Passkey Project#

A Java Spring Boot project contains many files, but the only ones important for us are in the /complete/src/main folder. The templates are located under /resources/templates while the FrontendController.java as well as its JsonReader.java helper class are located in a separate folder.

├── complete | ├── src/main | | ├── java/com/corbado/springboot | | | ├── FrontendController.java # Main controller which renders the HTML templates | | | └── JsonReader.java # Fetches json from web URLs | | | | | └── resources | | ├── application.properties # Contains the environment variables | | └── templates | | ├── index.html # Login page with the UI component | | └── profile.html # Profile page with user information | └── pom.xml # Contains info about the project and implementation details

4. Set Up Your Corbado Account and Project#

Visit the Corbado developer panel to sign up and create your account (you'll see passkey sign-up in action here!).

passkey sign up java spring boot

After sign-up, a project wizard will guide you through the necessary steps to get everything up and running:

  1. Begin by selecting an appropriate name for your project.
  2. For the product selection, opt for "Corbado Complete".
  3. Register your community license and optionally join our Passkeys Community or subscribe to the Passkeys Substack.
  4. Select "DEV" as your environment.
  5. Choose "Corbado session management" to get a secure and efficient session management besides passkey authentication.
  6. Choose "Web app" as we're building a web application.
  7. Select "Vanilla JS" as your frontend framework.
  8. Provide the Application URL and Relying Party ID. The Application URL is the URL where you embed the Corbado UI component. In this example, we set it to http://localhost:8080. The Relying Party ID is the domain (no protocol, no port and no path) where passkeys should be bound to. Here, it's localhost (you can define both values als in the Settings > General > URLs of the Corbado developer panel).
Slack Icon

Become part of our Passkeys Community for updates and support.

Join

Afterwards, you'll see the relevant HTML / JavaScript code snippets you need to integrate into the project. The subsequent sections of this article will explain them in detail.

As another step, we create an API secret which will be needed to request user data from the Corbado backend. Please create an API secret in Settings > Credentials > API secrets.

Corbado Developer Panel: Create API Secret for PHP Laravel Project

5. Create Java Spring Boot Passkeys App#

To initialize our project, we clone Java Spring Boot's starter repository with

git clone https://github.com/spring-guides/gs-spring-boot.git

In the /complete/src/main/java/com/example/springboot folder, you will find the HelloController.java. We rename it to FrontendController.java and use it to serve plain HTML files when a user requests a certain path.

We will need the Corbado project ID and API secret in the next steps, so we'll add them as an environment variable. For this, we create an application.properties file under /complete/src/main/resources and add them there:

.env
projectID=pro-xxx apiSecret=corbado1_xxx

6. Create Passkeys Login Page#

Under /complete/src/main/resources/templates create an index.html file with the content below. This will be our login page.

6.1 Embed the Passkey-First UI Component#

Add to the index.html a script from Corbado as well as the code for the UI component.

index.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <link rel="stylesheet" href="https://unpkg.com/@corbado/web-js@2.8.0/dist/bundle/index.css" /> <script src="https://unpkg.com/@corbado/web-js@2.8.0/dist/bundle/index.js" defer></script> </head> <body> <script th:inline="javascript"> document.addEventListener('DOMContentLoaded', async () => { await Corbado.load({ projectId: /*[[${PROJECT_ID}]]*/, darkMode: "off", setShortSessionCookie: "true", }); const authElement = document.getElementById('corbado-auth'); Corbado.mountAuthUI(authElement, { onLoggedIn: () => { window.location.href = '/profile'; }, }); }); </script> <div id="corbado-auth"></div> </body> </html>

6.2 Add Controller Endpoint for Passkeys Login Page#

To make things work, we modify the index endpoint in our FrontendController.java to render our login page template. The Corbado project ID and API secret are taken from the environment variables, used by SDK and are inserted into the template upon rendering.

FrontendController.java
@Controller public class FrontendController { @Value("${projectID}") private String projectID; @Value("${apiSecret}") private String apiSecret; private final CorbadoSdk sdk; @Autowired public FrontendController( @Value("${projectID}") final String projectID, @Value("${apiSecret}") final String apiSecret) throws StandardException { final Config config = new Config(projectID, apiSecret); this.sdk = new CorbadoSdk(config); } @RequestMapping("/") public String index(final Model model) { model.addAttribute("PROJECT_ID", projectID); return "index"; } ....
Substack Icon

Subscribe to our Passkeys Substack for the latest news, insights and strategies.

Subscribe

7. Add Passkey Profile Page#

After successful authentication, the Corbado UI component redirects the user. This page displays information about the user and provides a button to log out. In the templates folder, add a file profile.html with the following content:

profile.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <link rel="stylesheet" href="https://unpkg.com/@corbado/web-js@2.8.0/dist/bundle/index.css" /> <script src="https://unpkg.com/@corbado/web-js@2.8.0/dist/bundle/index.js" defer></script> </head> <body> <!-- Define passkey-list div and logout button --> <h2>:/protected</h2> <p>User ID: [[${USER_ID}]]</p> <p>Name: [[${USER_NAME}]]</p> <p>Email: [[${USER_EMAIL}]]</p> <div id="passkey-list"></div> <button id="logoutButton">Logout</button> <!-- Script to load Corbado and mount PasskeyList UI --> <script th:inline="javascript"> document.addEventListener('DOMContentLoaded', async () => { await Corbado.load({ projectId: /*[[${PROJECT_ID}]]*/, darkMode: "off", setShortSessionCookie: "true" // set short session cookie automatically }); // Get and mount PasskeyList UI const passkeyListElement = document.getElementById("passkey-list"); // Element where you want to render PasskeyList UI Corbado.mountPasskeyListUI(passkeyListElement); // Get logout button const logoutButton = document.getElementById('logoutButton'); // Add event listener to logout button logoutButton.addEventListener('click', function() { Corbado.logout() .then(() => { window.location.replace("/"); }) .catch(err => { console.error(err); }); }); })(); </script> </body> </html>

Next, create a profile() method with annotation inside the FrontendController.java:

FrontendController.java
@RequestMapping("/profile") public String profile() { return "profile"; }

We now need to obtain the user information we want to display in the profile.html template.

7.1 Verify Corbado Session#

Before we can use information embedded in the session, we need to verify that the session is valid. We therefore take the cbo_short_session cookie (the session) and verify its signature using the session service from the Corbado Java SDK. This can be done with:

final SessionValidationResult validationResp = sdk.getSessions().getAndValidateCurrentUser(cboShortSession);

7.2 Get Data from Corbado Session#

It takes the cbo_short_session cookie, validates it and returns the UserID and full name of the user.

The final code for the profile mapping looks as follows:

FrontendController.java
@RequestMapping("/profile") public String profile( final Model model, @CookieValue("cbo_short_session") final String cboShortSession) { try { // Validate user from token final SessionValidationResult validationResp = sdk.getSessions().getAndValidateCurrentUser(cboShortSession); // get list of emails from identifier service List<Identifier> emails; emails = sdk.getIdentifiers().listAllEmailsByUserId(validationResp.getUserID()); // model.addAttribute("PROJECT_ID", projectID); model.addAttribute("USER_ID", validationResp.getUserID()); model.addAttribute("USER_NAME", validationResp.getFullName()); // select email of your liking or list all emails model.addAttribute("USER_EMAIL", emails.get(0).getValue()); } catch (final Exception e) { System.out.println(e.getMessage()); model.addAttribute("ERROR", e.getMessage()); return "error"; } return "profile"; }

8. Start Using Passkeys with our Java Implementation#

To start our application, we head into the /complete directory of our app and execute:

./mvnw spring-boot:run

When visiting http://localhost:8080, you should see the following screen:

java spring boot passkey component login

After successful sign up / login, you see the profile page:

java spring boot passkey list component

Java Spring Icon

Add passkeys to your Java Spring app.

Start For Free

9. Conclusion#

This tutorial showed how easy it is to add passwordless authentication with passkeys to a Java Spring Boot app using Corbado. Besides the passkey-first authentication, Corbado provides simple session management, that we used for a retrieval of basic user data. If you want to read more about how Corbado's session management please check the docs here. If you want to add Corbado to your existing app with existing users, please see our documentation here.

Share this article


LinkedInTwitterFacebook

Enjoyed this read?

🤝 Join our Passkeys Community

Share passkeys implementation tips and get support to free the world from passwords.

🚀 Subscribe to Substack

Get the latest news, strategies, and insights about passkeys sent straight to your inbox.


We provide UI components, SDKs and guides to help you add passkeys to your app in <1 hour

Start for free