fix(auth): omit scope from OAuth2 refresh requests and guard None scopes#5352
Open
voidborne-d wants to merge 1 commit intogoogle:mainfrom
Open
fix(auth): omit scope from OAuth2 refresh requests and guard None scopes#5352voidborne-d wants to merge 1 commit intogoogle:mainfrom
voidborne-d wants to merge 1 commit intogoogle:mainfrom
Conversation
Per RFC 6749 §6, the scope parameter is OPTIONAL in refresh requests — when omitted, providers treat it as equal to the originally-granted scope. Some providers (e.g. Salesforce) actively reject refresh requests that include a scope parameter, causing silent token refresh failures. Changes: 1. oauth2_credential_refresher.py: Pass scope="" to client.refresh_token() to prevent authlib from injecting the session's scope into the refresh request body. Empty string is falsy, so authlib's prepare_token_request omits it entirely from the POST body. 2. oauth2_credential_util.py: Guard against None scopes in both authorizationCode and clientCredentials flows. When scopes are not specified (valid per OpenAPI spec), default to an empty list instead of crashing with AttributeError: 'NoneType' has no attribute 'keys'. Fixes google#5328
df4e848 to
eb65de1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #5328 — OAuth2 token refresh fails for providers that reject the
scopeparameter (e.g. Salesforce).Problem
Two related issues in the OAuth2 credential flow:
Scope in refresh requests:
OAuth2CredentialRefresher.refresh()creates anOAuth2Sessionwith scopes, and authlib automatically includesscopein the refresh token request body. Per RFC 6749 §6,scopeis OPTIONAL in refresh requests — when omitted, providers treat it as equal to the originally-granted scope. Some providers (e.g. Salesforce) actively reject refresh requests that includescope.None scopes crash:
create_oauth2_session()calls.scopes.keys()without checking forNone. WhenOAuthFlowClientCredentialsorOAuthFlowAuthorizationCodeis created without specifying scopes (valid per OpenAPI spec), this crashes withAttributeError: NoneType has no attribute keys.Fix
oauth2_credential_refresher.py: Passscope=""toclient.refresh_token(). This prevents authlib from injecting the session's scope into the refresh request, since"scope" in kwargsisTrue. The empty string is falsy, so authlib'sprepare_token_requestomits it from the POST body entirely.oauth2_credential_util.py: GuardscopesagainstNonein bothauthorizationCodeandclientCredentialsflow branches, defaulting to[].Tests
test_refresh_omits_scope_from_request— verifiesrefresh_token()is called withscope=""to suppress scope injection.test_create_oauth2_session_client_credentials_none_scopes— verifies no crash when clientCredentials flow has no scopes.test_create_oauth2_session_auth_code_none_scopes— verifies no crash when authorizationCode flow has no scopes.Related
generate_auth_uri), though that issue manifests in a different code path.