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.
241 lines
8.1 KiB
Plaintext
241 lines
8.1 KiB
Plaintext
|
|
------------------------------------------------------------------
|
|
== OpenID Connect discovery: GET /.well-known/openid-configuration
|
|
------------------------------------------------------------------
|
|
$ curl -s http://localhost:9000/.well-known/openid-configuration
|
|
{
|
|
"issuer": "http://localhost:9000",
|
|
"authorization_endpoint": "http://localhost:9000/oauth2/authorize",
|
|
"token_endpoint": "http://localhost:9000/oauth2/token",
|
|
"token_endpoint_auth_methods_supported": [
|
|
"client_secret_basic",
|
|
"client_secret_post",
|
|
"client_secret_jwt",
|
|
"private_key_jwt",
|
|
"tls_client_auth",
|
|
"self_signed_tls_client_auth"
|
|
],
|
|
"jwks_uri": "http://localhost:9000/oauth2/jwks",
|
|
"userinfo_endpoint": "http://localhost:9000/userinfo",
|
|
"end_session_endpoint": "http://localhost:9000/connect/logout",
|
|
"response_types_supported": [
|
|
"code"
|
|
],
|
|
"grant_types_supported": [
|
|
"authorization_code",
|
|
"client_credentials",
|
|
"refresh_token",
|
|
"urn:ietf:params:oauth:grant-type:token-exchange"
|
|
],
|
|
"revocation_endpoint": "http://localhost:9000/oauth2/revoke",
|
|
"revocation_endpoint_auth_methods_supported": [
|
|
"client_secret_basic",
|
|
"client_secret_post",
|
|
"client_secret_jwt",
|
|
"private_key_jwt",
|
|
"tls_client_auth",
|
|
"self_signed_tls_client_auth"
|
|
],
|
|
"introspection_endpoint": "http://localhost:9000/oauth2/introspect",
|
|
"introspection_endpoint_auth_methods_supported": [
|
|
"client_secret_basic",
|
|
"client_secret_post",
|
|
"client_secret_jwt",
|
|
"private_key_jwt",
|
|
"tls_client_auth",
|
|
"self_signed_tls_client_auth"
|
|
],
|
|
"code_challenge_methods_supported": [
|
|
"S256"
|
|
],
|
|
"tls_client_certificate_bound_access_tokens": true,
|
|
"dpop_signing_alg_values_supported": [
|
|
"RS256",
|
|
"RS384",
|
|
"RS512",
|
|
"PS256",
|
|
"PS384",
|
|
"PS512",
|
|
"ES256",
|
|
"ES384",
|
|
"ES512"
|
|
],
|
|
"subject_types_supported": [
|
|
"public"
|
|
],
|
|
"id_token_signing_alg_values_supported": [
|
|
"RS256"
|
|
],
|
|
"scopes_supported": [
|
|
"openid"
|
|
]
|
|
}
|
|
|
|
------------------------------------------------------------------
|
|
== OAuth2 metadata: GET /.well-known/oauth-authorization-server
|
|
------------------------------------------------------------------
|
|
Present even with .oidc(...) switched off. The OIDC document above is the one
|
|
that additionally advertises userinfo_endpoint and id_token signing algorithms.
|
|
$ curl -s http://localhost:9000/.well-known/oauth-authorization-server
|
|
{
|
|
"issuer": "http://localhost:9000",
|
|
"authorization_endpoint": "http://localhost:9000/oauth2/authorize",
|
|
"token_endpoint": "http://localhost:9000/oauth2/token",
|
|
"token_endpoint_auth_methods_supported": [
|
|
"client_secret_basic",
|
|
"client_secret_post",
|
|
"client_secret_jwt",
|
|
"private_key_jwt",
|
|
"tls_client_auth",
|
|
"self_signed_tls_client_auth"
|
|
],
|
|
"jwks_uri": "http://localhost:9000/oauth2/jwks",
|
|
"response_types_supported": [
|
|
"code"
|
|
],
|
|
"grant_types_supported": [
|
|
"authorization_code",
|
|
"client_credentials",
|
|
"refresh_token",
|
|
"urn:ietf:params:oauth:grant-type:token-exchange"
|
|
],
|
|
"revocation_endpoint": "http://localhost:9000/oauth2/revoke",
|
|
"revocation_endpoint_auth_methods_supported": [
|
|
"client_secret_basic",
|
|
"client_secret_post",
|
|
"client_secret_jwt",
|
|
"private_key_jwt",
|
|
"tls_client_auth",
|
|
"self_signed_tls_client_auth"
|
|
],
|
|
"introspection_endpoint": "http://localhost:9000/oauth2/introspect",
|
|
"introspection_endpoint_auth_methods_supported": [
|
|
"client_secret_basic",
|
|
"client_secret_post",
|
|
"client_secret_jwt",
|
|
"private_key_jwt",
|
|
"tls_client_auth",
|
|
"self_signed_tls_client_auth"
|
|
],
|
|
"code_challenge_methods_supported": [
|
|
"S256"
|
|
],
|
|
"tls_client_certificate_bound_access_tokens": true,
|
|
"dpop_signing_alg_values_supported": [
|
|
"RS256",
|
|
"RS384",
|
|
"RS512",
|
|
"PS256",
|
|
"PS384",
|
|
"PS512",
|
|
"ES256",
|
|
"ES384",
|
|
"ES512"
|
|
]
|
|
}
|
|
|
|
------------------------------------------------------------------
|
|
== JWK Set: GET /oauth2/jwks
|
|
------------------------------------------------------------------
|
|
Public keys only. No 'd' member - if you ever see one here, stop the server.
|
|
{
|
|
"keys": [
|
|
{
|
|
"kty": "RSA",
|
|
"e": "AQAB",
|
|
"kid": "262bd550-3657-46c4-bafc-cce4c6f4e0cb",
|
|
"n": "pFCIstpVnGQm7Mp8bskE_-_Rz-oI6mPaiyQLiWMBuVip4fkKYwapZVbsZf9fmy1w1KXWIdtXOhe-fqa3-KqYzsrje-o2u6_D27rqR1Z0I9ezbDfw2A4Gsj5AlmnXzWMLnNMzSueSf8luRk04MHO4bGzXLqQ1gOltnqMkMAQzhCqWFZmKxNJeaB4FlXOtxqzcso0eeKsPzRjZvTamgU5TvGUZmQ4LTKTkoYzB3kjvCspVpZAbdVR01RlmzfTJB0tVIc0ioMk1YZHUx27TPN1W8Nw1AaAYmV9URaf2fgz2Ja3y_Lj8hmXuQAcPOGBmoVWX0QkW4DTSAPW0xiPHqpjw9Q"
|
|
}
|
|
]
|
|
}
|
|
|
|
------------------------------------------------------------------
|
|
== Resolved endpoint settings, read back from AuthorizationServerSettings
|
|
------------------------------------------------------------------
|
|
{
|
|
"settings.authorization-server.client-registration-endpoint": "/oauth2/register",
|
|
"settings.authorization-server.authorization-endpoint": "/oauth2/authorize",
|
|
"settings.authorization-server.token-endpoint": "/oauth2/token",
|
|
"settings.authorization-server.device-verification-endpoint": "/oauth2/device_verification",
|
|
"settings.authorization-server.oidc-user-info-endpoint": "/userinfo",
|
|
"settings.authorization-server.pushed-authorization-request-endpoint": "/oauth2/par",
|
|
"settings.authorization-server.oidc-client-registration-endpoint": "/connect/register",
|
|
"settings.authorization-server.oidc-logout-endpoint": "/connect/logout",
|
|
"settings.authorization-server.issuer": "http://localhost:9000",
|
|
"settings.authorization-server.multiple-issuers-allowed": false,
|
|
"settings.authorization-server.device-authorization-endpoint": "/oauth2/device_authorization",
|
|
"settings.authorization-server.jwk-set-endpoint": "/oauth2/jwks",
|
|
"settings.authorization-server.token-revocation-endpoint": "/oauth2/revoke",
|
|
"settings.authorization-server.token-introspection-endpoint": "/oauth2/introspect"
|
|
}
|
|
|
|
------------------------------------------------------------------
|
|
== Registered clients, as the server actually holds them
|
|
------------------------------------------------------------------
|
|
[
|
|
{
|
|
"clientId": "demo-web",
|
|
"authenticationMethods": [
|
|
"client_secret_basic"
|
|
],
|
|
"grantTypes": [
|
|
"refresh_token",
|
|
"authorization_code"
|
|
],
|
|
"redirectUris": [
|
|
"http://127.0.0.1:8080/login/oauth2/code/demo-web"
|
|
],
|
|
"scopes": [
|
|
"orders.write",
|
|
"openid",
|
|
"profile",
|
|
"orders.read"
|
|
],
|
|
"requireProofKey": true,
|
|
"requireAuthorizationConsent": true,
|
|
"accessTokenFormat": "self-contained",
|
|
"accessTokenTtlSeconds": 300,
|
|
"reuseRefreshTokens": false
|
|
},
|
|
{
|
|
"clientId": "demo-spa",
|
|
"authenticationMethods": [
|
|
"none"
|
|
],
|
|
"grantTypes": [
|
|
"refresh_token",
|
|
"authorization_code"
|
|
],
|
|
"redirectUris": [
|
|
"http://127.0.0.1:8080/authorized"
|
|
],
|
|
"scopes": [
|
|
"openid",
|
|
"orders.read"
|
|
],
|
|
"requireProofKey": true,
|
|
"requireAuthorizationConsent": true,
|
|
"accessTokenFormat": "self-contained",
|
|
"accessTokenTtlSeconds": 300,
|
|
"reuseRefreshTokens": true
|
|
},
|
|
{
|
|
"clientId": "demo-service",
|
|
"authenticationMethods": [
|
|
"client_secret_basic"
|
|
],
|
|
"grantTypes": [
|
|
"client_credentials"
|
|
],
|
|
"redirectUris": [],
|
|
"scopes": [
|
|
"orders.read"
|
|
],
|
|
"requireProofKey": true,
|
|
"requireAuthorizationConsent": false,
|
|
"accessTokenFormat": "self-contained",
|
|
"accessTokenTtlSeconds": 600,
|
|
"reuseRefreshTokens": true
|
|
}
|
|
]
|