Add AuthSettings.validate_token_resource to check a bearer token's resource (#3447)

This commit is contained in:
Max 2026-09-05 03:35:55 +01:00 • committed by GitHub
commit 0c9136841f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 293 additions and 41 deletions

View file

@ -169,4 +169,5 @@ def auth_settings(
required_scopes=scopes,
client_registration_options=ClientRegistrationOptions(enabled=True, valid_scopes=scopes, default_scopes=scopes),
identity_assertion_enabled=identity_assertion_enabled,
validate_token_resource=True,
)

View file

@ -28,6 +28,7 @@ class StaticTokenVerifier(TokenVerifier):
client_id="demo-client",
scopes=[REQUIRED_SCOPE],
expires_at=int(time.time()) + 3600,
resource=RESOURCE_URL,
subject="demo-user",
)
@ -40,6 +41,7 @@ def build_app() -> Starlette:
issuer_url=AnyHttpUrl(ISSUER),
resource_server_url=AnyHttpUrl(RESOURCE_URL),
required_scopes=[REQUIRED_SCOPE],
validate_token_resource=True,
),
)

View file

@ -46,6 +46,7 @@ def build_app() -> Starlette:
issuer_url=AnyHttpUrl(ISSUER),
resource_server_url=AnyHttpUrl(RESOURCE_URL),
required_scopes=[REQUIRED_SCOPE],
validate_token_resource=True,
),
token_verifier=StaticTokenVerifier(),
transport_security=NO_DNS_REBIND,

View file

@ -66,7 +66,14 @@ def build_app() -> Starlette:
if creds != f"{DEMO_CLIENT_ID}:{DEMO_CLIENT_SECRET}":
return JSONResponse({"error": "invalid_client"}, status_code=401)
access = f"access_{secrets.token_hex(16)}"
issued[access] = AccessToken(token=access, client_id=DEMO_CLIENT_ID, scopes=[DEMO_SCOPE], expires_at=None)
resource = form.get("resource") # RFC 8707: bind the token to the resource the client asked for
issued[access] = AccessToken(
token=access,
client_id=DEMO_CLIENT_ID,
scopes=[DEMO_SCOPE],
expires_at=None,
resource=resource if isinstance(resource, str) else None,
)
body = OAuthToken(access_token=access, token_type="Bearer", expires_in=3600, scope=DEMO_SCOPE)
return JSONResponse(body.model_dump(exclude_none=True), headers={"cache-control": "no-store"})

View file

@ -63,7 +63,14 @@ def build_app() -> Starlette:
if creds != f"{DEMO_CLIENT_ID}:{DEMO_CLIENT_SECRET}":
return JSONResponse({"error": "invalid_client"}, status_code=401)
access = f"access_{secrets.token_hex(16)}"
issued[access] = AccessToken(token=access, client_id=DEMO_CLIENT_ID, scopes=[DEMO_SCOPE], expires_at=None)
resource = form.get("resource") # RFC 8707: bind the token to the resource the client asked for
issued[access] = AccessToken(
token=access,
client_id=DEMO_CLIENT_ID,
scopes=[DEMO_SCOPE],
expires_at=None,
resource=resource if isinstance(resource, str) else None,
)
body = OAuthToken(access_token=access, token_type="Bearer", expires_in=3600, scope=DEMO_SCOPE)
return JSONResponse(body.model_dump(exclude_none=True), headers={"cache-control": "no-store"})