Skip to main content
Prerequisites:
  • JDK 17+ (download)
  • Maven 3.6+ or Gradle 7+ (Maven | Gradle)
  • An IDE (IntelliJ IDEA, Eclipse, or VS Code recommended)
Java Version Compatibility: Spring Boot 3.x+ and the Okta Spring Boot Starter 3.x require Java 17 or higher.

Get Started

This quickstart demonstrates how to add Auth0 login to a Spring Boot web application. You’ll build a secure web app with login, logout, and a protected profile page using the Okta Spring Boot Starter, which auto-configures Spring Security’s OAuth2 login support.
1

Create a new project

Generate a Spring Boot project with the required dependencies.
curl -L https://start.spring.io/starter.zip \
    -d dependencies=web,security,thymeleaf \
    -d javaVersion=17 \
    -d name=auth0-webapp \
    -d artifactId=auth0-webapp \
    -d packageName=com.auth0.example \
    -o auth0-webapp.zip

mkdir auth0-webapp && unzip auth0-webapp.zip -d auth0-webapp && cd auth0-webapp
2

Add the Okta Spring Boot Starter

Add the Okta Spring Boot Starter dependency to your project. This pulls in Spring Security OAuth2 login support with Auth0/Okta-specific auto-configuration.
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.thymeleaf.extras</groupId>
    <artifactId>thymeleaf-extras-springsecurity6</artifactId>
</dependency>
<dependency>
    <groupId>com.okta.spring</groupId>
    <artifactId>okta-spring-boot-starter</artifactId>
    <version>3.1.0</version>
</dependency>
3

Configure Auth0

Create a Regular Web Application in your Auth0 tenant and add the configuration to your project.You can choose to do this automatically by running a CLI command or do it manually via the Dashboard:
Run the following shell command on your project’s root directory to create an Auth0 application and update your application.yml file:
AUTH0_APP_NAME="My Spring Boot Webapp" && \
brew tap auth0/auth0-cli && \
brew install auth0 && \
auth0 login --no-input && \
auth0 apps create -n "${AUTH0_APP_NAME}" -t regular \
    --callbacks "http://localhost:3000/login/oauth2/code/okta" \
    --logout-urls "http://localhost:3000/" \
    --json > auth0-app-details.json && \
DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && \
CLIENT_ID=$(jq -r '.client_id' auth0-app-details.json) && \
CLIENT_SECRET=$(jq -r '.client_secret' auth0-app-details.json) && \
mkdir -p src/main/resources && \
printf 'server:\n  port: 3000\n\nokta:\n  oauth2:\n    issuer: https://%s/\n    client-id: %s\n    client-secret: %s\n' "$DOMAIN" "$CLIENT_ID" "$CLIENT_SECRET" > src/main/resources/application.yml && \
rm auth0-app-details.json && \
echo "✅ application.yml created with your Auth0 app details:" && \
cat src/main/resources/application.yml
4

Configure authentication

Create a security configuration that enables OAuth2 login and handles Auth0 logout. Unauthenticated users are redirected to the Auth0 login page automatically.
// src/main/java/com/auth0/example/SecurityConfig.java

package com.auth0.example;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import java.io.IOException;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
public class SecurityConfig {

    @Value("${okta.oauth2.issuer}")
    private String issuer;
    @Value("${okta.oauth2.client-id}")
    private String clientId;

    @Bean
    public SecurityFilterChain configure(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(authorize -> authorize
                .requestMatchers("/", "/images/**").permitAll()
                .anyRequest().authenticated()
            )
            .oauth2Login(withDefaults())
            .logout(logout -> logout
                .addLogoutHandler(logoutHandler()));
        return http.build();
    }

    private LogoutHandler logoutHandler() {
        return (request, response, authentication) -> {
            try {
                String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString();
                response.sendRedirect(issuer + "v2/logout?client_id=" + clientId + "&returnTo=" + baseUrl);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
}
5

Create controllers and views

Create the controllers and the Thymeleaf templates for the home and profile pages.
6

Run your application

Start the application using the Maven or Gradle wrapper.
./mvnw spring-boot:run
Your application is now running on http://localhost:3000. Navigate to http://localhost:3000/profile to trigger the Auth0 login flow.
You should now have a fully functional Spring Boot web application with Auth0 login running on your localhost. The home page is public, and navigating to /profile redirects unauthenticated users to the Auth0 login page.

Advanced Usage

The @AuthenticationPrincipal OidcUser parameter gives you access to all claims from the ID token. Use getClaims() to retrieve the full set or individual getter methods for specific claims.
@GetMapping("/profile")
public String profile(Model model, @AuthenticationPrincipal OidcUser oidcUser) {
    model.addAttribute("name", oidcUser.getFullName());
    model.addAttribute("email", oidcUser.getEmail());
    model.addAttribute("picture", oidcUser.getPicture());
    model.addAttribute("sub", oidcUser.getSubject());
    model.addAttribute("allClaims", oidcUser.getClaims());
    return "profile";
}
You can restrict access to pages based on Auth0 roles. First, add roles to the ID token using an Auth0 Action, then use hasAuthority() in your security configuration.

Add Roles to Tokens

  1. Go to Auth0 DashboardActionsFlowsLogin.
  2. Create a custom Action that adds roles as a custom claim to the ID token:
exports.onExecutePostLogin = async (event, api) => {
  const namespace = "https://my-app.example.com";
  if (event.authorization) {
    api.idToken.setCustomClaim(`${namespace}/roles`, event.authorization.roles);
  }
};

Configure Authorization

Update your SecurityConfig to require specific roles on endpoints:
@Bean
public SecurityFilterChain configure(HttpSecurity http) throws Exception {
    http
        .authorizeHttpRequests(authorize -> authorize
            .requestMatchers("/", "/images/**").permitAll()
            .requestMatchers("/admin/**").hasAuthority("ROLE_admin")
            .anyRequest().authenticated()
        )
        .oauth2Login(withDefaults())
        .logout(logout -> logout
            .addLogoutHandler(logoutHandler()));
    return http.build();
}
The Okta starter supports custom authority mapping through the AuthoritiesProvider interface. Register a bean to add custom GrantedAuthority objects based on user attributes or external data sources.
package com.auth0.example;

import com.okta.spring.boot.oauth.AuthoritiesProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Configuration
public class AuthoritiesConfig {

    @Bean
    AuthoritiesProvider customAuthoritiesProvider() {
        return (user, userRequest) -> {
            Set<GrantedAuthority> authorities = new HashSet<>();

            // Map custom roles claim to Spring Security authorities
            Object roles = user.getAttribute("https://my-app.example.com/roles");
            if (roles instanceof List<?> roleList) {
                roleList.forEach(role ->
                    authorities.add(new SimpleGrantedAuthority("ROLE_" + role))
                );
            }

            return authorities;
        };
    }
}

Common Issues

After selecting login, Auth0 shows an error about a callback URL mismatch.The Allowed Callback URLs in your Auth0 application must exactly match the callback URL used by Spring Security. The default is http://localhost:3000/login/oauth2/code/okta.
  1. Go to Auth0 DashboardApplications → Your App → Settings.
  2. Under Allowed Callback URLs, add: http://localhost:3000/login/oauth2/code/okta.
  3. Choose Save Changes.
The application fails to start or login fails with an issuer mismatch.The okta.oauth2.issuer must be the full Auth0 tenant URL including https:// and a trailing /.
# ❌ WRONG - missing https:// or trailing slash
okta:
  oauth2:
    issuer: "dev-abc123.us.auth0.com"

# ✅ CORRECT - full URL with trailing slash
okta:
  oauth2:
    issuer: "https://dev-abc123.us.auth0.com/"
The application fails to start with a connection error when fetching /.well-known/openid-configuration.The Okta Spring Boot Starter fetches the OpenID Connect discovery document from your issuer URL at startup. Verify that the issuer URL is correct and reachable from your network. If behind a corporate firewall, configure the proxy:
okta:
  oauth2:
    issuer: "https://dev-abc123.us.auth0.com/"
    proxy:
      host: "proxy.example.com"
      port: 8080
The application starts but login fails because configuration properties are not being read.Ensure your application.yml uses the correct YAML indentation under the okta.oauth2 namespace:
# ❌ WRONG - flat structure, not nested
okta.oauth2.issuer: "https://dev-abc123.us.auth0.com/"

# ✅ CORRECT - properly nested YAML
okta:
  oauth2:
    issuer: "https://dev-abc123.us.auth0.com/"
    client-id: "YOUR_CLIENT_ID"
    client-secret: "YOUR_CLIENT_SECRET"
After selecting logout, the user is immediately logged back in without seeing the Auth0 login page.Ensure your SecurityConfig includes the custom LogoutHandler that redirects to the Auth0 /v2/logout endpoint. Also verify that the Allowed Logout URLs in your Auth0 Application Settings includes http://localhost:3000/.

Additional Resources

SDK Documentation

Complete SDK documentation, source code, and release notes

Auth0 Documentation

Official Auth0 documentation for Spring Boot applications

Spring Security Reference

Spring Security OAuth2 Login documentation

Configuration Reference

All available okta.oauth2.* configuration properties

Auth0 Dashboard

Manage your Auth0 APIs and applications

Community Forum

Get help from the Auth0 community

Sample Application

A complete sample application demonstrating login, profile display, and logout with Auth0 is available in the Auth0 samples repository.

MVC Login Sample

Includes login, logout, and profile page with Auth0 OAuth2 integration
Clone and run:
git clone https://github.com/auth0-samples/auth0-spring-boot-login-samples.git
cd auth0-spring-boot-login-samples/mvc-login

# Update src/main/resources/application.yml with your Auth0 configuration
# Then run:
./gradlew bootRun
Open http://localhost:3000 in your browser and select the Login link to test the Auth0 login flow.