-------------------------------------------------------------------------- resource server profiles: stub,roles -------------------------------------------------------------------------- Baseline: 25 requests with a VALID token, whose kid is in the cached JWK Set. requests to the resource server : 25 fetches of /jwks.json : 0 Now 25 requests carrying a token whose kid has never existed. Each one is refused - but look at what it costs the issuer first. requests to the resource server : 25 fetches of /jwks.json : 25 Every rejected request became a request to the authorization server. An attacker who can reach an unauthenticated endpoint of your resource server can point that ratio at your identity provider, from one connection, using tokens that are never valid. And it does not need an authenticated endpoint. /api/public/ping is permitAll(). requests to /api/public/ping : 25 fetches of /jwks.json : 25 A permitAll() endpoint still evaluates a bearer token if one is present, because BearerTokenAuthenticationFilter runs before any authorization rule. Presenting a broken token to a public endpoint gets a 401 from the public endpoint - and a JWKS fetch on the way. $ GET /api/public/ping with an unknown kid HTTP 401 WWW-Authenticate: Bearer error="invalid_token", error_description="An error occurred while attempting to decode the Jwt: Signed JWT rejected: Another algorithm expected, or no matching key(s) found", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1", resource_metadata="http://localhost:8081/.well-known/oauth-protected-resource" The status returned to the caller is unremarkable: $ GET /api/me with an unknown kid HTTP 401 WWW-Authenticate: Bearer error="invalid_token", error_description="An error occurred while attempting to decode the Jwt: Signed JWT rejected: Another algorithm expected, or no matching key(s) found", error_uri="https://tools.ietf.org/html/rfc6750#section-3.1", resource_metadata="http://localhost:8081/.well-known/oauth-protected-resource"