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