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,64 @@
# Running your own OAuth2 / OIDC provider
Companion documentation for
[Spring Authorization Server: Running Your Own OAuth2 / OIDC Provider](https://ankurm.com/spring-authorization-server-oauth2-oidc-provider/)
on ankurm.com, and for the code in [`authorization-server/`](../../authorization-server).
Where the other two projects in this repository *consume* tokens, this one **mints** them.
[`docs/01`–`18`](../) cover a hand-written JWT filter and a resource server in front of
somebody else's issuer; the chapters here cover the issuer itself.
| | |
|---|---|
| JDK | Temurin **25.0.4.1+1** (current LTS) |
| Spring Boot | **4.1.1** |
| Spring Framework | **7.0.9** |
| Spring Security | **7.1.1** |
| Spring Authorization Server | **7.1.1** — the same artifact, now versioned with Spring Security |
| Maven | 3.9.11 |
Everything in [`docs/output/as-*.txt`](../output) is real program output, regenerated by
[`authorization-server/scripts/run-all.sh`](../../authorization-server/scripts/run-all.sh).
## Chapters
| # | chapter | what it settles |
|---|---|---|
| 01 | [Versions, artifacts and the 7.0 move](01-versions.md) | why there is no SAS version to pin any more, and which starter to use |
| 02 | [The minimum working provider](02-minimum-provider.md) | two filter chains, and the API that replaced `applyDefaultSecurity` |
| 03 | [Clients, PKCE and the defaults that moved](03-clients-and-pkce.md) | `requireProofKey` flipped to `true` on both sides |
| 04 | [The consent page](04-consent-page.md) | the form contract, and the redirect loop you get for breaking it |
| 05 | [Token customisation](05-token-customisation.md) | the bean the JWT generator looks for, and the one it ignores |
| 06 | [The resource server side](06-resource-server.md) | what `issuer-uri` does and does not validate |
| 07 | [Diagnostics](07-diagnostics.md) | reading the effective configuration back out of the running server |
| 08 | [The relying party](08-client.md) | driving a real browser flow, and the client-side PKCE default |
| 09 | [The entry point and the Accept header](09-entry-point.md) | why the token endpoint 302s to a login page |
| 10 | [Should you run one at all](10-should-you.md) | the honest answer, and what you are signing up for |
## Captured output
| file | produced by |
|---|---|
| [`as-settings-defaults.txt`](../output/as-settings-defaults.txt) | `scripts/settings-defaults.sh` |
| [`as-legacy-compile-failure.txt`](../output/as-legacy-compile-failure.txt) | `scripts/compile-legacy.sh` |
| [`as-missing-consent-service.txt`](../output/as-missing-consent-service.txt) | a real startup failure, kept |
| [`as-discovery.txt`](../output/as-discovery.txt) | `scripts/discovery.sh` |
| [`as-client-credentials.txt`](../output/as-client-credentials.txt) | `scripts/client-credentials.sh` |
| [`as-client-credentials-noclaims.txt`](../output/as-client-credentials-noclaims.txt) | same, `noclaims` profile |
| [`as-client-credentials-opaque.txt`](../output/as-client-credentials-opaque.txt) | same, `opaque` profile |
| [`as-authcode-pkce.txt`](../output/as-authcode-pkce.txt) | `scripts/authcode-pkce.sh`, public client |
| [`as-authcode-web.txt`](../output/as-authcode-web.txt) | same, confidential client |
| [`as-authcode-noclaims.txt`](../output/as-authcode-noclaims.txt) | same, `noclaims` profile |
| [`as-authcode-noconsent.txt`](../output/as-authcode-noconsent.txt) | same, `noconsent` profile |
| [`as-authcode-nopkce.txt`](../output/as-authcode-nopkce.txt) | same, `nopkce` profile, challenge still sent |
| [`as-authcode-nochallenge.txt`](../output/as-authcode-nochallenge.txt) | same, `nopkce` profile, no challenge at all |
| [`as-authcode-pkce-enforced.txt`](../output/as-authcode-pkce-enforced.txt) | same, defaults, no challenge — rejected |
| [`as-pkce-applier.txt`](../output/as-pkce-applier.txt) | `scripts/pkce-applier.sh` |
| [`as-client-flow.txt`](../output/as-client-flow.txt) | `scripts/client-flow.sh` |
| [`as-client-flow-nopkce.txt`](../output/as-client-flow-nopkce.txt) | same, pre-7.0 client |
| [`as-entrypoint-accept.txt`](../output/as-entrypoint-accept.txt) | `scripts/entrypoint-accept.sh` |
| [`as-audience.txt`](../output/as-audience.txt) | `scripts/audience.sh` |
| [`as-rs-startup-failure.txt`](../output/as-rs-startup-failure.txt) | `scripts/rs-startup-failure.sh` |
| [`as-test-run.txt`](../output/as-test-run.txt) | `mvn -pl auth-server test` |
Next: [01 — Versions, artifacts and the 7.0 move](01-versions.md)