UNPKG

@azure/core-rest-pipeline

Version:

Isomorphic client library for making HTTP requests in node.js and browser.

62 lines 3.11 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. import { createTokenCycler } from "../util/tokenCycler.js"; import { logger as coreLogger } from "../log.js"; /** * The programmatic identifier of the auxiliaryAuthenticationHeaderPolicy. */ export const auxiliaryAuthenticationHeaderPolicyName = "auxiliaryAuthenticationHeaderPolicy"; const AUTHORIZATION_AUXILIARY_HEADER = "x-ms-authorization-auxiliary"; async function sendAuthorizeRequest(options) { const { scopes, getAccessToken, request } = options; const getTokenOptions = { abortSignal: request.abortSignal, tracingOptions: request.tracingOptions, }; return (await getAccessToken(scopes, getTokenOptions))?.token ?? ""; } /** * A policy for external tokens to `x-ms-authorization-auxiliary` header. * This header will be used when creating a cross-tenant application we may need to handle authentication requests * for resources that are in different tenants. * 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 */ export function auxiliaryAuthenticationHeaderPolicy(options) { const { credentials, scopes } = options; const logger = options.logger || coreLogger; const tokenCyclerMap = new WeakMap(); return { name: auxiliaryAuthenticationHeaderPolicyName, async sendRequest(request, next) { if (!request.url.toLowerCase().startsWith("https://")) { throw new Error("Bearer token authentication for auxiliary header is not permitted for non-TLS protected (non-https) URLs."); } if (!credentials || credentials.length === 0) { logger.info(`${auxiliaryAuthenticationHeaderPolicyName} header will not be set due to empty credentials.`); return next(request); } const tokenPromises = []; for (const credential of credentials) { let getAccessToken = tokenCyclerMap.get(credential); if (!getAccessToken) { getAccessToken = createTokenCycler(credential); tokenCyclerMap.set(credential, getAccessToken); } tokenPromises.push(sendAuthorizeRequest({ scopes: Array.isArray(scopes) ? scopes : [scopes], request, getAccessToken, logger, })); } const auxiliaryTokens = (await Promise.all(tokenPromises)).filter((token) => Boolean(token)); if (auxiliaryTokens.length === 0) { logger.warning(`None of the auxiliary tokens are valid. ${AUTHORIZATION_AUXILIARY_HEADER} header will not be set.`); return next(request); } request.headers.set(AUTHORIZATION_AUXILIARY_HEADER, auxiliaryTokens.map((token) => `Bearer ${token}`).join(", ")); return next(request); }, }; } //# sourceMappingURL=auxiliaryAuthenticationHeaderPolicy.js.map