LAB-015: JWK Rotation and Multiple Issuers¶
Status: Verified
Theory: JWK Rotation and Multiple Issuers
Objective¶
Prove that the resource server accepts tokens signed by either the current or the previous key, rejects unknown kids, and validates issuer and audience independently of the JWK source.
Implementation map¶
| Artifact | Purpose |
|---|---|
JwkLabKeyProvider | Generates two RSA keys with current and previous identifiers |
ResourceServerSecurityConfig | NimbusJwtDecoder built with JWSVerificationKeySelector over a JWKSource containing both keys |
ResourceServerJwtLabTest | Eleven JWT scenarios including rotation, unknown kid, and untrusted key |
Exercises¶
- Issue a token signed with the current key and access
/rs/profile. - Issue a token signed with the previous key and confirm it is still accepted.
- Issue a token with an unknown
kidand confirm 401. - Sign a token with a fresh attacker key using the same
kidand confirm 401. - Change the issuer and confirm 401.
- Change the audience and confirm 401.
- Explain why
kidalone does not prove a token is valid. - Document how a real
issuer-uriandjwkSetUriwould replace the in-process JWK source.
Verification¶
Eleven assertions must pass, including the new rotation and unknown-kid cases.
Attack checks¶
- Confirm the
kidis only a key-selection hint, not an authority. - Confirm a matching
kidfrom an untrusted key does not bypass verification. - Confirm
alg=noneor unexpectedalgvalues are rejected. - Confirm the JWK source is from server configuration, not the token.
Production extension¶
Use spring.security.oauth2.resourceserver.jwt.issuer-uri with JWK discovery, implement a bounded JWK cache, and add a rotation runbook with an overlap window and emergency-replacement procedure.
Review¶
Complete the JWK and issuer questions in the SSO and Federation Quiz.
Next: LAB-016 API Gateway