wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
{"version":3,"file":"auxiliaryAuthenticationHeaderPolicy.js","sourceRoot":"","sources":["../../../src/policies/auxiliaryAuthenticationHeaderPolicy.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\nimport type { AzureLogger } from \"@azure/logger\";\nimport type { PipelineRequest, PipelineResponse, SendRequest } from \"../interfaces.js\";\nimport type { PipelinePolicy } from \"../pipeline.js\";\nimport { type AccessTokenGetter, createTokenCycler } from \"../util/tokenCycler.js\";\nimport { logger as coreLogger } from \"../log.js\";\nimport type { AuthorizeRequestOptions } from \"./bearerTokenAuthenticationPolicy.js\";\n\n/**\n * The programmatic identifier of the auxiliaryAuthenticationHeaderPolicy.\n */\nexport const auxiliaryAuthenticationHeaderPolicyName = \"auxiliaryAuthenticationHeaderPolicy\";\nconst AUTHORIZATION_AUXILIARY_HEADER = \"x-ms-authorization-auxiliary\";\n\n/**\n * Options to configure the auxiliaryAuthenticationHeaderPolicy\n */\nexport interface AuxiliaryAuthenticationHeaderPolicyOptions {\n  /**\n   * TokenCredential list used to get token from auxiliary tenants and\n   * one credential for each tenant the client may need to access\n   */\n  credentials?: TokenCredential[];\n  /**\n   * Scopes depend on the cloud your application runs in\n   */\n  scopes: string | string[];\n  /**\n   * A logger can be sent for debugging purposes.\n   */\n  logger?: AzureLogger;\n}\n\nasync function sendAuthorizeRequest(options: AuthorizeRequestOptions): Promise<string> {\n  const { scopes, getAccessToken, request } = options;\n  const getTokenOptions: GetTokenOptions = {\n    abortSignal: request.abortSignal,\n    tracingOptions: request.tracingOptions,\n  };\n\n  return (await getAccessToken(scopes, getTokenOptions))?.token ?? \"\";\n}\n\n/**\n * A policy for external tokens to `x-ms-authorization-auxiliary` header.\n * This header will be used when creating a cross-tenant application we may need to handle authentication requests\n * for resources that are in different tenants.\n * You could see [ARM docs](https://learn.microsoft.com/azure/azure-resource-manager/management/authenticate-multi-tenant) for a rundown of how this feature works\n */\nexport function auxiliaryAuthenticationHeaderPolicy(\n  options: AuxiliaryAuthenticationHeaderPolicyOptions,\n): PipelinePolicy {\n  const { credentials, scopes } = options;\n  const logger = options.logger || coreLogger;\n  const tokenCyclerMap = new WeakMap<TokenCredential, AccessTokenGetter>();\n\n  return {\n    name: auxiliaryAuthenticationHeaderPolicyName,\n    async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n      if (!request.url.toLowerCase().startsWith(\"https://\")) {\n        throw new Error(\n          \"Bearer token authentication for auxiliary header is not permitted for non-TLS protected (non-https) URLs.\",\n        );\n      }\n      if (!credentials || credentials.length === 0) {\n        logger.info(\n          `${auxiliaryAuthenticationHeaderPolicyName} header will not be set due to empty credentials.`,\n        );\n        return next(request);\n      }\n\n      const tokenPromises: Promise<string>[] = [];\n      for (const credential of credentials) {\n        let getAccessToken = tokenCyclerMap.get(credential);\n        if (!getAccessToken) {\n          getAccessToken = createTokenCycler(credential);\n          tokenCyclerMap.set(credential, getAccessToken);\n        }\n        tokenPromises.push(\n          sendAuthorizeRequest({\n            scopes: Array.isArray(scopes) ? scopes : [scopes],\n            request,\n            getAccessToken,\n            logger,\n          }),\n        );\n      }\n      const auxiliaryTokens = (await Promise.all(tokenPromises)).filter((token) => Boolean(token));\n      if (auxiliaryTokens.length === 0) {\n        logger.warning(\n          `None of the auxiliary tokens are valid. ${AUTHORIZATION_AUXILIARY_HEADER} header will not be set.`,\n        );\n        return next(request);\n      }\n      request.headers.set(\n        AUTHORIZATION_AUXILIARY_HEADER,\n        auxiliaryTokens.map((token) => `Bearer ${token}`).join(\", \"),\n      );\n\n      return next(request);\n    },\n  };\n}\n"]}