Sign inSign up

suayb/spring-authorization-server-samples

By suayb

Updated 24 days ago

Image
0

604

suayb/spring-authorization-server-samples repository overview

Spring Authorization Server Samples (Spring Boot 4 + Native)

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.

Features

  • 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

How to use this image

1. Start a PostgreSQL server
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
2. Start the application (prod mode with PostgreSQL)
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
Browser consoles

The image includes two static OIDC clients. Open either URL in a browser; it redirects to the localized Spring Security login screen when necessary.

ConsoleURLSeeded loginRequired scope
Administrationhttp://localhost:9090/adminadmin/adminadmin-api and the required administrative authority
Accounthttp://localhost:9090/accountadmin/admin or user/useraccount-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.

3. Check health
curl http://localhost:9090/actuator/health/readiness

Expected response contains:

{"status":"UP"}
4. Fetch discovery metadata
curl http://localhost:9090/.well-known/openid-configuration
5. Request a token

Seeded OAuth2 client:

Client IDClient Secret
demo-clientdemo-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

Environment variables

NameDefaultDescription
SPRING_PROFILES_ACTIVEdefaultActive Spring profile
SERVER_PORT9090HTTP server port
SPRING_DATASOURCE_URLjdbc:h2:mem:authserversamples;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSEJDBC URL
SPRING_DATASOURCE_USERNAMEsaDatabase username
SPRING_DATASOURCE_PASSWORD(empty)Database password
SPRING_LIQUIBASE_ENABLEDtrueEnable or disable Liquibase migrations
APP_AUTHORIZATION_SERVER_ISSUERhttps://spring-authorization-server-samples.localOAuth2/OIDC issuer

RSA signing keys

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.

HTTP endpoints

Authorization Server:

  • GET /.well-known/openid-configuration
  • GET /.well-known/oauth-authorization-server
  • GET /oauth2/jwks
  • GET /oauth2/authorize
  • POST /oauth2/token
  • POST /oauth2/revoke
  • POST /oauth2/introspect

OIDC:

  • GET /connect/logout

Browser UIs:

  • GET /en/admin/, GET /tr/admin/
  • GET /en/account/, GET /tr/account/

Health:

  • GET /actuator/health
  • GET /actuator/health/liveness
  • GET /actuator/health/readiness

Health checks

The 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

Notes

  • This is an HTTP OAuth2/OIDC authorization server sample; it is not a gRPC service.
  • The default database is in-memory H2, so data is reset when the container stops.
  • Liquibase migrations and CSV seed data run on startup by default.
  • Hibernate second-level cache is enabled in the application configuration.
  • Registered OAuth2 clients are seeded from Liquibase CSV, not created dynamically at startup.
  • RSA signing keys should remain stable across restarts; changing the key invalidates signature verification for tokens signed with the previous key unless the previous public key remains available.
  • Never commit production private keys to source control or bake them into the container image.
  • OAuth2 error responses honor 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.
  • The console clients are registered for 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.

Tag summary

Content type

Image

Digest

sha256:c1f9a1be0

Size

41.3 MB

Last updated

24 days ago

docker pull suayb/spring-authorization-server-samples:latest-native