1
0

Add Spring Authorization Server project: OAuth2/OIDC provider, client and resource server

Three modules on Spring Boot 4.1.1 with Spring Authorization Server 7.1.1: the provider
itself, a relying party, and an API that trusts its tokens. Client registration, PKCE,
a custom consent page and token customisation, with profiles that make each failure
reproducible.

Every claim is backed by captured output in docs/output/as-*.txt, regenerated by
authorization-server/scripts/run-all.sh. Notable findings, verified against the jars:

  - OAuth2AuthorizationServerConfiguration.applyDefaultSecurity(HttpSecurity) was deleted
    in 7.0, and both configuration classes moved into spring-security-config
  - ClientSettings.requireProofKey flipped from false to true, on the authorization server
    (1.5.8 -> 7.1.1) and on the OAuth2 client (6.5.1 -> 7.1.1)
  - requireProofKey(false) does not make PKCE optional for a public client; the code
    verifier is that client's only authentication at the token endpoint
  - MediaTypeRequestMatcher(TEXT_HTML) matches Accept: */*, so the token endpoint answers
    API callers with 302 -> /login unless setIgnoredMediaTypes(ALL) is called

Also renames the repository to spring-auth-demo and cross-links the new chapter set from
the existing documentation.
This commit is contained in:
2026-08-24 08:12:36 +05:30
parent 4dc45d5e00
commit e9381dc5be
89 changed files with 5237 additions and 9 deletions

View File

@@ -0,0 +1,114 @@
#!/usr/bin/env bash
# Regenerates every file in ../docs/output that belongs to this project.
#
# ./scripts/run-all.sh
#
# Starts and stops the servers itself. Takes a few minutes. The only non-deterministic
# content is timestamps, key ids and token values, which change on every run by design.
set -u
cd "$(dirname "$0")/.."
. scripts/lib.sh
start_auth() {
kill_app AuthServerApplication 9000
local profiles="${1:-}"
local args=(-B -o -pl auth-server org.springframework.boot:spring-boot-maven-plugin:run)
[ -n "$profiles" ] && args+=("-Dspring-boot.run.profiles=$profiles")
setsid nohup mvn "${args[@]}" > /tmp/auth-server.log 2>&1 < /dev/null &
wait_for "$AS/oauth2/jwks" 90
}
start_client() {
kill_app ClientApplication 8080
local profiles="${1:-}"
local args=(-B -o -pl oidc-client org.springframework.boot:spring-boot-maven-plugin:run)
[ -n "$profiles" ] && args+=("-Dspring-boot.run.profiles=$profiles")
setsid nohup mvn "${args[@]}" > /tmp/oidc-client.log 2>&1 < /dev/null &
wait_for "http://127.0.0.1:8080/" 90
}
start_rs() {
kill_app ResourceServerApplication 8090
local profiles="${1:-}"
local args=(-B -o -pl resource-server org.springframework.boot:spring-boot-maven-plugin:run)
[ -n "$profiles" ] && args+=("-Dspring-boot.run.profiles=$profiles")
setsid nohup mvn "${args[@]}" > /tmp/rs.log 2>&1 < /dev/null &
wait_for "$RS/public" 90
}
echo "== ClientSettings / TokenSettings defaults, 1.5.8 vs 7.1.1"
./scripts/settings-defaults.sh > /dev/null
echo "== the SAS 1.x configuration against 7.1.1 (compile only)"
./scripts/compile-legacy.sh > /dev/null
echo "== default profile"
start_auth ""
start_rs ""
./scripts/discovery.sh
./scripts/client-credentials.sh as-client-credentials
./scripts/authcode-pkce.sh as-authcode-pkce demo-spa
./scripts/authcode-pkce.sh as-authcode-web demo-web
echo "== why a confidential Spring client does not send PKCE by default"
./scripts/pkce-applier.sh > /dev/null
echo "== the real Spring OAuth2 client, end to end"
start_client ""
./scripts/client-flow.sh as-client-flow "client sends PKCE"
# Restart the authorization server too, so the consent already granted above does not
# short-circuit the second run.
start_auth ""
start_client "nopkce"
./scripts/client-flow.sh as-client-flow-nopkce "confidential client, no PKCE - the Boot default"
kill_app ClientApplication 8080
echo "== noclaims: the token customiser removed"
start_auth "noclaims"
./scripts/client-credentials.sh as-client-credentials-noclaims
./scripts/authcode-pkce.sh as-authcode-noclaims demo-spa
echo "== nopkce: the public client no longer requires a verifier"
start_auth "nopkce"
# With a challenge present, the server still demands the verifier - requireProofKey only
# controls whether a challenge is MANDATORY, not whether one that was sent is honoured.
./scripts/authcode-pkce.sh as-authcode-nopkce demo-spa
# Without any challenge at all, the code alone is enough. This is the actual exposure.
NO_CHALLENGE=1 ./scripts/authcode-pkce.sh as-authcode-nochallenge demo-spa
echo "== the same request against a client that DOES require PKCE"
start_auth ""
NO_CHALLENGE=1 ./scripts/authcode-pkce.sh as-authcode-pkce-enforced demo-spa
echo "== noconsent: consent turned off"
start_auth "noconsent"
./scripts/authcode-pkce.sh as-authcode-noconsent demo-spa
echo "== entry point and the Accept header"
rm -f ../docs/output/as-entrypoint-accept.txt
start_auth "acceptall"
./scripts/entrypoint-accept.sh "acceptall profile: setIgnoredMediaTypes NOT called"
start_auth ""
./scripts/entrypoint-accept.sh "default profile: setIgnoredMediaTypes(ALL) called"
echo "== opaque: reference tokens for the service client"
start_auth "opaque"
./scripts/client-credentials.sh as-client-credentials-opaque
echo "== audience validation off on the resource server"
start_auth ""
start_rs "noaud"
./scripts/audience.sh
echo "== the contract tests"
mvn -B -o -pl auth-server test 2>&1 | grep -E "Tests run:|^\[INFO\] Running" \
> ../docs/output/as-test-run.txt || true
kill_app AuthServerApplication 9000
kill_app ResourceServerApplication 8090
kill_app ClientApplication 8080
echo "== resource server startup with no provider"
./scripts/rs-startup-failure.sh > /dev/null
echo
echo "docs/output:"
ls -1 ../docs/output/as-*.txt