OAuth2 Authorization Server and OpenID Connect sample application built with Spring Boot 4, Spring Security Authorization Server, Spring Data JPA, Liquibase, H2/PostgreSQL, Spring Security, and Hibernate second-level cache backed by Caffeine/JCache. This image runs the app as a GraalVM native executable for fast startup and low memory usage.
This image exposes an HTTP-based authorization server on port 9090. It serves OpenID Provider metadata, JWK Set, OAuth2 token and authorization endpoints, and actuator health probes.
Custom Next.js/React-Bootstrap login, Administration Console, and Account Console UIs bundled into the Spring Boot image
OAuth2 Authorization Server with OIDC enabled
Authorization Code, Refresh Token, and Client Credentials grants
RSA-signed JWT access and ID tokens
Database-backed RSA JWK signing keys with active/passive key support
JPA-backed registered client storage
JPA-backed authorization and consent storage
H2 in-memory database for local use
PostgreSQL support for production-style runs
XML-based Liquibase schema migrations
CSV seed data for users, authorities, and OAuth2 clients
JPA auditing with Instant created_at and updated_at
Hibernate second-level cache via JCache + Caffeine
Actuator liveness and readiness endpoints
GraalVM native executable
docker run --name postgresql --rm -d \
-e POSTGRES_USER=appuser \
-e POSTGRES_PASSWORD=appuser \
-e POSTGRES_DB=authserversamples \
-p 127.0.0.1:5432:5432 \
postgres:18-alpine
docker run --rm -p 9090:9090 \
-e SPRING_PROFILES_ACTIVE=prod \
-e SPRING_DATASOURCE_URL=jdbc:postgresql://host.docker.internal:5432/authserversamples \
-e SPRING_DATASOURCE_USERNAME=appuser \
-e SPRING_DATASOURCE_PASSWORD=appuser \
-e APP_AUTHORIZATION_SERVER_ISSUER=http://localhost:9090 \
suayb/spring-authorization-server-samples:latest-native
Or with H2 in-memory:
docker run --rm -p 9090:9090 \
suayb/spring-authorization-server-samples:latest-native
The server is available at:
localhost:9090
The image includes two static OIDC clients. Open either URL in a browser; it redirects to the localized Spring Security login screen when necessary.
| Console | URL | Seeded login | Required scope |
|---|---|---|---|
| Administration | http://localhost:9090/admin | admin/admin | admin-api and the required administrative authority |
| Account | http://localhost:9090/account | admin/admin or user/user | account-api |
Both consoles are public OAuth2 clients (admin-console and account-console) using Authorization Code + PKCE, refresh-token rotation, and OIDC logout. They share the authorization server's browser SSO session. Set APP_AUTHORIZATION_SERVER_ISSUER to the exact public browser address of the container and use redirect URIs registered for that address; the supplied Docker command uses http://localhost:9090, which is included in the seed data.
curl http://localhost:9090/actuator/health/readiness
Expected response contains:
{"status":"UP"}
curl http://localhost:9090/.well-known/openid-configuration
Seeded OAuth2 client:
| Client ID | Client Secret |
|---|---|
demo-client | demo-secret |
Request a client credentials token:
curl -u demo-client:demo-secret \
-H 'Accept-Language: en' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d grant_type=client_credentials \
-d scope=openid \
http://localhost:9090/oauth2/token
Fetch the JWK Set:
curl http://localhost:9090/oauth2/jwks
Capture the access token:
TOKEN=$(curl -s -u demo-client:demo-secret \
-H 'Accept-Language: en' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d grant_type=client_credentials \
-d scope=openid \
http://localhost:9090/oauth2/token | jq -r '.access_token')
Introspect the access token:
curl -u demo-client:demo-secret \
-H 'Accept-Language: en' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d token="${TOKEN}" \
http://localhost:9090/oauth2/introspect
Revoke the access token:
curl -u demo-client:demo-secret \
-H 'Accept-Language: en' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d token="${TOKEN}" \
-d token_type_hint=access_token \
http://localhost:9090/oauth2/revoke
| Name | Default | Description |
|---|---|---|
SPRING_PROFILES_ACTIVE | default | Active Spring profile |
SERVER_PORT | 9090 | HTTP server port |
SPRING_DATASOURCE_URL | jdbc:h2:mem:authserversamples;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE | JDBC URL |
SPRING_DATASOURCE_USERNAME | sa | Database username |
SPRING_DATASOURCE_PASSWORD | (empty) | Database password |
SPRING_LIQUIBASE_ENABLED | true | Enable or disable Liquibase migrations |
APP_AUTHORIZATION_SERVER_ISSUER | https://spring-authorization-server-samples.local | OAuth2/OIDC issuer |
RSA signing keys are stored in the oauth2_key table. The initial sample key is seeded by Liquibase from db/data/oauth2-keys.csv.
Exactly one key must be marked active=true. The active key is used for signing, while inactive keys are exposed as public-only JWKs for verification of tokens issued before key rotation. All rows remain in the published JWK Set until removed from the table.
Authorization Server:
GET /.well-known/openid-configurationGET /.well-known/oauth-authorization-serverGET /oauth2/jwksGET /oauth2/authorizePOST /oauth2/tokenPOST /oauth2/revokePOST /oauth2/introspectOIDC:
GET /connect/logoutBrowser UIs:
GET /en/admin/, GET /tr/admin/GET /en/account/, GET /tr/account/Health:
GET /actuator/healthGET /actuator/health/livenessGET /actuator/health/readinessThe image exposes standard HTTP actuator probes.
Kubernetes example:
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 9090
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 9090
initialDelaySeconds: 10
periodSeconds: 10
Accept-Language; use headers such as Accept-Language: en on token-oriented requests when you want localized error messages.authorization_code flow requires a browser login and redirect handling, so it is not shown as a curl-only example here.localhost:9090 and https://spring-authorization-server-samples.local; register additional callback and post-logout redirect URIs before exposing the image through another public address.Content type
Image
Digest
sha256:c1f9a1be0…
Size
41.3 MB
Last updated
24 days ago
docker pull suayb/spring-authorization-server-samples:latest-native