Skip to main content
This Quickstart is currently in Beta. We’d love to hear your feedback!

Use AI to integrate Auth0

If you use an AI coding assistant like Claude Code, Cursor, or GitHub Copilot, you can add Auth0 authentication automatically in minutes using agent skills.Install:
npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-springboot-api
Then ask your AI assistant:
Add Auth0 JWT authentication to my Spring Boot API
Your AI assistant will automatically create your Auth0 API, fetch credentials, add the Auth0 Spring Boot API SDK dependency, configure application.yml, and implement a SecurityFilterChain with JWT validation and protected endpoints. Full agent skills documentation →
Prerequisites: Before you begin, ensure you have the following installed:
  • JDK 17+ for Spring Boot 3.2+ compatibility
  • Maven 3.6+ or Gradle 7+ for dependency management
  • Your preferred IDE (IntelliJ IDEA, Eclipse, or VS Code with Java support)
Java Version Compatibility: This quickstart works with Java 17+ and Spring Boot 3.2+.

Get Started

This quickstart demonstrates how to add Auth0 JWT authentication to a Spring Boot API. You’ll build a secure API with protected endpoints using the Auth0 Spring Boot API SDK.
1

Create a new project

Create a new Spring Boot API project for this quickstart:Using Spring Initializr:
curl -L https://start.spring.io/starter.zip \
    -d dependencies=web,security \
    -d javaVersion=17 \
    -d name=auth0-api \
    -d artifactId=auth0-api \
    -d packageName=com.example.auth0api \
    -o auth0-api.zip

mkdir auth0-api && unzip auth0-api.zip -d auth0-api && cd auth0-api
Or manually create with Maven:
mvn archetype:generate \
    -DgroupId=com.example \
    -DartifactId=auth0-api \
    -DarchetypeArtifactId=maven-archetype-quickstart \
    -DinteractiveMode=false

cd auth0-api
2

Add the Auth0 SDK

Add the Auth0 Spring Boot API SDK to your project dependencies:Maven (pom.xml):
<dependency>
    <groupId>com.auth0</groupId>
    <artifactId>auth0-springboot-api</artifactId>
    <version>1.0.0-beta.0</version>
</dependency>
Gradle (build.gradle):
dependencies {
    implementation 'com.auth0:auth0-springboot-api:1.0.0-beta.0'
}
3

Setup your Auth0 API

Next up, you need to create a new API on 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 API and update your application.yml file:
AUTH0_API_NAME="My Spring Boot API" && \
AUTH0_API_IDENTIFIER="https://my-springboot-api" && \
brew tap auth0/auth0-cli && \
brew install auth0 && \
auth0 login --no-input && \
auth0 apis create -n "${AUTH0_API_NAME}" -i "${AUTH0_API_IDENTIFIER}" --offline-access --token-lifetime 86400 --signing-alg RS256 --json > auth0-api-details.json && \
DOMAIN=$(auth0 tenants list --json | jq -r '.[] | select(.active == true) | .name') && \
AUDIENCE=$(jq -r '.identifier' auth0-api-details.json) && \
mkdir -p src/main/resources && \
printf 'auth0:\n  domain: %s\n  audience: %s\n\nspring:\n  application:\n    name: auth0-api\n' "$DOMAIN" "$AUDIENCE" > src/main/resources/application.yml && \
rm auth0-api-details.json && \
echo "✅ application.yml created with your Auth0 API details:" && \
cat src/main/resources/application.yml
4

Configure authentication

Create a security configuration class to enable Auth0 JWT authentication. Create src/main/java/com/example/auth0api/SecurityConfig.java:
src/main/java/com/example/auth0api/SecurityConfig.java
package com.example.auth0api;

import com.auth0.spring.boot.Auth0AuthenticationFilter;
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.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

@Configuration
public class SecurityConfig {

    @Bean
    SecurityFilterChain apiSecurity(HttpSecurity http, Auth0AuthenticationFilter authFilter) throws Exception {
        return http
            .csrf(csrf -> csrf.disable())
            .sessionManagement(session ->
                session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/public").permitAll()
                .requestMatchers("/api/private").authenticated()
                .anyRequest().permitAll())
            .addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
            .build();
    }
}
5

Create public and protected endpoints

Create API endpoints to test authentication. Create src/main/java/com/example/auth0api/ApiController.java:
src/main/java/com/example/auth0api/ApiController.java
package com.example.auth0api;

import com.auth0.spring.boot.Auth0AuthenticationToken;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Map;

@RestController
@RequestMapping("/api")
public class ApiController {

    // Public endpoint - no authentication required
    @GetMapping("/public")
    public ResponseEntity<Map<String, String>> publicEndpoint() {
        return ResponseEntity.ok(Map.of(
            "message", "This endpoint is public - no authentication required"
        ));
    }

    // Protected endpoint - requires authentication
    @GetMapping("/private")
    public ResponseEntity<Map<String, Object>> privateEndpoint(Authentication authentication) {
        Auth0AuthenticationToken auth0Token = (Auth0AuthenticationToken) authentication;

        return ResponseEntity.ok(Map.of(
            "message", "This endpoint requires authentication",
            "user", authentication.getName(),
            "scopes", auth0Token.getAuthorities()
        ));
    }
}
6

Run your API

Start your Spring Boot application:Maven:
./mvnw spring-boot:run
Gradle:
./gradlew bootRun
Your API is now running on http://localhost:8080 (check your console output for the exact URL).
CheckpointYou should now have a fully functional Auth0-protected API running on your localhost

Advanced Usage

Test your protected endpoints with an access token.1. Get an access token from Auth0 using the Client Credentials flow:
curl --request POST \
  --url https://YOUR_DOMAIN/oauth/token \
  --header 'content-type: application/json' \
  --data '{"client_id":"YOUR_CLIENT_ID","client_secret":"YOUR_CLIENT_SECRET","audience":"YOUR_AUDIENCE","grant_type":"client_credentials"}'
To get YOUR_CLIENT_ID and YOUR_CLIENT_SECRET, create a Machine to Machine Application in the Auth0 Dashboard and authorize it for your API.
2. Test the public endpoint (should return 200 OK):
curl http://localhost:8080/api/public
3. Test the protected endpoint without authentication (should return 401 Unauthorized):
curl http://localhost:8080/api/private
4. Call the protected endpoint with the token:
curl http://localhost:8080/api/private \
  --header 'Authorization: Bearer YOUR_ACCESS_TOKEN'
Access additional user information and token claims in your endpoints.
@GetMapping("/profile")
public ResponseEntity<Map<String, Object>> getUserProfile(Authentication authentication) {
    Auth0AuthenticationToken auth0Token = (Auth0AuthenticationToken) authentication;
    Map<String, Object> claims = auth0Token.getAuthenticationContext().getClaims();

    return ResponseEntity.ok(Map.of(
        "userId", authentication.getName(),
        "email", claims.get("email"),
        "scope", claims.get("scope"),
        "issuer", claims.get("iss"),
        "audience", claims.get("aud")
    ));
}
Implement fine-grained access control using JWT scopes for enhanced security.1. Define scopes in your Auth0 API:In the Auth0 Dashboard → APIs → Your API → Permissions, add scopes:
  • read:users - Read user data
  • write:users - Write user data
  • admin - Administrative access
2. Configure authorization policies:
@Configuration
public class SecurityConfig {
    @Bean
    SecurityFilterChain apiSecurity(HttpSecurity http, Auth0AuthenticationFilter authFilter) throws Exception {
        return http
            .csrf(csrf -> csrf.disable())
            .sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/admin/**").hasAuthority("SCOPE_admin")
                .requestMatchers("/api/users/**").hasAnyAuthority("SCOPE_read:users", "SCOPE_write:users")
                .requestMatchers("/api/private").authenticated()
                .anyRequest().permitAll())
            .addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
            .build();
    }
}
When requesting an access token, include the required scope:
curl --request POST \
  --url https://YOUR_DOMAIN/oauth/token \
  --header 'content-type: application/json' \
  --data '{"client_id":"YOUR_CLIENT_ID","client_secret":"YOUR_CLIENT_SECRET","audience":"YOUR_AUDIENCE","grant_type":"client_credentials","scope":"read:users write:users admin"}'
Enable DPoP (Demonstration of Proof-of-Possession) for enhanced token security that binds access tokens to cryptographic keys.Configure DPoP support in application.yml:
auth0:
  domain: "your-tenant.auth0.com"
  audience: "https://my-springboot-api"
  dpopMode: ALLOWED # DISABLED, ALLOWED (default), REQUIRED
  dpopIatOffsetSeconds: 300 # 5 minutes (default)
  dpopIatLeewaySeconds: 60 # 1 minute leeway (default: 30s)
DPoP Modes:
  • ALLOWED (default): Accepts both Bearer and DPoP tokens
  • REQUIRED: Only accepts DPoP tokens, rejects Bearer tokens
  • DISABLED: Standard JWT Bearer validation only
    Learn more about DPoP in the Auth0 DPoP Documentation.

Common Issues

Problem: API returns 401 even with valid tokens.Solution: Ensure auth0.audience exactly matches your Auth0 API identifier. The audience claim in the token must match this value.
# ❌ WRONG
auth0:
  audience: "my-api"

# ✅ CORRECT
auth0:
  audience: "https://my-springboot-api"
Problem: Token issuer validation fails.Solution: Verify your Domain is correct and does not include https://. Use domain without https:// prefix.
# ❌ WRONG
auth0:
  domain: "https://your-tenant.auth0.com"

# ✅ CORRECT
auth0:
  domain: "your-tenant.auth0.com"
Problem: Application fails to start with configuration errors.Solution: Verify application.yml structure and property names. Ensure the auth0 section contains Domain and Audience values.
# ✅ CORRECT structure
auth0:
  domain: "your-tenant.auth0.com"
  audience: "https://your-api-identifier"

spring:
  application:
    name: auth0-api
Problem: Authentication not working despite correct configuration.Solution: Ensure Auth0AuthenticationFilter is properly integrated with Spring Security chain. The filter must be added before UsernamePasswordAuthenticationFilter.
// ✅ CORRECT filter order
.addFilterBefore(authFilter, UsernamePasswordAuthenticationFilter.class)
Problem: JWKS retrieval failures or connection timeouts.Solution: Corporate firewall may be blocking Auth0 endpoints. Whitelist Auth0 domains for HTTPS access:
# Required firewall rules (outbound HTTPS/443)
*.auth0.com
*.us.auth0.com  # For US region tenants
*.eu.auth0.com  # For EU region tenants
*.au.auth0.com  # For AU region tenants
Problem: Scope-based authorization policies always fail.Solution: Ensure your access token includes the required scopes. When requesting a token, specify the scopes:
curl --request POST \
  --url https://YOUR_DOMAIN/oauth/token \
  --data '{"client_id":"...","client_secret":"...","audience":"...","grant_type":"client_credentials","scope":"read:users write:users admin"}'
Also verify scopes are defined in your Auth0 API settings (Dashboard → APIs → Your API → Permissions).

Additional Resources

SDK Documentation

Complete SDK documentation and API reference

Code Examples

Comprehensive code examples and integration patterns

DPoP Documentation

Learn about proof-of-possession security enhancement

Spring Security Reference

Official Spring Security documentation

Auth0 Dashboard

Manage your Auth0 APIs and applications

Community Forum

Get help from the Auth0 community

Sample Application

A complete sample application demonstrating all features is available in the SDK repository.

Playground Application

Includes public and protected endpoints, DPoP support, and comprehensive examples
Clone and run:
git clone https://github.com/auth0/auth0-auth-java.git
cd auth0-auth-java/auth0-springboot-api-playground

# Update src/main/resources/application.yml with your Auth0 configuration
# Then run:
./mvnw spring-boot:run
Testing with curl:
# Test public endpoint
curl http://localhost:8080/api/public

# Get access token (replace with your Auth0 credentials)
curl -X POST https://YOUR_DOMAIN/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "audience": "https://my-springboot-api",
    "grant_type": "client_credentials"
  }'

# Test protected endpoint with Bearer token
curl -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
     http://localhost:8080/api/private