Skip to main content

Overview

Hub uses Auth0 for authentication and authorization. The backend validates JWT tokens issued by Auth0 and extracts user permissions for role-based access control.
The Hub platform implements OAuth 2.0 with JWT bearer tokens for stateless authentication.

Prerequisites

Before configuring authentication, you need:
  • An Auth0 account
  • An Auth0 API configured for your application
  • Auth0 Application (SPA or Regular Web App) for your frontend

Auth0 Setup

1

Create Auth0 API

  1. Log in to your Auth0 dashboard
  2. Navigate to Applications > APIs
  3. Click Create API
  4. Set a name (e.g., “Hub API”) and identifier (e.g., https://api.padelhub.com)
  5. Keep the signing algorithm as RS256
2

Configure permissions

In your Auth0 API, define permissions for different user roles:
  • read:venues - View venue information
  • write:venues - Create and update venues
  • read:bookings - View own bookings
  • write:bookings - Create bookings
  • admin:all - Full administrative access
3

Create Auth0 Application

  1. Go to Applications > Applications
  2. Click Create Application
  3. Choose Single Page Web Applications (for React/Vue frontends)
  4. Configure the following:
    • Allowed Callback URLs: http://localhost:3000/callback, https://app.padelhub.com/callback
    • Allowed Logout URLs: http://localhost:3000, https://app.padelhub.com
    • Allowed Web Origins: http://localhost:3000, https://app.padelhub.com
4

Get configuration values

From your Auth0 dashboard, collect:
  • Domain: Found in your API settings (e.g., padelhub.eu.auth0.com)
  • Audience: Your API identifier (e.g., https://api.padelhub.com)

Environment Configuration

Set the following environment variables:
AUTH0_ISSUER
string
required
Auth0 issuer URI for JWT validationFormat: https://YOUR_DOMAIN.auth0.com/Example: https://padelhub.eu.auth0.com/
Must include the trailing slash /
AUTH0_AUDIENCE
string
required
Auth0 API audience identifierExample: https://api.padelhub.comThis must exactly match the identifier you set when creating the Auth0 API.
AUTH0_ISSUER=https://padelhub.eu.auth0.com/
AUTH0_AUDIENCE=https://api.padelhub.com

JWT Token Structure

The backend expects JWT tokens with the following claims:
JWT Token Claims
{
  "iss": "https://padelhub.eu.auth0.com/",
  "sub": "auth0|6479e1234567890abcdef",
  "aud": "https://api.padelhub.com",
  "iat": 1678901234,
  "exp": 1678987634,
  "scope": "openid profile email",
  "permissions": [
    "read:venues",
    "write:bookings",
    "read:bookings"
  ]
}

Key Claims

  • iss (Issuer): Auth0 domain, validated against AUTH0_ISSUER
  • aud (Audience): API identifier, validated against AUTH0_AUDIENCE
  • sub (Subject): Unique user identifier (Auth0 user ID)
  • permissions: Array of user permissions for authorization
  • scope: OAuth 2.0 scopes

Authorization Flow

1

User requests authentication

Frontend redirects user to Auth0 login page with your application’s client ID.
2

User authenticates

User logs in via Auth0 (username/password, social login, etc.).
3

Auth0 issues tokens

Auth0 returns an access token (JWT) and optional refresh token.
4

Frontend includes token

Frontend includes the JWT in the Authorization header:
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
5

Backend validates token

The backend:
  1. Verifies the JWT signature using Auth0’s public keys
  2. Validates the issuer matches AUTH0_ISSUER
  3. Validates the audience matches AUTH0_AUDIENCE
  4. Checks token expiration
  5. Extracts permissions for authorization
6

User synchronized

The EnsureLocalUserFilter ensures a local user record exists in the database, creating one if necessary.

Security Configuration

The application implements several security measures:

CORS Configuration

Allowed origins are configured based on APP_FRONTEND_URL:
SecurityConfig.java
config.setAllowedOrigins(List.of(
  "http://localhost:3000",
  "http://127.0.0.1:3000",
  "http://localhost:5173",
  "http://127.0.0.1:5173",
  frontendUrl  // From APP_FRONTEND_URL
));
Update APP_FRONTEND_URL to match your production frontend URL.

HTTP Security Headers

  • Content Security Policy: default-src 'self'; frame-ancestors 'none'
  • HSTS: Enabled with 1-year max age and includeSubDomains
  • Session Management: Stateless (no server-side sessions)

Public Endpoints

The following endpoints do not require authentication:
  • /actuator/health - Health check
  • /v3/api-docs/** - OpenAPI documentation (disable in production)
  • /swagger-ui/** - Swagger UI (disable in production)

Permission-Based Authorization

Protect endpoints using Spring Security’s method security:
@PreAuthorize("hasAuthority('PERM_write:venues')")
public VenueDto createVenue(CreateVenueRequest request) {
    // Only users with 'write:venues' permission can access
}
Permissions from the JWT are prefixed with PERM_ by the JwtAuthenticationConverter.

Testing Authentication

Get a Test Token

Use Auth0’s test feature or implement a login flow in your frontend:
cURL Example
curl -X POST https://padelhub.eu.auth0.com/oauth/token \
  -H 'content-type: application/json' \
  -d '{
    "client_id":"YOUR_CLIENT_ID",
    "client_secret":"YOUR_CLIENT_SECRET",
    "audience":"https://api.padelhub.com",
    "grant_type":"client_credentials"
  }'

Make Authenticated Request

Authenticated API Call
curl -X GET http://localhost:8080/api/venues \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Expected Responses

Success (200 OK):
{
  "venues": [...]
}
Unauthorized (401):
{
  "error": "unauthorized",
  "error_description": "Full authentication is required to access this resource"
}
Forbidden (403):
{
  "error": "access_denied",
  "error_description": "Insufficient permissions"
}

Troubleshooting

Token Validation Failures

Error: The iss claim is not validSolution: Verify AUTH0_ISSUER matches your Auth0 domain exactly, including the trailing slash.
Error: The aud claim is not validSolution: Ensure AUTH0_AUDIENCE matches the API identifier in Auth0 exactly.
Error: Jwt expired at...Solution: Tokens have a limited lifetime (typically 24 hours). Request a new token or implement token refresh.
Error: Access Denied (403)Solution: Check that the user has the required permissions in Auth0. Permissions must be added to the JWT token.

Debugging Tips

  1. Enable debug logging:
    logging:
      level:
        org.springframework.security: DEBUG
    
  2. Decode JWT tokens: Use jwt.io to inspect token contents
  3. Check Auth0 logs: Review authentication logs in the Auth0 dashboard
  4. Verify public keys: Ensure the backend can access https://YOUR_DOMAIN.auth0.com/.well-known/jwks.json

Next Steps

Database Configuration

Set up PostgreSQL database

User Management

Manage users via API

Frontend Development

Frontend Auth0 integration

Environment Variables

Configure Auth0 environment

Build docs developers (and LLMs) love