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.
115 lines
4.2 KiB
Bash
Executable File
115 lines
4.2 KiB
Bash
Executable File
#!/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
|