ITADN

Add smart signing extension method to AuthClient

#159Opendemolaf 创建于 2026-02-06
D
demolafcommented
# Add smart signing extension method to AuthClient ## Description ### Problem Once Issues #154-158 are implemented, `googleapis_auth` will have all the primitives needed for signing (local signing, IAM signing, impersonation, credential association, universe domain). However, users would need to manually write logic to choose between these signing methods based on the authentication scenario. This creates a poor developer experience compared to other Google auth libraries (e.g., Node.js `google-auth-library`) which provide a single `sign()` method that automatically chooses the right signing strategy. ### Proposed Solution Add a `sign()` extension method on `AuthClient` that intelligently chooses the signing method: ```dart extension AuthClientSigningExtension on AuthClient { /// Signs data using the appropriate method based on the auth client type. /// /// Signing behavior: /// - [ImpersonatedAuthClient]: Uses IAM signBlob with target principal /// - Auth clients with service account credentials: Signs locally with RSA-SHA256 /// - Other auth clients (ADC on GCE/Cloud Run): Uses IAM signBlob with default service account /// /// [data] is the bytes to be signed. /// [endpoint] is an optional custom IAM Credentials API endpoint for universe domain support. /// /// Returns the signature as a list of bytes. Future<List<int>> sign(List<int> data, {String? endpoint}) async { // 1. Check if impersonated client if (this is ImpersonatedAuthClient) { final impersonated = this as ImpersonatedAuthClient; return impersonated.sign(data); } // 2. Check for local signing capability (requires #154) final serviceAccountCreds = // ... get credentials via #154 if (serviceAccountCreds != null) { // Use local signing (#156) return serviceAccountCreds.sign(data); } // 3. Fall back to IAM signing (#157) // Determine endpoint from universe domain (#155) final universeDomain = // ... from credentials or default endpoint ??= 'https://iamcredentials.$universeDomain'; final signer = IAMSigner( this, serviceAccountEmail: await _getServiceAccountEmail(), endpoint: endpoint, ); return signer.sign(data); } } ``` ### Use Case Provides a seamless signing API that works across all authentication scenarios: ```dart // Works with service account key file final creds = ServiceAccountCredentials.fromJson(json); final client = await clientViaServiceAccount(creds, scopes); final signature = await client.sign(dataToSign); // Works with ADC on GCE/Cloud Run final client = await clientViaApplicationDefaultCredentials(scopes: scopes); final signature = await client.sign(dataToSign); // Works with impersonated credentials final impersonatedClient = ImpersonatedAuthClient( sourceClient: sourceClient, targetPrincipal: 'target@project.iam.gserviceaccount.com', ); final signature = await impersonatedClient.sign(dataToSign); ``` Users don't need to know or care about the authentication method - signing "just works". ### Dependencies This issue **depends on all previous issues**: - **#156** (Public Signing API): For local signing with service account credentials - **#157** (IAM signBlob API): For remote signing via IAM API - **#158** (ImpersonatedAuthClient): For impersonated signing - **#155** (universeDomain and projectId fields): For correct IAM endpoint construction - **#154** (Credential-Client Association): To determine which signing method to use ### Implementation Order This should be implemented **last**, after all dependencies are complete. ### References - Node.js equivalent: [GoogleAuth.sign() method](https://github.com/googleapis/google-cloud-node-core/blob/main/packages/google-auth-library-nodejs/src/auth/googleauth.ts#L1272-L1310) - intelligently chooses between local signing (JWT), IAM signBlob, or impersonated signing - Related to replacing `googleapis_auth_utils` functionality - This is the final piece that makes `googleapis_auth_utils` obsolete
0 条评论