feat: forward the OAuth2 nonce to the authorization request

Some OIDC providers require a nonce parameter on the authorization
request, but generate_auth_uri dropped the OAuth2Auth.nonce field even
when a caller set it. Pass nonce through to create_authorization_url
when present, leaving non-OIDC flows that omit it unchanged.

Close #2067

Co-authored-by: George Weale <gweale@google.com>
PiperOrigin-RevId: 951116662
This commit is contained in:
George Weale
2026-07-20 16:29:04 -07:00
committed by Copybara-Service
parent 8f98bcd513
commit 79cc1f2970
2 changed files with 55 additions and 0 deletions
+2
View File
@@ -215,6 +215,8 @@ class AuthHandler:
}
if auth_credential.oauth2.audience:
params["audience"] = auth_credential.oauth2.audience
if auth_credential.oauth2.nonce:
params["nonce"] = auth_credential.oauth2.nonce
# If using PKCE with S256, ensure a code_verifier exists.
# If not provided in the credential, generate a cryptographically secure
+53
View File
@@ -355,6 +355,59 @@ class TestGenerateAuthUri:
assert "code_verifier" in kwargs
assert kwargs["code_verifier"] == result.oauth2.code_verifier
@patch("google.adk.auth.auth_handler.OAuth2Session")
def test_generate_auth_uri_with_nonce(
self, mock_oauth2_session, oauth2_auth_scheme, oauth2_credentials
):
"""Test that a nonce is forwarded to the authorization request."""
oauth2_credentials.oauth2.nonce = "test_nonce"
exchanged = oauth2_credentials.model_copy(deep=True)
config = AuthConfig(
auth_scheme=oauth2_auth_scheme,
raw_auth_credential=oauth2_credentials,
exchanged_auth_credential=exchanged,
)
mock_client = Mock()
mock_oauth2_session.return_value = mock_client
mock_client.create_authorization_url.return_value = (
"https://example.com/oauth2/authorize?nonce=test_nonce",
"mock_state",
)
handler = AuthHandler(config)
handler.generate_auth_uri()
_, kwargs = mock_client.create_authorization_url.call_args
assert kwargs["nonce"] == "test_nonce"
@patch("google.adk.auth.auth_handler.OAuth2Session")
def test_generate_auth_uri_without_nonce(
self, mock_oauth2_session, oauth2_auth_scheme, oauth2_credentials
):
"""Test that no nonce is sent when the credential has none."""
exchanged = oauth2_credentials.model_copy(deep=True)
config = AuthConfig(
auth_scheme=oauth2_auth_scheme,
raw_auth_credential=oauth2_credentials,
exchanged_auth_credential=exchanged,
)
mock_client = Mock()
mock_oauth2_session.return_value = mock_client
mock_client.create_authorization_url.return_value = (
"https://example.com/oauth2/authorize",
"mock_state",
)
handler = AuthHandler(config)
handler.generate_auth_uri()
_, kwargs = mock_client.create_authorization_url.call_args
assert "nonce" not in kwargs
def test_generate_auth_uri_unsupported_pkce_method(
self, oauth2_auth_scheme, oauth2_credentials
):