first commit
SAP-ERP Portal CI/CD / build (push) Failing after 5m20s

This commit is contained in:
John
2026-09-23 17:31:02 +05:30
commit 69b4e68baf
51657 changed files with 3864077 additions and 0 deletions
+235
View File
@@ -0,0 +1,235 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { ServiceClient } from "@azure/core-client";
import { isNode } from "@azure/core-util";
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { AbortController } from "@azure/abort-controller";
import { AuthenticationError, AuthenticationErrorName } from "../errors";
import { getIdentityTokenEndpointSuffix } from "../util/identityTokenEndpoint";
import { DefaultAuthorityHost, SDK_VERSION } from "../constants";
import { tracingClient } from "../util/tracing";
import { logger } from "../util/logging";
const noCorrelationId = "noCorrelationId";
/**
* @internal
*/
export function getIdentityClientAuthorityHost(options) {
// The authorityHost can come from options or from the AZURE_AUTHORITY_HOST environment variable.
let authorityHost = options === null || options === void 0 ? void 0 : options.authorityHost;
// The AZURE_AUTHORITY_HOST environment variable can only be provided in Node.js.
if (isNode) {
authorityHost = authorityHost !== null && authorityHost !== void 0 ? authorityHost : process.env.AZURE_AUTHORITY_HOST;
}
// If the authorityHost is not provided, we use the default one from the public cloud: https://login.microsoftonline.com
return authorityHost !== null && authorityHost !== void 0 ? authorityHost : DefaultAuthorityHost;
}
/**
* The network module used by the Identity credentials.
*
* It allows for credentials to abort any pending request independently of the MSAL flow,
* by calling to the `abortRequests()` method.
*
*/
export class IdentityClient extends ServiceClient {
constructor(options) {
var _a, _b;
const packageDetails = `azsdk-js-identity/${SDK_VERSION}`;
const userAgentPrefix = ((_a = options === null || options === void 0 ? void 0 : options.userAgentOptions) === null || _a === void 0 ? void 0 : _a.userAgentPrefix)
? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
: `${packageDetails}`;
const baseUri = getIdentityClientAuthorityHost(options);
if (!baseUri.startsWith("https:")) {
throw new Error("The authorityHost address must use the 'https' protocol.");
}
super(Object.assign(Object.assign({ requestContentType: "application/json; charset=utf-8", retryOptions: {
maxRetries: 3,
} }, options), { userAgentOptions: {
userAgentPrefix,
}, baseUri }));
this.authorityHost = baseUri;
this.abortControllers = new Map();
this.allowLoggingAccountIdentifiers = (_b = options === null || options === void 0 ? void 0 : options.loggingOptions) === null || _b === void 0 ? void 0 : _b.allowLoggingAccountIdentifiers;
}
async sendTokenRequest(request, expiresOnParser) {
logger.info(`IdentityClient: sending token request to [${request.url}]`);
const response = await this.sendRequest(request);
expiresOnParser =
expiresOnParser ||
((responseBody) => {
return Date.now() + responseBody.expires_in * 1000;
});
if (response.bodyAsText && (response.status === 200 || response.status === 201)) {
const parsedBody = JSON.parse(response.bodyAsText);
if (!parsedBody.access_token) {
return null;
}
this.logIdentifiers(response);
const token = {
accessToken: {
token: parsedBody.access_token,
expiresOnTimestamp: expiresOnParser(parsedBody),
},
refreshToken: parsedBody.refresh_token,
};
logger.info(`IdentityClient: [${request.url}] token acquired, expires on ${token.accessToken.expiresOnTimestamp}`);
return token;
}
else {
const error = new AuthenticationError(response.status, response.bodyAsText);
logger.warning(`IdentityClient: authentication error. HTTP status: ${response.status}, ${error.errorResponse.errorDescription}`);
throw error;
}
}
async refreshAccessToken(tenantId, clientId, scopes, refreshToken, clientSecret, expiresOnParser, options = {}) {
if (refreshToken === undefined) {
return null;
}
logger.info(`IdentityClient: refreshing access token with client ID: ${clientId}, scopes: ${scopes} started`);
const refreshParams = {
grant_type: "refresh_token",
client_id: clientId,
refresh_token: refreshToken,
scope: scopes,
};
if (clientSecret !== undefined) {
refreshParams.client_secret = clientSecret;
}
const query = new URLSearchParams(refreshParams);
return tracingClient.withSpan("IdentityClient.refreshAccessToken", options, async (updatedOptions) => {
try {
const urlSuffix = getIdentityTokenEndpointSuffix(tenantId);
const request = createPipelineRequest({
url: `${this.authorityHost}/${tenantId}/${urlSuffix}`,
method: "POST",
body: query.toString(),
abortSignal: options.abortSignal,
headers: createHttpHeaders({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
}),
tracingOptions: updatedOptions.tracingOptions,
});
const response = await this.sendTokenRequest(request, expiresOnParser);
logger.info(`IdentityClient: refreshed token for client ID: ${clientId}`);
return response;
}
catch (err) {
if (err.name === AuthenticationErrorName &&
err.errorResponse.error === "interaction_required") {
// It's likely that the refresh token has expired, so
// return null so that the credential implementation will
// initiate the authentication flow again.
logger.info(`IdentityClient: interaction required for client ID: ${clientId}`);
return null;
}
else {
logger.warning(`IdentityClient: failed refreshing token for client ID: ${clientId}: ${err}`);
throw err;
}
}
});
}
// Here is a custom layer that allows us to abort requests that go through MSAL,
// since MSAL doesn't allow us to pass options all the way through.
generateAbortSignal(correlationId) {
const controller = new AbortController();
const controllers = this.abortControllers.get(correlationId) || [];
controllers.push(controller);
this.abortControllers.set(correlationId, controllers);
const existingOnAbort = controller.signal.onabort;
controller.signal.onabort = (...params) => {
this.abortControllers.set(correlationId, undefined);
if (existingOnAbort) {
existingOnAbort(...params);
}
};
return controller.signal;
}
abortRequests(correlationId) {
const key = correlationId || noCorrelationId;
const controllers = [
...(this.abortControllers.get(key) || []),
// MSAL passes no correlation ID to the get requests...
...(this.abortControllers.get(noCorrelationId) || []),
];
if (!controllers.length) {
return;
}
for (const controller of controllers) {
controller.abort();
}
this.abortControllers.set(key, undefined);
}
getCorrelationId(options) {
var _a;
const parameter = (_a = options === null || options === void 0 ? void 0 : options.body) === null || _a === void 0 ? void 0 : _a.split("&").map((part) => part.split("=")).find(([key]) => key === "client-request-id");
return parameter && parameter.length ? parameter[1] || noCorrelationId : noCorrelationId;
}
// The MSAL network module methods follow
async sendGetRequestAsync(url, options) {
const request = createPipelineRequest({
url,
method: "GET",
body: options === null || options === void 0 ? void 0 : options.body,
headers: createHttpHeaders(options === null || options === void 0 ? void 0 : options.headers),
abortSignal: this.generateAbortSignal(noCorrelationId),
});
const response = await this.sendRequest(request);
this.logIdentifiers(response);
return {
body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
headers: response.headers.toJSON(),
status: response.status,
};
}
async sendPostRequestAsync(url, options) {
const request = createPipelineRequest({
url,
method: "POST",
body: options === null || options === void 0 ? void 0 : options.body,
headers: createHttpHeaders(options === null || options === void 0 ? void 0 : options.headers),
// MSAL doesn't send the correlation ID on the get requests.
abortSignal: this.generateAbortSignal(this.getCorrelationId(options)),
});
const response = await this.sendRequest(request);
this.logIdentifiers(response);
return {
body: response.bodyAsText ? JSON.parse(response.bodyAsText) : undefined,
headers: response.headers.toJSON(),
status: response.status,
};
}
/**
* If allowLoggingAccountIdentifiers was set on the constructor options
* we try to log the account identifiers by parsing the received access token.
*
* The account identifiers we try to log are:
* - `appid`: The application or Client Identifier.
* - `upn`: User Principal Name.
* - It might not be available in some authentication scenarios.
* - If it's not available, we put a placeholder: "No User Principal Name available".
* - `tid`: Tenant Identifier.
* - `oid`: Object Identifier of the authenticated user.
*/
logIdentifiers(response) {
if (!this.allowLoggingAccountIdentifiers || !response.bodyAsText) {
return;
}
const unavailableUpn = "No User Principal Name available";
try {
const parsed = response.parsedBody || JSON.parse(response.bodyAsText);
const accessToken = parsed.access_token;
if (!accessToken) {
// Without an access token allowLoggingAccountIdentifiers isn't useful.
return;
}
const base64Metadata = accessToken.split(".")[1];
const { appid, upn, tid, oid } = JSON.parse(Buffer.from(base64Metadata, "base64").toString("utf8"));
logger.info(`[Authenticated account] Client ID: ${appid}. Tenant ID: ${tid}. User Principal Name: ${upn || unavailableUpn}. Object ID (user): ${oid}`);
}
catch (e) {
logger.warning("allowLoggingAccountIdentifiers was set, but we couldn't log the account information. Error:", e.message);
}
}
}
//# sourceMappingURL=identityClient.js.map
File diff suppressed because one or more lines are too long
+46
View File
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
/**
* Current version of the `@azure/identity` package.
*/
export const SDK_VERSION = `2.1.0`;
/**
* The default client ID for authentication
* @internal
*/
// TODO: temporary - this is the Azure CLI clientID - we'll replace it when
// Developer Sign On application is available
// https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/Constants.cs#L9
export const DeveloperSignOnClientId = "04b07795-8ddb-461a-bbee-02f9e1bf7b46";
/**
* The default tenant for authentication
* @internal
*/
export const DefaultTenantId = "common";
/**
* A list of known Azure authority hosts
*/
export var AzureAuthorityHosts;
(function (AzureAuthorityHosts) {
/**
* China-based Azure Authority Host
*/
AzureAuthorityHosts["AzureChina"] = "https://login.chinacloudapi.cn";
/**
* Germany-based Azure Authority Host
*/
AzureAuthorityHosts["AzureGermany"] = "https://login.microsoftonline.de";
/**
* US Government Azure Authority Host
*/
AzureAuthorityHosts["AzureGovernment"] = "https://login.microsoftonline.us";
/**
* Public Cloud Azure Authority Host
*/
AzureAuthorityHosts["AzurePublicCloud"] = "https://login.microsoftonline.com";
})(AzureAuthorityHosts || (AzureAuthorityHosts = {}));
/**
* The default authority host.
*/
export const DefaultAuthorityHost = AzureAuthorityHosts.AzurePublicCloud;
//# sourceMappingURL=constants.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC;AAEnC;;;GAGG;AACH,2EAA2E;AAC3E,6CAA6C;AAC7C,uGAAuG;AACvG,MAAM,CAAC,MAAM,uBAAuB,GAAG,sCAAsC,CAAC;AAE9E;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC;AAExC;;GAEG;AACH,MAAM,CAAN,IAAY,mBAiBX;AAjBD,WAAY,mBAAmB;IAC7B;;OAEG;IACH,oEAA6C,CAAA;IAC7C;;OAEG;IACH,wEAAiD,CAAA;IACjD;;OAEG;IACH,2EAAoD,CAAA;IACpD;;OAEG;IACH,6EAAsD,CAAA;AACxD,CAAC,EAjBW,mBAAmB,KAAnB,mBAAmB,QAiB9B;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC,gBAAgB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/**\n * Current version of the `@azure/identity` package.\n */\nexport const SDK_VERSION = `2.1.0`;\n\n/**\n * The default client ID for authentication\n * @internal\n */\n// TODO: temporary - this is the Azure CLI clientID - we'll replace it when\n// Developer Sign On application is available\n// https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/Constants.cs#L9\nexport const DeveloperSignOnClientId = \"04b07795-8ddb-461a-bbee-02f9e1bf7b46\";\n\n/**\n * The default tenant for authentication\n * @internal\n */\nexport const DefaultTenantId = \"common\";\n\n/**\n * A list of known Azure authority hosts\n */\nexport enum AzureAuthorityHosts {\n /**\n * China-based Azure Authority Host\n */\n AzureChina = \"https://login.chinacloudapi.cn\",\n /**\n * Germany-based Azure Authority Host\n */\n AzureGermany = \"https://login.microsoftonline.de\",\n /**\n * US Government Azure Authority Host\n */\n AzureGovernment = \"https://login.microsoftonline.us\",\n /**\n * Public Cloud Azure Authority Host\n */\n AzurePublicCloud = \"https://login.microsoftonline.com\",\n}\n\n/**\n * The default authority host.\n */\nexport const DefaultAuthorityHost = AzureAuthorityHosts.AzurePublicCloud;\n"]}
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("AuthorizationCodeCredential is not supported in the browser. InteractiveBrowserCredential is more appropriate for this use case.");
const logger = credentialLogger("AuthorizationCodeCredential");
export class AuthorizationCodeCredential {
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=authorizationCodeCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"authorizationCodeCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/authorizationCodeCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,kIAAkI,CACnI,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,6BAA6B,CAAC,CAAC;AAE/D,MAAM,OAAO,2BAA2B;IAmBtC;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"AuthorizationCodeCredential is not supported in the browser. InteractiveBrowserCredential is more appropriate for this use case.\"\n);\nconst logger = credentialLogger(\"AuthorizationCodeCredential\");\n\nexport class AuthorizationCodeCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor(\n tenantId: string | \"common\",\n clientId: string,\n clientSecret: string,\n authorizationCode: string,\n redirectUri: string,\n options?: TokenCredentialOptions\n );\n constructor(\n tenantId: string | \"common\",\n clientId: string,\n authorizationCode: string,\n redirectUri: string,\n options?: TokenCredentialOptions\n );\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,55 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger } from "../util/logging";
import { checkTenantId } from "../util/checkTenantId";
import { MsalAuthorizationCode } from "../msal/nodeFlows/msalAuthorizationCode";
import { tracingClient } from "../util/tracing";
const logger = credentialLogger("AuthorizationCodeCredential");
/**
* Enables authentication to Azure Active Directory using an authorization code
* that was obtained through the authorization code flow, described in more detail
* in the Azure Active Directory documentation:
*
* https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow
*/
export class AuthorizationCodeCredential {
/**
* @hidden
* @internal
*/
constructor(tenantId, clientId, clientSecretOrAuthorizationCode, authorizationCodeOrRedirectUri, redirectUriOrOptions, options) {
checkTenantId(logger, tenantId);
let clientSecret = clientSecretOrAuthorizationCode;
if (typeof redirectUriOrOptions === "string") {
// the clientId+clientSecret constructor
this.authorizationCode = authorizationCodeOrRedirectUri;
this.redirectUri = redirectUriOrOptions;
// in this case, options are good as they come
}
else {
// clientId only
this.authorizationCode = clientSecretOrAuthorizationCode;
this.redirectUri = authorizationCodeOrRedirectUri;
clientSecret = undefined;
options = redirectUriOrOptions;
}
this.msalFlow = new MsalAuthorizationCode(Object.assign(Object.assign({}, options), { clientSecret,
clientId,
tenantId, tokenCredentialOptions: options || {}, logger, redirectUri: this.redirectUri, authorizationCode: this.authorizationCode }));
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
});
}
}
//# sourceMappingURL=authorizationCodeCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
import { ChainedTokenCredential } from "./chainedTokenCredential";
const BrowserNotSupportedError = new Error("ApplicationCredential is not supported in the browser. Use InteractiveBrowserCredential instead.");
const logger = credentialLogger("ApplicationCredential");
/**
* Provides a default {@link ChainedTokenCredential} configuration for
* applications that will be deployed to Azure.
*
* Only available in Node.js
*/
export class AzureApplicationCredential extends ChainedTokenCredential {
/**
* Creates an instance of the AzureApplicationCredential class.
*
* The AzureApplicationCredential provides a default {@link ChainedTokenCredential} configuration for
* applications that will be deployed to Azure.
*
* Only available in Node.js
*
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(_tokenCredentialOptions) {
super();
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=azureApplicationCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"azureApplicationCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/azureApplicationCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,kGAAkG,CACnG,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,OAAO,0BAA2B,SAAQ,sBAAsB;IACpE;;;;;;;;;OASG;IACH,YAAY,uBAAgD;QAC1D,KAAK,EAAE,CAAC;QACR,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken } from \"@azure/core-auth\";\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { credentialLogger, formatError } from \"../util/logging\";\nimport { ChainedTokenCredential } from \"./chainedTokenCredential\";\n\nconst BrowserNotSupportedError = new Error(\n \"ApplicationCredential is not supported in the browser. Use InteractiveBrowserCredential instead.\"\n);\nconst logger = credentialLogger(\"ApplicationCredential\");\n\n/**\n * Provides a default {@link ChainedTokenCredential} configuration for\n * applications that will be deployed to Azure.\n *\n * Only available in Node.js\n */\nexport class AzureApplicationCredential extends ChainedTokenCredential {\n /**\n * Creates an instance of the AzureApplicationCredential class.\n *\n * The AzureApplicationCredential provides a default {@link ChainedTokenCredential} configuration for\n * applications that will be deployed to Azure.\n *\n * Only available in Node.js\n *\n * @param options - Options for configuring the client which makes the authentication request.\n */\n constructor(_tokenCredentialOptions?: TokenCredentialOptions) {\n super();\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,35 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { ChainedTokenCredential } from "./chainedTokenCredential";
import { EnvironmentCredential } from "./environmentCredential";
import { DefaultManagedIdentityCredential } from "./defaultAzureCredential";
export const AzureApplicationCredentials = [
EnvironmentCredential,
DefaultManagedIdentityCredential,
];
/**
* Provides a default {@link ChainedTokenCredential} configuration that should
* work for most applications that use the Azure SDK.
*/
export class AzureApplicationCredential extends ChainedTokenCredential {
/**
* Creates an instance of the AzureApplicationCredential class.
*
* The AzureApplicationCredential provides a default {@link ChainedTokenCredential} configuration that should
* work for most applications deployed on Azure. The following credential types will be tried, in order:
*
* - {@link EnvironmentCredential}
* - {@link ManagedIdentityCredential}
*
* Consult the documentation of these credential types for more information
* on how they attempt authentication.
*
* @param options - Optional parameters. See {@link AzureApplicationCredentialOptions}.
*/
constructor(options) {
super(...AzureApplicationCredentials.map((ctor) => new ctor(options)));
this.UnavailableMessage =
"ApplicationCredential => failed to retrieve a token from the included credentials. To troubleshoot, visit https://aka.ms/azsdk/js/identity/applicationcredential/troubleshoot.";
}
}
//# sourceMappingURL=azureApplicationCredential.js.map
@@ -0,0 +1 @@
{"version":3,"file":"azureApplicationCredential.js","sourceRoot":"","sources":["../../../src/credentials/azureApplicationCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAOlC,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,gCAAgC,EAAE,MAAM,0BAA0B,CAAC;AAuB5E,MAAM,CAAC,MAAM,2BAA2B,GAA4C;IAClF,qBAAqB;IACrB,gCAAgC;CACjC,CAAC;AAEF;;;GAGG;AACH,MAAM,OAAO,0BAA2B,SAAQ,sBAAsB;IACpE;;;;;;;;;;;;;OAaG;IACH,YAAY,OAA2C;QACrD,KAAK,CAAC,GAAG,2BAA2B,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACvE,IAAI,CAAC,kBAAkB;YACrB,gLAAgL,CAAC;IACrL,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredential } from \"@azure/core-auth\";\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { ChainedTokenCredential } from \"./chainedTokenCredential\";\nimport { EnvironmentCredential } from \"./environmentCredential\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\nimport { DefaultManagedIdentityCredential } from \"./defaultAzureCredential\";\n\n/**\n * Provides options to configure the {@link AzureApplicationCredential} class.\n */\nexport interface AzureApplicationCredentialOptions\n extends TokenCredentialOptions,\n CredentialPersistenceOptions {\n /**\n * Optionally pass in a user assigned client ID to be used by the {@link ManagedIdentityCredential}.\n * This client ID can also be passed through to the {@link ManagedIdentityCredential} through the environment variable: AZURE_CLIENT_ID.\n */\n managedIdentityClientId?: string;\n}\n\n/**\n * The type of a class that implements TokenCredential and accepts\n * `ApplicationCredentialOptions`.\n */\ninterface AzureApplicationCredentialConstructor {\n new (options?: AzureApplicationCredentialOptions): TokenCredential;\n}\n\nexport const AzureApplicationCredentials: AzureApplicationCredentialConstructor[] = [\n EnvironmentCredential,\n DefaultManagedIdentityCredential,\n];\n\n/**\n * Provides a default {@link ChainedTokenCredential} configuration that should\n * work for most applications that use the Azure SDK.\n */\nexport class AzureApplicationCredential extends ChainedTokenCredential {\n /**\n * Creates an instance of the AzureApplicationCredential class.\n *\n * The AzureApplicationCredential provides a default {@link ChainedTokenCredential} configuration that should\n * work for most applications deployed on Azure. The following credential types will be tried, in order:\n *\n * - {@link EnvironmentCredential}\n * - {@link ManagedIdentityCredential}\n *\n * Consult the documentation of these credential types for more information\n * on how they attempt authentication.\n *\n * @param options - Optional parameters. See {@link AzureApplicationCredentialOptions}.\n */\n constructor(options?: AzureApplicationCredentialOptions) {\n super(...AzureApplicationCredentials.map((ctor) => new ctor(options)));\n this.UnavailableMessage =\n \"ApplicationCredential => failed to retrieve a token from the included credentials. To troubleshoot, visit https://aka.ms/azsdk/js/identity/applicationcredential/troubleshoot.\";\n }\n}\n"]}
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("AzureCliCredential is not supported in the browser.");
const logger = credentialLogger("AzureCliCredential");
/**
* This credential will use the currently logged-in user login information
* via the Azure CLI ('az') commandline tool.
*/
export class AzureCliCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=azureCliCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"azureCliCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/azureCliCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CAAC,qDAAqD,CAAC,CAAC;AAClG,MAAM,MAAM,GAAG,gBAAgB,CAAC,oBAAoB,CAAC,CAAC;AAEtD;;;GAGG;AACH,MAAM,OAAO,kBAAkB;IAC7B;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAED,QAAQ;QACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\"AzureCliCredential is not supported in the browser.\");\nconst logger = credentialLogger(\"AzureCliCredential\");\n\n/**\n * This credential will use the currently logged-in user login information\n * via the Azure CLI ('az') commandline tool.\n */\nexport class AzureCliCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,139 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { tracingClient } from "../util/tracing";
import { CredentialUnavailableError } from "../errors";
import { credentialLogger, formatError, formatSuccess } from "../util/logging";
import child_process from "child_process";
import { ensureValidScope, getScopeResource } from "../util/scopeUtils";
import { processMultiTenantRequest } from "../util/validateMultiTenant";
import { checkTenantId } from "../util/checkTenantId";
/**
* Mockable reference to the CLI credential cliCredentialFunctions
* @internal
*/
export const cliCredentialInternals = {
/**
* @internal
*/
getSafeWorkingDir() {
if (process.platform === "win32") {
if (!process.env.SystemRoot) {
throw new Error("Azure CLI credential expects a 'SystemRoot' environment variable");
}
return process.env.SystemRoot;
}
else {
return "/bin";
}
},
/**
* Gets the access token from Azure CLI
* @param resource - The resource to use when getting the token
* @internal
*/
async getAzureCliAccessToken(resource, tenantId) {
let tenantSection = [];
if (tenantId) {
tenantSection = ["--tenant", tenantId];
}
return new Promise((resolve, reject) => {
try {
child_process.execFile("az", [
"account",
"get-access-token",
"--output",
"json",
"--resource",
resource,
...tenantSection,
], { cwd: cliCredentialInternals.getSafeWorkingDir(), shell: true }, (error, stdout, stderr) => {
resolve({ stdout: stdout, stderr: stderr, error });
});
}
catch (err) {
reject(err);
}
});
},
};
const logger = credentialLogger("AzureCliCredential");
/**
* This credential will use the currently logged-in user login information
* via the Azure CLI ('az') commandline tool.
* To do so, it will read the user access token and expire time
* with Azure CLI command "az account get-access-token".
*/
export class AzureCliCredential {
/**
* Creates an instance of the {@link AzureCliCredential}.
*
* To use this credential, ensure that you have already logged
* in via the 'az' tool using the command "az login" from the commandline.
*
* @param options - Options, to optionally allow multi-tenant requests.
*/
constructor(options) {
this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
const tenantId = processMultiTenantRequest(this.tenantId, options);
if (tenantId) {
checkTenantId(logger, tenantId);
}
const scope = typeof scopes === "string" ? scopes : scopes[0];
logger.getToken.info(`Using the scope ${scope}`);
ensureValidScope(scope, logger);
const resource = getScopeResource(scope);
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
var _a, _b, _c, _d;
try {
const obj = await cliCredentialInternals.getAzureCliAccessToken(resource, tenantId);
const specificScope = (_a = obj.stderr) === null || _a === void 0 ? void 0 : _a.match("(.*)az login --scope(.*)");
const isLoginError = ((_b = obj.stderr) === null || _b === void 0 ? void 0 : _b.match("(.*)az login(.*)")) && !specificScope;
const isNotInstallError = ((_c = obj.stderr) === null || _c === void 0 ? void 0 : _c.match("az:(.*)not found")) || ((_d = obj.stderr) === null || _d === void 0 ? void 0 : _d.startsWith("'az' is not recognized"));
if (isNotInstallError) {
const error = new CredentialUnavailableError("Azure CLI could not be found. Please visit https://aka.ms/azure-cli for installation instructions and then, once installed, authenticate to your Azure account using 'az login'.");
logger.getToken.info(formatError(scopes, error));
throw error;
}
if (isLoginError) {
const error = new CredentialUnavailableError("Please run 'az login' from a command prompt to authenticate before using this credential.");
logger.getToken.info(formatError(scopes, error));
throw error;
}
try {
const responseData = obj.stdout;
const response = JSON.parse(responseData);
logger.getToken.info(formatSuccess(scopes));
const returnValue = {
token: response.accessToken,
expiresOnTimestamp: new Date(response.expiresOn).getTime(),
};
return returnValue;
}
catch (e) {
if (obj.stderr) {
throw new CredentialUnavailableError(obj.stderr);
}
throw e;
}
}
catch (err) {
const error = err.name === "CredentialUnavailableError"
? err
: new CredentialUnavailableError(err.message || "Unknown error while trying to retrieve the access token");
logger.getToken.info(formatError(scopes, error));
throw error;
}
});
}
}
//# sourceMappingURL=azureCliCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=azureCliCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"azureCliCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/azureCliCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\n\n/**\n * Options for the {@link AzureCliCredential}\n */\nexport interface AzureCliCredentialOptions extends TokenCredentialOptions {\n /**\n * Allows specifying a tenant ID\n */\n tenantId?: string;\n}\n"]}
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("AzurePowerShellCredential is not supported in the browser.");
const logger = credentialLogger("AzurePowerShellCredential");
/**
* This credential will use the currently-logged-in user's login information via the Azure Power Shell command line tool.
*/
export class AzurePowerShellCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=azurePowerShellCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"azurePowerShellCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/azurePowerShellCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,4DAA4D,CAC7D,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,2BAA2B,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,OAAO,yBAAyB;IACpC;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAED,QAAQ;QACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"AzurePowerShellCredential is not supported in the browser.\"\n);\nconst logger = credentialLogger(\"AzurePowerShellCredential\");\n\n/**\n * This credential will use the currently-logged-in user's login information via the Azure Power Shell command line tool.\n */\nexport class AzurePowerShellCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,173 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { CredentialUnavailableError } from "../errors";
import { credentialLogger, formatError, formatSuccess } from "../util/logging";
import { tracingClient } from "../util/tracing";
import { ensureValidScope, getScopeResource } from "../util/scopeUtils";
import { processUtils } from "../util/processUtils";
import { processMultiTenantRequest } from "../util/validateMultiTenant";
import { checkTenantId } from "../util/checkTenantId";
const logger = credentialLogger("AzurePowerShellCredential");
const isWindows = process.platform === "win32";
/**
* Returns a platform-appropriate command name by appending ".exe" on Windows.
*
* @internal
*/
export function formatCommand(commandName) {
if (isWindows) {
return `${commandName}.exe`;
}
else {
return commandName;
}
}
/**
* Receives a list of commands to run, executes them, then returns the outputs.
* If anything fails, an error is thrown.
* @internal
*/
async function runCommands(commands) {
const results = [];
for (const command of commands) {
const [file, ...parameters] = command;
const result = (await processUtils.execFile(file, parameters, { encoding: "utf8" }));
results.push(result);
}
return results;
}
/**
* Known PowerShell errors
* @internal
*/
export const powerShellErrors = {
login: "Run Connect-AzAccount to login",
installed: "The specified module 'Az.Accounts' with version '2.2.0' was not loaded because no valid module file was found in any module directory",
};
/**
* Messages to use when throwing in this credential.
* @internal
*/
export const powerShellPublicErrorMessages = {
login: "Please run 'Connect-AzAccount' from PowerShell to authenticate before using this credential.",
installed: `The 'Az.Account' module >= 2.2.0 is not installed. Install the Azure Az PowerShell module with: "Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force".`,
troubleshoot: `To troubleshoot, visit https://aka.ms/azsdk/js/identity/powershellcredential/troubleshoot.`,
};
// PowerShell Azure User not logged in error check.
const isLoginError = (err) => err.message.match(`(.*)${powerShellErrors.login}(.*)`);
// Az Module not Installed in Azure PowerShell check.
const isNotInstalledError = (err) => err.message.match(powerShellErrors.installed);
/**
* The PowerShell commands to be tried, in order.
*
* @internal
*/
export const commandStack = [formatCommand("pwsh")];
if (isWindows) {
commandStack.push(formatCommand("powershell"));
}
/**
* This credential will use the currently logged-in user information from the
* Azure PowerShell module. To do so, it will read the user access token and
* expire time with Azure PowerShell command `Get-AzAccessToken -ResourceUrl {ResourceScope}`
*/
export class AzurePowerShellCredential {
/**
* Creates an instance of the {@link AzurePowerShellCredential}.
*
* To use this credential:
* - Install the Azure Az PowerShell module with:
* `Install-Module -Name Az -Scope CurrentUser -Repository PSGallery -Force`.
* - You have already logged in to Azure PowerShell using the command
* `Connect-AzAccount` from the command line.
*
* @param options - Options, to optionally allow multi-tenant requests.
*/
constructor(options) {
this.tenantId = options === null || options === void 0 ? void 0 : options.tenantId;
}
/**
* Gets the access token from Azure PowerShell
* @param resource - The resource to use when getting the token
*/
async getAzurePowerShellAccessToken(resource, tenantId) {
// Clone the stack to avoid mutating it while iterating
for (const powerShellCommand of [...commandStack]) {
try {
await runCommands([[powerShellCommand, "/?"]]);
}
catch (e) {
// Remove this credential from the original stack so that we don't try it again.
commandStack.shift();
continue;
}
let tenantSection = "";
if (tenantId) {
tenantSection = `-TenantId "${tenantId}"`;
}
const results = await runCommands([
[
powerShellCommand,
"-Command",
"Import-Module Az.Accounts -MinimumVersion 2.2.0 -PassThru",
],
[
powerShellCommand,
"-Command",
`Get-AzAccessToken ${tenantSection} -ResourceUrl "${resource}" | ConvertTo-Json`,
],
]);
const result = results[1];
try {
return JSON.parse(result);
}
catch (e) {
throw new Error(`Unable to parse the output of PowerShell. Received output: ${result}`);
}
}
throw new Error(`Unable to execute PowerShell. Ensure that it is installed in your system`);
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If the authentication cannot be performed through PowerShell, a {@link CredentialUnavailableError} will be thrown.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async () => {
const tenantId = processMultiTenantRequest(this.tenantId, options);
if (tenantId) {
checkTenantId(logger, tenantId);
}
const scope = typeof scopes === "string" ? scopes : scopes[0];
ensureValidScope(scope, logger);
logger.getToken.info(`Using the scope ${scope}`);
const resource = getScopeResource(scope);
try {
const response = await this.getAzurePowerShellAccessToken(resource, tenantId);
logger.getToken.info(formatSuccess(scopes));
return {
token: response.Token,
expiresOnTimestamp: new Date(response.ExpiresOn).getTime(),
};
}
catch (err) {
if (isNotInstalledError(err)) {
const error = new CredentialUnavailableError(powerShellPublicErrorMessages.installed);
logger.getToken.info(formatError(scope, error));
throw error;
}
else if (isLoginError(err)) {
const error = new CredentialUnavailableError(powerShellPublicErrorMessages.login);
logger.getToken.info(formatError(scope, error));
throw error;
}
const error = new CredentialUnavailableError(`${err}. ${powerShellPublicErrorMessages.troubleshoot}`);
logger.getToken.info(formatError(scope, error));
throw error;
}
});
}
}
//# sourceMappingURL=azurePowerShellCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=azurePowerShellCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"azurePowerShellCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/azurePowerShellCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\n\n/**\n * Options for the {@link AzurePowerShellCredential}\n */\nexport interface AzurePowerShellCredentialOptions extends TokenCredentialOptions {\n /**\n * Allows specifying a tenant ID\n */\n tenantId?: string;\n}\n"]}
@@ -0,0 +1,82 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { AggregateAuthenticationError, CredentialUnavailableError } from "../errors";
import { tracingClient } from "../util/tracing";
import { credentialLogger, formatError, formatSuccess } from "../util/logging";
/**
* @internal
*/
export const logger = credentialLogger("ChainedTokenCredential");
/**
* Enables multiple `TokenCredential` implementations to be tried in order
* until one of the getToken methods returns an access token.
*/
export class ChainedTokenCredential {
/**
* Creates an instance of ChainedTokenCredential using the given credentials.
*
* @param sources - `TokenCredential` implementations to be tried in order.
*
* Example usage:
* ```javascript
* const firstCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);
* const secondCredential = new ClientSecretCredential(tenantId, anotherClientId, anotherSecret);
* const credentialChain = new ChainedTokenCredential(firstCredential, secondCredential);
* ```
*/
constructor(...sources) {
/**
* The message to use when the chained token fails to get a token
*/
this.UnavailableMessage = "ChainedTokenCredential => failed to retrieve a token from the included credentials";
this._sources = [];
this._sources = sources;
}
/**
* Returns the first access token returned by one of the chained
* `TokenCredential` implementations. Throws an {@link AggregateAuthenticationError}
* when one or more credentials throws an {@link AuthenticationError} and
* no credentials have returned an access token.
*
* This method is called automatically by Azure SDK client libraries. You may call this method
* directly, but you must also handle token caching and token refreshing.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* `TokenCredential` implementation might make.
*/
async getToken(scopes, options = {}) {
let token = null;
let successfulCredentialName = "";
const errors = [];
return tracingClient.withSpan("ChainedTokenCredential.getToken", options, async (updatedOptions) => {
for (let i = 0; i < this._sources.length && token === null; i++) {
try {
token = await this._sources[i].getToken(scopes, updatedOptions);
successfulCredentialName = this._sources[i].constructor.name;
}
catch (err) {
if (err.name === "CredentialUnavailableError" ||
err.name === "AuthenticationRequiredError") {
errors.push(err);
}
else {
logger.getToken.info(formatError(scopes, err));
throw err;
}
}
}
if (!token && errors.length > 0) {
const err = new AggregateAuthenticationError(errors, "ChainedTokenCredential authentication failed.");
logger.getToken.info(formatError(scopes, err));
throw err;
}
logger.getToken.info(`Result for ${successfulCredentialName}: ${formatSuccess(scopes)}`);
if (token === null) {
throw new CredentialUnavailableError("Failed to retrieve a valid token");
}
return token;
});
}
}
//# sourceMappingURL=chainedTokenCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("ClientAssertionCredential is not supported in the browser.");
const logger = credentialLogger("ClientAssertionCredential");
/**
* Authenticates a service principal with a JWT assertion.
*/
export class ClientAssertionCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=clientAssertionCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"clientAssertionCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/clientAssertionCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,4DAA4D,CAC7D,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,2BAA2B,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,OAAO,yBAAyB;IACpC;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"ClientAssertionCredential is not supported in the browser.\"\n);\nconst logger = credentialLogger(\"ClientAssertionCredential\");\n\n/**\n * Authenticates a service principal with a JWT assertion.\n */\nexport class ClientAssertionCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,45 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger } from "../util/logging";
import { tracingClient } from "../util/tracing";
import { MsalClientAssertion } from "../msal/nodeFlows/msalClientAssertion";
const logger = credentialLogger("ClientAssertionCredential");
/**
* Authenticates a service principal with a JWT assertion.
*/
export class ClientAssertionCredential {
/**
* Creates an instance of the ClientAssertionCredential with the details
* needed to authenticate against Azure Active Directory with a client
* assertion provided by the developer through the `getAssertion` function parameter.
*
* @param tenantId - The Azure Active Directory tenant (directory) ID.
* @param clientId - The client (application) ID of an App Registration in the tenant.
* @param getAssertion - A function that retrieves the assertion for the credential to use.
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(tenantId, clientId, getAssertion, options = {}) {
if (!tenantId || !clientId || !getAssertion) {
throw new Error("ClientAssertionCredential: tenantId, clientId, and clientAssertion are required parameters.");
}
this.tenantId = tenantId;
this.clientId = clientId;
this.options = options;
this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, newOptions);
});
}
}
//# sourceMappingURL=clientAssertionCredential.js.map
@@ -0,0 +1 @@
{"version":3,"file":"clientAssertionCredential.js","sourceRoot":"","sources":["../../../src/credentials/clientAssertionCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAE5E,MAAM,MAAM,GAAG,gBAAgB,CAAC,2BAA2B,CAAC,CAAC;AAE7D;;GAEG;AACH,MAAM,OAAO,yBAAyB;IAMpC;;;;;;;;;OASG;IACH,YACE,QAAgB,EAChB,QAAgB,EAChB,YAAmC,EACnC,UAAkC,EAAE;QAEpC,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,EAAE;YAC3C,MAAM,IAAI,KAAK,CACb,6FAA6F,CAC9F,CAAC;SACH;QACD,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,QAAQ,GAAG,IAAI,mBAAmB,iCAClC,OAAO,KACV,MAAM,EACN,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ,EACvB,sBAAsB,EAAE,IAAI,CAAC,OAAO,EACpC,YAAY,IACZ,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,QAAQ,CAAC,MAAyB,EAAE,UAA2B,EAAE;QACrE,OAAO,aAAa,CAAC,QAAQ,CAC3B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,WAAW,EACnC,OAAO,EACP,KAAK,EAAE,UAAU,EAAE,EAAE;YACnB,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACzD,CAAC,CACF,CAAC;IACJ,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\n\nimport { credentialLogger } from \"../util/logging\";\nimport { tracingClient } from \"../util/tracing\";\nimport { MsalFlow } from \"../msal/flows\";\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { MsalClientAssertion } from \"../msal/nodeFlows/msalClientAssertion\";\n\nconst logger = credentialLogger(\"ClientAssertionCredential\");\n\n/**\n * Authenticates a service principal with a JWT assertion.\n */\nexport class ClientAssertionCredential implements TokenCredential {\n private msalFlow: MsalFlow;\n private tenantId: string;\n private clientId: string;\n private options: TokenCredentialOptions;\n\n /**\n * Creates an instance of the ClientAssertionCredential with the details\n * needed to authenticate against Azure Active Directory with a client\n * assertion provided by the developer through the `getAssertion` function parameter.\n *\n * @param tenantId - The Azure Active Directory tenant (directory) ID.\n * @param clientId - The client (application) ID of an App Registration in the tenant.\n * @param getAssertion - A function that retrieves the assertion for the credential to use.\n * @param options - Options for configuring the client which makes the authentication request.\n */\n constructor(\n tenantId: string,\n clientId: string,\n getAssertion: () => Promise<string>,\n options: TokenCredentialOptions = {}\n ) {\n if (!tenantId || !clientId || !getAssertion) {\n throw new Error(\n \"ClientAssertionCredential: tenantId, clientId, and clientAssertion are required parameters.\"\n );\n }\n this.tenantId = tenantId;\n this.clientId = clientId;\n this.options = options;\n this.msalFlow = new MsalClientAssertion({\n ...options,\n logger,\n clientId: this.clientId,\n tenantId: this.tenantId,\n tokenCredentialOptions: this.options,\n getAssertion,\n });\n }\n\n /**\n * Authenticates with Azure Active Directory and returns an access token if successful.\n * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n *\n * @param scopes - The list of scopes for which the token will have access.\n * @param options - The options used to configure any requests this\n * TokenCredential implementation might make.\n */\n async getToken(scopes: string | string[], options: GetTokenOptions = {}): Promise<AccessToken> {\n return tracingClient.withSpan(\n `${this.constructor.name}.getToken`,\n options,\n async (newOptions) => {\n const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];\n return this.msalFlow.getToken(arrayScopes, newOptions);\n }\n );\n }\n}\n"]}
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("ClientCertificateCredential is not supported in the browser.");
const logger = credentialLogger("ClientCertificateCredential");
/**
* Enables authentication to Azure Active Directory using a PEM-encoded
* certificate that is assigned to an App Registration.
*/
export class ClientCertificateCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=clientCertificateCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"clientCertificateCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/clientCertificateCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,8DAA8D,CAC/D,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,6BAA6B,CAAC,CAAC;AAE/D;;;GAGG;AACH,MAAM,OAAO,2BAA2B;IACtC;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"ClientCertificateCredential is not supported in the browser.\"\n);\nconst logger = credentialLogger(\"ClientCertificateCredential\");\n\n/**\n * Enables authentication to Azure Active Directory using a PEM-encoded\n * certificate that is assigned to an App Registration.\n */\nexport class ClientCertificateCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,55 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { MsalClientCertificate } from "../msal/nodeFlows/msalClientCertificate";
import { credentialLogger } from "../util/logging";
import { tracingClient } from "../util/tracing";
const credentialName = "ClientCertificateCredential";
const logger = credentialLogger(credentialName);
/**
* Enables authentication to Azure Active Directory using a PEM-encoded
* certificate that is assigned to an App Registration. More information
* on how to configure certificate authentication can be found here:
*
* https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials#register-your-certificate-with-azure-ad
*
*/
export class ClientCertificateCredential {
constructor(tenantId, clientId, certificatePathOrConfiguration, options = {}) {
if (!tenantId || !clientId) {
throw new Error(`${credentialName}: tenantId and clientId are required parameters.`);
}
const configuration = Object.assign({}, (typeof certificatePathOrConfiguration === "string"
? {
certificatePath: certificatePathOrConfiguration,
}
: certificatePathOrConfiguration));
const certificate = configuration
.certificate;
const certificatePath = configuration.certificatePath;
if (!configuration || !(certificate || certificatePath)) {
throw new Error(`${credentialName}: Provide either a PEM certificate in string form, or the path to that certificate in the filesystem. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
}
if (certificate && certificatePath) {
throw new Error(`${credentialName}: To avoid unexpected behaviors, providing both the contents of a PEM certificate and the path to a PEM certificate is forbidden. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
}
this.msalFlow = new MsalClientCertificate(Object.assign(Object.assign({}, options), { configuration,
logger,
clientId,
tenantId, sendCertificateChain: options.sendCertificateChain, tokenCredentialOptions: options }));
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, newOptions);
});
}
}
//# sourceMappingURL=clientCertificateCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=clientCertificateCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"clientCertificateCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/clientCertificateCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\n\n/**\n * Optional parameters for the {@link ClientCertificateCredential} class.\n */\nexport interface ClientCertificateCredentialOptions\n extends TokenCredentialOptions,\n CredentialPersistenceOptions {\n /**\n * Option to include x5c header for SubjectName and Issuer name authorization.\n * Set this option to send base64 encoded public certificate in the client assertion header as an x5c claim\n */\n sendCertificateChain?: boolean;\n // TODO: Export again once we're ready to release this feature.\n // /**\n // * Specifies a regional authority. Please refer to the {@link RegionalAuthority} type for the accepted values.\n // * If {@link RegionalAuthority.AutoDiscoverRegion} is specified, we will try to discover the regional authority endpoint.\n // * If the property is not specified, the credential uses the global authority endpoint.\n // */\n // regionalAuthority?: string;\n}\n"]}
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createHttpHeaders, createPipelineRequest } from "@azure/core-rest-pipeline";
import { credentialLogger, formatError, formatSuccess } from "../util/logging";
import { getIdentityTokenEndpointSuffix } from "../util/identityTokenEndpoint";
import { IdentityClient } from "../client/identityClient";
import { tracingClient } from "../util/tracing";
const logger = credentialLogger("ClientSecretCredential");
// This credential is exported on browser bundles for development purposes.
// For this credential to work in browsers, browsers would need to have security features disabled.
// Please do not disable your browser security features.
/**
* Enables authentication to Azure Active Directory using a client secret
* that was generated for an App Registration. More information on how
* to configure a client secret can be found here:
*
* https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-credentials-to-your-web-application
*
*/
export class ClientSecretCredential {
/**
* Creates an instance of the ClientSecretCredential with the details
* needed to authenticate against Azure Active Directory with a client
* secret.
*
* @param tenantId - The Azure Active Directory tenant (directory) ID.
* @param clientId - The client (application) ID of an App Registration in the tenant.
* @param clientSecret - A client secret that was generated for the App Registration.
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(tenantId, clientId, clientSecret, options) {
this.identityClient = new IdentityClient(options);
this.tenantId = tenantId;
this.clientId = clientId;
this.clientSecret = clientSecret;
}
/**
* Authenticates with Azure Active Directory and returns an access token if
* successful. If authentication cannot be performed at this time, this method may
* return null. If an error occurs during authentication, an {@link AuthenticationError}
* containing failure details will be thrown.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const query = new URLSearchParams({
response_type: "token",
grant_type: "client_credentials",
client_id: this.clientId,
client_secret: this.clientSecret,
scope: typeof scopes === "string" ? scopes : scopes.join(" "),
});
try {
const urlSuffix = getIdentityTokenEndpointSuffix(this.tenantId);
const request = createPipelineRequest({
url: `${this.identityClient.authorityHost}/${this.tenantId}/${urlSuffix}`,
method: "POST",
body: query.toString(),
headers: createHttpHeaders({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
}),
abortSignal: options && options.abortSignal,
tracingOptions: newOptions === null || newOptions === void 0 ? void 0 : newOptions.tracingOptions,
});
const tokenResponse = await this.identityClient.sendTokenRequest(request);
logger.getToken.info(formatSuccess(scopes));
return (tokenResponse && tokenResponse.accessToken) || null;
}
catch (err) {
logger.getToken.info(formatError(scopes, err));
throw err;
}
});
}
}
//# sourceMappingURL=clientSecretCredential.browser.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,50 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { MsalClientSecret } from "../msal/nodeFlows/msalClientSecret";
import { credentialLogger } from "../util/logging";
import { tracingClient } from "../util/tracing";
const logger = credentialLogger("ClientSecretCredential");
/**
* Enables authentication to Azure Active Directory using a client secret
* that was generated for an App Registration. More information on how
* to configure a client secret can be found here:
*
* https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-credentials-to-your-web-application
*
*/
export class ClientSecretCredential {
/**
* Creates an instance of the ClientSecretCredential with the details
* needed to authenticate against Azure Active Directory with a client
* secret.
*
* @param tenantId - The Azure Active Directory tenant (directory) ID.
* @param clientId - The client (application) ID of an App Registration in the tenant.
* @param clientSecret - A client secret that was generated for the App Registration.
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(tenantId, clientId, clientSecret, options = {}) {
if (!tenantId || !clientId || !clientSecret) {
throw new Error("ClientSecretCredential: tenantId, clientId, and clientSecret are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.");
}
this.msalFlow = new MsalClientSecret(Object.assign(Object.assign({}, options), { logger,
clientId,
tenantId,
clientSecret, tokenCredentialOptions: options }));
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, newOptions);
});
}
}
//# sourceMappingURL=clientSecretCredential.js.map
@@ -0,0 +1 @@
{"version":3,"file":"clientSecretCredential.js","sourceRoot":"","sources":["../../../src/credentials/clientSecretCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAIhD,MAAM,MAAM,GAAG,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,OAAO,sBAAsB;IAGjC;;;;;;;;;OASG;IACH,YACE,QAAgB,EAChB,QAAgB,EAChB,YAAoB,EACpB,UAAyC,EAAE;QAE3C,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,EAAE;YAC3C,MAAM,IAAI,KAAK,CACb,4LAA4L,CAC7L,CAAC;SACH;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,gBAAgB,iCAC/B,OAAO,KACV,MAAM;YACN,QAAQ;YACR,QAAQ;YACR,YAAY,EACZ,sBAAsB,EAAE,OAAO,IAC/B,CAAC;IACL,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,QAAQ,CAAC,MAAyB,EAAE,UAA2B,EAAE;QACrE,OAAO,aAAa,CAAC,QAAQ,CAC3B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,WAAW,EACnC,OAAO,EACP,KAAK,EAAE,UAAU,EAAE,EAAE;YACnB,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACzD,CAAC,CACF,CAAC;IACJ,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\n\nimport { MsalClientSecret } from \"../msal/nodeFlows/msalClientSecret\";\nimport { credentialLogger } from \"../util/logging\";\nimport { tracingClient } from \"../util/tracing\";\nimport { MsalFlow } from \"../msal/flows\";\nimport { ClientSecretCredentialOptions } from \"./clientSecretCredentialOptions\";\n\nconst logger = credentialLogger(\"ClientSecretCredential\");\n\n/**\n * Enables authentication to Azure Active Directory using a client secret\n * that was generated for an App Registration. More information on how\n * to configure a client secret can be found here:\n *\n * https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-credentials-to-your-web-application\n *\n */\nexport class ClientSecretCredential implements TokenCredential {\n private msalFlow: MsalFlow;\n\n /**\n * Creates an instance of the ClientSecretCredential with the details\n * needed to authenticate against Azure Active Directory with a client\n * secret.\n *\n * @param tenantId - The Azure Active Directory tenant (directory) ID.\n * @param clientId - The client (application) ID of an App Registration in the tenant.\n * @param clientSecret - A client secret that was generated for the App Registration.\n * @param options - Options for configuring the client which makes the authentication request.\n */\n constructor(\n tenantId: string,\n clientId: string,\n clientSecret: string,\n options: ClientSecretCredentialOptions = {}\n ) {\n if (!tenantId || !clientId || !clientSecret) {\n throw new Error(\n \"ClientSecretCredential: tenantId, clientId, and clientSecret are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.\"\n );\n }\n this.msalFlow = new MsalClientSecret({\n ...options,\n logger,\n clientId,\n tenantId,\n clientSecret,\n tokenCredentialOptions: options,\n });\n }\n\n /**\n * Authenticates with Azure Active Directory and returns an access token if successful.\n * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n *\n * @param scopes - The list of scopes for which the token will have access.\n * @param options - The options used to configure any requests this\n * TokenCredential implementation might make.\n */\n async getToken(scopes: string | string[], options: GetTokenOptions = {}): Promise<AccessToken> {\n return tracingClient.withSpan(\n `${this.constructor.name}.getToken`,\n options,\n async (newOptions) => {\n const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];\n return this.msalFlow.getToken(arrayScopes, newOptions);\n }\n );\n }\n}\n"]}
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=clientSecretCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"clientSecretCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/clientSecretCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\n\n/**\n * Optional parameters for the {@link ClientSecretCredential} class.\n */\nexport interface ClientSecretCredentialOptions\n extends TokenCredentialOptions,\n CredentialPersistenceOptions {\n // TODO: Export again once we're ready to release this feature.\n // /**\n // * Specifies a regional authority. Please refer to the {@link RegionalAuthority} type for the accepted values.\n // * If {@link RegionalAuthority.AutoDiscoverRegion} is specified, we will try to discover the regional authority endpoint.\n // * If the property is not specified, the credential uses the global authority endpoint.\n // */\n // regionalAuthority?: string;\n}\n"]}
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=credentialPersistenceOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"credentialPersistenceOptions.js","sourceRoot":"","sources":["../../../src/credentials/credentialPersistenceOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCachePersistenceOptions } from \"../msal/nodeFlows/tokenCachePersistenceOptions\";\n\n/**\n * Shared configuration options for credentials that support persistent token\n * caching.\n */\nexport interface CredentialPersistenceOptions {\n /**\n * Options to provide to the persistence layer (if one is available) when\n * storing credentials.\n *\n * You must first register a persistence provider plugin. See the\n * `@azure/identity-cache-persistence` package on NPM.\n *\n * Example:\n *\n * ```javascript\n * import { cachePersistencePlugin } from \"@azure/identity-cache-persistence\";\n * import { useIdentityPlugin, DeviceCodeCredential } from \"@azure/identity\";\n *\n * useIdentityPlugin(cachePersistencePlugin);\n *\n * async function main() {\n * const credential = new DeviceCodeCredential({\n * tokenCachePersistenceOptions: {\n * enabled: true\n * }\n * });\n * }\n *\n * main().catch((error) => {\n * console.error(\"An error occurred:\", error);\n * process.exit(1);\n * });\n * ```\n */\n\n tokenCachePersistenceOptions?: TokenCachePersistenceOptions;\n}\n"]}
@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
import { ChainedTokenCredential } from "./chainedTokenCredential";
const BrowserNotSupportedError = new Error("DefaultAzureCredential is not supported in the browser. Use InteractiveBrowserCredential instead.");
const logger = credentialLogger("DefaultAzureCredential");
/**
* Provides a default {@link ChainedTokenCredential} configuration for
* applications that will be deployed to Azure.
*
* Only available in Node.js.
*/
export class DefaultAzureCredential extends ChainedTokenCredential {
/**
* Creates an instance of the DefaultAzureCredential class.
*
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(_tokenCredentialOptions) {
super();
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=defaultAzureCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"defaultAzureCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/defaultAzureCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAElE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,mGAAmG,CACpG,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,OAAO,sBAAuB,SAAQ,sBAAsB;IAChE;;;;OAIG;IACH,YAAY,uBAAgD;QAC1D,KAAK,EAAE,CAAC;QACR,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken } from \"@azure/core-auth\";\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { credentialLogger, formatError } from \"../util/logging\";\nimport { ChainedTokenCredential } from \"./chainedTokenCredential\";\n\nconst BrowserNotSupportedError = new Error(\n \"DefaultAzureCredential is not supported in the browser. Use InteractiveBrowserCredential instead.\"\n);\nconst logger = credentialLogger(\"DefaultAzureCredential\");\n\n/**\n * Provides a default {@link ChainedTokenCredential} configuration for\n * applications that will be deployed to Azure.\n *\n * Only available in Node.js.\n */\nexport class DefaultAzureCredential extends ChainedTokenCredential {\n /**\n * Creates an instance of the DefaultAzureCredential class.\n *\n * @param options - Options for configuring the client which makes the authentication request.\n */\n constructor(_tokenCredentialOptions?: TokenCredentialOptions) {\n super();\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { ChainedTokenCredential } from "./chainedTokenCredential";
import { AzureCliCredential } from "./azureCliCredential";
import { AzurePowerShellCredential } from "./azurePowerShellCredential";
import { EnvironmentCredential } from "./environmentCredential";
import { ManagedIdentityCredential, } from "./managedIdentityCredential";
import { VisualStudioCodeCredential } from "./visualStudioCodeCredential";
/**
* A shim around ManagedIdentityCredential that adapts it to accept
* `DefaultAzureCredentialOptions`.
*
* @internal
*/
export class DefaultManagedIdentityCredential extends ManagedIdentityCredential {
// Constructor overload with just the other default options
// Last constructor overload with Union of all options not required since the above two constructor overloads have optional properties
constructor(options) {
var _a;
const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
const managedResourceId = options === null || options === void 0 ? void 0 : options.managedIdentityResourceId;
// ManagedIdentityCredential throws if both the resourceId and the clientId are provided.
if (managedResourceId) {
const managedIdentityResourceIdOptions = Object.assign(Object.assign({}, options), { resourceId: managedResourceId });
super(managedIdentityResourceIdOptions);
}
else if (managedIdentityClientId) {
const managedIdentityClientOptions = Object.assign(Object.assign({}, options), { clientId: managedIdentityClientId });
super(managedIdentityClientOptions);
}
else {
super(options);
}
}
}
export const defaultCredentials = [
EnvironmentCredential,
DefaultManagedIdentityCredential,
VisualStudioCodeCredential,
AzureCliCredential,
AzurePowerShellCredential,
];
/**
* Provides a default {@link ChainedTokenCredential} configuration that should
* work for most applications that use the Azure SDK.
*/
export class DefaultAzureCredential extends ChainedTokenCredential {
constructor(options) {
super(...defaultCredentials.map((ctor) => new ctor(options)));
this.UnavailableMessage =
"DefaultAzureCredential => failed to retrieve a token from the included credentials. To troubleshoot, visit https://aka.ms/azsdk/js/identity/defaultazurecredential/troubleshoot.";
}
}
//# sourceMappingURL=defaultAzureCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("DeviceCodeCredential is not supported in the browser.");
const logger = credentialLogger("DeviceCodeCredential");
/**
* Enables authentication to Azure Active Directory using a device code
* that the user can enter into https://microsoft.com/devicelogin.
*/
export class DeviceCodeCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=deviceCodeCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"deviceCodeCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/deviceCodeCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;AACpG,MAAM,MAAM,GAAG,gBAAgB,CAAC,sBAAsB,CAAC,CAAC;AAExD;;;GAGG;AACH,MAAM,OAAO,oBAAoB;IAC/B;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\"DeviceCodeCredential is not supported in the browser.\");\nconst logger = credentialLogger(\"DeviceCodeCredential\");\n\n/**\n * Enables authentication to Azure Active Directory using a device code\n * that the user can enter into https://microsoft.com/devicelogin.\n */\nexport class DeviceCodeCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,79 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger } from "../util/logging";
import { MsalDeviceCode } from "../msal/nodeFlows/msalDeviceCode";
import { tracingClient } from "../util/tracing";
const logger = credentialLogger("DeviceCodeCredential");
/**
* Method that logs the user code from the DeviceCodeCredential.
* @param deviceCodeInfo - The device code.
*/
export function defaultDeviceCodePromptCallback(deviceCodeInfo) {
console.log(deviceCodeInfo.message);
}
/**
* Enables authentication to Azure Active Directory using a device code
* that the user can enter into https://microsoft.com/devicelogin.
*/
export class DeviceCodeCredential {
/**
* Creates an instance of DeviceCodeCredential with the details needed
* to initiate the device code authorization flow with Azure Active Directory.
*
* A message will be logged, giving users a code that they can use to authenticate once they go to https://microsoft.com/devicelogin
*
* Developers can configure how this message is shown by passing a custom `userPromptCallback`:
*
* ```js
* const credential = new DeviceCodeCredential({
* tenantId: env.AZURE_TENANT_ID,
* clientId: env.AZURE_CLIENT_ID,
* userPromptCallback: (info) => {
* console.log("CUSTOMIZED PROMPT CALLBACK", info.message);
* }
* });
* ```
*
* @param options - Options for configuring the client which makes the authentication requests.
*/
constructor(options) {
this.msalFlow = new MsalDeviceCode(Object.assign(Object.assign({}, options), { logger, userPromptCallback: (options === null || options === void 0 ? void 0 : options.userPromptCallback) || defaultDeviceCodePromptCallback, tokenCredentialOptions: options || {} }));
this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the user provided the option `disableAutomaticAuthentication`,
* once the token can't be retrieved silently,
* this method won't attempt to request user interaction to retrieve the token.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
});
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the token can't be retrieved silently, this method will require user interaction to retrieve the token.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async authenticate(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.authenticate`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
await this.msalFlow.getToken(arrayScopes, newOptions);
return this.msalFlow.getActiveAccount();
});
}
}
//# sourceMappingURL=deviceCodeCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=deviceCodeCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"deviceCodeCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/deviceCodeCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { InteractiveCredentialOptions } from \"./interactiveCredentialOptions\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\n\n/**\n * Provides the user code and verification URI where the code must be\n * entered. Also provides a message to display to the user which\n * contains an instruction with these details.\n */\nexport interface DeviceCodeInfo {\n /**\n * The device code that the user must enter into the verification page.\n */\n userCode: string;\n\n /**\n * The verification URI to which the user must navigate to enter the device\n * code.\n */\n verificationUri: string;\n\n /**\n * A message that may be shown to the user to instruct them on how to enter\n * the device code in the page specified by the verification URI.\n */\n message: string;\n}\n\n/**\n * Defines the signature of a callback which will be passed to\n * DeviceCodeCredential for the purpose of displaying authentication\n * details to the user.\n */\nexport type DeviceCodePromptCallback = (deviceCodeInfo: DeviceCodeInfo) => void;\n\n/**\n * Defines options for the InteractiveBrowserCredential class for Node.js.\n */\nexport interface DeviceCodeCredentialOptions\n extends InteractiveCredentialOptions,\n CredentialPersistenceOptions {\n /**\n * The Azure Active Directory tenant (directory) ID.\n */\n tenantId?: string;\n /**\n * The client (application) ID of an App Registration in the tenant.\n */\n clientId?: string;\n /**\n * A callback function that will be invoked to show {@link DeviceCodeInfo} to the user.\n * If left unassigned, we will automatically log the device code information\n * and the authentication instructions in the console.\n */\n userPromptCallback?: DeviceCodePromptCallback;\n}\n"]}
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const BrowserNotSupportedError = new Error("EnvironmentCredential is not supported in the browser.");
const logger = credentialLogger("EnvironmentCredential");
/**
* Enables authentication to Azure Active Directory using client secret
* details configured in environment variables
*/
export class EnvironmentCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=environmentCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"environmentCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/environmentCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,wDAAwD,CACzD,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,uBAAuB,CAAC,CAAC;AAEzD;;;GAGG;AACH,MAAM,OAAO,qBAAqB;IAChC;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAED,QAAQ;QACN,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"EnvironmentCredential is not supported in the browser.\"\n);\nconst logger = credentialLogger(\"EnvironmentCredential\");\n\n/**\n * Enables authentication to Azure Active Directory using client secret\n * details configured in environment variables\n */\nexport class EnvironmentCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,106 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError, formatSuccess, processEnvVars } from "../util/logging";
import { ClientSecretCredential } from "./clientSecretCredential";
import { AuthenticationError, CredentialUnavailableError } from "../errors";
import { checkTenantId } from "../util/checkTenantId";
import { tracingClient } from "../util/tracing";
import { ClientCertificateCredential } from "./clientCertificateCredential";
import { UsernamePasswordCredential } from "./usernamePasswordCredential";
/**
* Contains the list of all supported environment variable names so that an
* appropriate error message can be generated when no credentials can be
* configured.
*
* @internal
*/
export const AllSupportedEnvironmentVariables = [
"AZURE_TENANT_ID",
"AZURE_CLIENT_ID",
"AZURE_CLIENT_SECRET",
"AZURE_CLIENT_CERTIFICATE_PATH",
"AZURE_USERNAME",
"AZURE_PASSWORD",
];
const credentialName = "EnvironmentCredential";
const logger = credentialLogger(credentialName);
/**
* Enables authentication to Azure Active Directory using client secret
* details configured in environment variables
*/
export class EnvironmentCredential {
/**
* Creates an instance of the EnvironmentCredential class and decides what credential to use depending on the available environment variables.
*
* Required environment variables:
* - `AZURE_TENANT_ID`: The Azure Active Directory tenant (directory) ID.
* - `AZURE_CLIENT_ID`: The client (application) ID of an App Registration in the tenant.
*
* Environment variables used for client credential authentication:
* - `AZURE_CLIENT_SECRET`: A client secret that was generated for the App Registration.
* - `AZURE_CLIENT_CERTIFICATE_PATH`: The path to a PEM certificate to use during the authentication, instead of the client secret.
*
* Alternatively, users can provide environment variables for username and password authentication:
* - `AZURE_USERNAME`: Username to authenticate with.
* - `AZURE_PASSWORD`: Password to authenticate with.
*
* If the environment variables required to perform the authentication are missing, a {@link CredentialUnavailableError} will be thrown.
* If the authentication fails, or if there's an unknown error, an {@link AuthenticationError} will be thrown.
*
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(options) {
// Keep track of any missing environment variables for error details
this._credential = undefined;
const assigned = processEnvVars(AllSupportedEnvironmentVariables).assigned.join(", ");
logger.info(`Found the following environment variables: ${assigned}`);
const tenantId = process.env.AZURE_TENANT_ID, clientId = process.env.AZURE_CLIENT_ID, clientSecret = process.env.AZURE_CLIENT_SECRET;
if (tenantId) {
checkTenantId(logger, tenantId);
}
if (tenantId && clientId && clientSecret) {
logger.info(`Invoking ClientSecretCredential with tenant ID: ${tenantId}, clientId: ${clientId} and clientSecret: [REDACTED]`);
this._credential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);
return;
}
const certificatePath = process.env.AZURE_CLIENT_CERTIFICATE_PATH;
if (tenantId && clientId && certificatePath) {
logger.info(`Invoking ClientCertificateCredential with tenant ID: ${tenantId}, clientId: ${clientId} and certificatePath: ${certificatePath}`);
this._credential = new ClientCertificateCredential(tenantId, clientId, { certificatePath }, options);
return;
}
const username = process.env.AZURE_USERNAME;
const password = process.env.AZURE_PASSWORD;
if (tenantId && clientId && username && password) {
logger.info(`Invoking UsernamePasswordCredential with tenant ID: ${tenantId}, clientId: ${clientId} and username: ${username}`);
this._credential = new UsernamePasswordCredential(tenantId, clientId, username, password, options);
}
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - Optional parameters. See {@link GetTokenOptions}.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => {
if (this._credential) {
try {
const result = await this._credential.getToken(scopes, newOptions);
logger.getToken.info(formatSuccess(scopes));
return result;
}
catch (err) {
const authenticationError = new AuthenticationError(400, {
error: `${credentialName} authentication failed. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`,
error_description: err.message.toString().split("More details:").join(""),
});
logger.getToken.info(formatError(scopes, authenticationError));
throw authenticationError;
}
}
throw new CredentialUnavailableError(`${credentialName} is unavailable. No underlying credential could be used. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot.`);
});
}
}
//# sourceMappingURL=environmentCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
import { tracingClient } from "../util/tracing";
import { MSALAuthCode } from "../msal/browserFlows/msalAuthCode";
const logger = credentialLogger("InteractiveBrowserCredential");
/**
* Enables authentication to Azure Active Directory inside of the web browser
* using the interactive login flow.
*/
export class InteractiveBrowserCredential {
/**
* Creates an instance of the InteractiveBrowserCredential with the
* details needed to authenticate against Azure Active Directory with
* a user identity.
*
* This credential uses the [Authorization Code Flow](https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow).
* On Node.js, it will open a browser window while it listens for a redirect response from the authentication service.
* On browsers, it authenticates via popups. The `loginStyle` optional parameter can be set to `redirect` to authenticate by redirecting the user to an Azure secure login page, which then will redirect the user back to the web application where the authentication started.
*
* It's recommended that the AAD Applications used are configured to authenticate using Single Page Applications.
* More information here: [link](https://docs.microsoft.com/en-us/azure/active-directory/develop/scenario-spa-app-registration#redirect-uri-msaljs-20-with-auth-code-flow).
*
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(options) {
if (!(options === null || options === void 0 ? void 0 : options.clientId)) {
const error = new Error("The parameter `clientId` cannot be left undefined for the `InteractiveBrowserCredential`");
logger.info(formatError("", error));
throw error;
}
const browserOptions = options;
const loginStyle = browserOptions.loginStyle || "popup";
const loginStyles = ["redirect", "popup"];
if (loginStyles.indexOf(loginStyle) === -1) {
const error = new Error(`Invalid loginStyle: ${browserOptions.loginStyle}. Should be any of the following: ${loginStyles.join(", ")}.`);
logger.info(formatError("", error));
throw error;
}
const msalOptions = Object.assign(Object.assign({}, options), { logger, loginStyle: loginStyle, redirectUri: typeof options.redirectUri === "function" ? options.redirectUri() : options.redirectUri });
this.msalFlow = new MSALAuthCode(msalOptions);
this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the user provided the option `disableAutomaticAuthentication`,
* once the token can't be retrieved silently,
* this method won't attempt to request user interaction to retrieve the token.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
});
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the token can't be retrieved silently, this method will require user interaction to retrieve the token.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async authenticate(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.authenticate`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
await this.msalFlow.getToken(arrayScopes, newOptions);
return this.msalFlow.getActiveAccount();
});
}
}
//# sourceMappingURL=interactiveBrowserCredential.browser.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,71 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger } from "../util/logging";
import { tracingClient } from "../util/tracing";
import { MsalOpenBrowser } from "../msal/nodeFlows/msalOpenBrowser";
const logger = credentialLogger("InteractiveBrowserCredential");
/**
* Enables authentication to Azure Active Directory inside of the web browser
* using the interactive login flow.
*/
export class InteractiveBrowserCredential {
/**
* Creates an instance of InteractiveBrowserCredential with the details needed.
*
* This credential uses the [Authorization Code Flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow).
* On Node.js, it will open a browser window while it listens for a redirect response from the authentication service.
* On browsers, it authenticates via popups. The `loginStyle` optional parameter can be set to `redirect` to authenticate by redirecting the user to an Azure secure login page, which then will redirect the user back to the web application where the authentication started.
*
* For Node.js, if a `clientId` is provided, the Azure Active Directory application will need to be configured to have a "Mobile and desktop applications" redirect endpoint.
* Follow our guide on [setting up Redirect URIs for Desktop apps that calls to web APIs](https://docs.microsoft.com/azure/active-directory/develop/scenario-desktop-app-registration#redirect-uris).
*
* @param options - Options for configuring the client which makes the authentication requests.
*/
constructor(options = {}) {
const redirectUri = typeof options.redirectUri === "function"
? options.redirectUri()
: options.redirectUri || "http://localhost";
this.msalFlow = new MsalOpenBrowser(Object.assign(Object.assign({}, options), { tokenCredentialOptions: options, logger,
redirectUri }));
this.disableAutomaticAuthentication = options === null || options === void 0 ? void 0 : options.disableAutomaticAuthentication;
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the user provided the option `disableAutomaticAuthentication`,
* once the token can't be retrieved silently,
* this method won't attempt to request user interaction to retrieve the token.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, Object.assign(Object.assign({}, newOptions), { disableAutomaticAuthentication: this.disableAutomaticAuthentication }));
});
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the token can't be retrieved silently, this method will require user interaction to retrieve the token.
*
* On Node.js, this credential has [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636) enabled by default.
* PKCE is a security feature that mitigates authentication code interception attacks.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async authenticate(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.authenticate`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
await this.msalFlow.getToken(arrayScopes, newOptions);
return this.msalFlow.getActiveAccount();
});
}
}
//# sourceMappingURL=interactiveBrowserCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=interactiveBrowserCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"interactiveBrowserCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/interactiveBrowserCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { InteractiveCredentialOptions } from \"./interactiveCredentialOptions\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\n\n/**\n * (Browser-only feature)\n * The \"login style\" to use in the authentication flow:\n * - \"redirect\" redirects the user to the authentication page and then\n * redirects them back to the page once authentication is completed.\n * - \"popup\" opens a new browser window through with the redirect flow\n * is initiated. The user's existing browser window does not leave\n * the current page\n */\nexport type BrowserLoginStyle = \"redirect\" | \"popup\";\n\n/**\n * Defines the common options for the InteractiveBrowserCredential class.\n */\nexport interface InteractiveBrowserCredentialNodeOptions\n extends InteractiveCredentialOptions,\n CredentialPersistenceOptions {\n /**\n * Gets the redirect URI of the application. This should be same as the value\n * in the application registration portal. Defaults to `window.location.href`.\n */\n redirectUri?: string | (() => string);\n\n /**\n * The Azure Active Directory tenant (directory) ID.\n */\n tenantId?: string;\n\n /**\n * The client (application) ID of an App Registration in the tenant.\n */\n clientId?: string;\n\n /**\n * loginHint allows a user name to be pre-selected for interactive logins.\n * Setting this option skips the account selection prompt and immediately attempts to login with the specified account.\n */\n loginHint?: string;\n}\n\n/**\n * Defines the common options for the InteractiveBrowserCredential class.\n */\nexport interface InteractiveBrowserCredentialInBrowserOptions extends InteractiveCredentialOptions {\n /**\n * Gets the redirect URI of the application. This should be same as the value\n * in the application registration portal. Defaults to `window.location.href`.\n */\n redirectUri?: string | (() => string);\n\n /**\n * The Azure Active Directory tenant (directory) ID.\n */\n tenantId?: string;\n\n /**\n * The client (application) ID of an App Registration in the tenant.\n * This parameter is required on the browser.\n */\n clientId: string;\n\n /**\n * Specifies whether a redirect or a popup window should be used to\n * initiate the user authentication flow. Possible values are \"redirect\"\n * or \"popup\" (default) for browser and \"popup\" (default) for node.\n *\n */\n loginStyle?: BrowserLoginStyle;\n\n /**\n * loginHint allows a user name to be pre-selected for interactive logins.\n * Setting this option skips the account selection prompt and immediately attempts to login with the specified account.\n */\n loginHint?: string;\n}\n"]}
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=interactiveCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"interactiveCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/interactiveCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { AuthenticationRecord } from \"../msal/types\";\n\n/**\n * Common constructor options for the Identity credentials that requires user interaction.\n */\nexport interface InteractiveCredentialOptions extends TokenCredentialOptions {\n /**\n * Result of a previous authentication that can be used to retrieve the cached credentials of each individual account.\n * This is necessary to provide in case the application wants to work with more than one account per\n * Client ID and Tenant ID pair.\n *\n * This record can be retrieved by calling to the credential's `authenticate()` method, as follows:\n *\n * const authenticationRecord = await credential.authenticate();\n *\n */\n authenticationRecord?: AuthenticationRecord;\n\n /**\n * Makes getToken throw if a manual authentication is necessary.\n * Developers will need to call to `authenticate()` to control when to manually authenticate.\n */\n disableAutomaticAuthentication?: boolean;\n}\n"]}
@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { credentialLogger } from "../../util/logging";
import { mapScopesToResource } from "./utils";
const msiName = "ManagedIdentityCredential - AppServiceMSI 2017";
const logger = credentialLogger(msiName);
/**
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
*/
function expiresOnParser(requestBody) {
// App Service always returns string expires_on values.
return Date.parse(requestBody.expires_on);
}
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId) {
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const queryParameters = {
resource,
"api-version": "2017-09-01",
};
if (clientId) {
queryParameters.clientid = clientId;
}
const query = new URLSearchParams(queryParameters);
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
if (!process.env.MSI_ENDPOINT) {
throw new Error(`${msiName}: Missing environment variable: MSI_ENDPOINT`);
}
if (!process.env.MSI_SECRET) {
throw new Error(`${msiName}: Missing environment variable: MSI_SECRET`);
}
return {
url: `${process.env.MSI_ENDPOINT}?${query.toString()}`,
method: "GET",
headers: createHttpHeaders({
Accept: "application/json",
secret: process.env.MSI_SECRET,
}),
};
}
/**
* Defines how to determine whether the Azure App Service MSI is available, and also how to retrieve a token from the Azure App Service MSI.
*/
export const appServiceMsi2017 = {
async isAvailable({ scopes }) {
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
const env = process.env;
const result = Boolean(env.MSI_ENDPOINT && env.MSI_SECRET);
if (!result) {
logger.info(`${msiName}: Unavailable. The environment variables needed are: MSI_ENDPOINT and MSI_SECRET.`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
const { identityClient, scopes, clientId, resourceId } = configuration;
if (resourceId) {
logger.warning(`${msiName}: managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
}
logger.info(`${msiName}: Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
const request = createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId)), {
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
allowInsecureConnection: true }));
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser);
return (tokenResponse && tokenResponse.accessToken) || null;
},
};
//# sourceMappingURL=appServiceMsi2017.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { credentialLogger } from "../../util/logging";
import { mapScopesToResource } from "./utils";
const msiName = "ManagedIdentityCredential - AppServiceMSI 2019";
const logger = credentialLogger(msiName);
/**
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
*/
function expiresOnParser(requestBody) {
// App Service always returns string expires_on values.
return Date.parse(requestBody.expires_on);
}
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId, resourceId) {
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const queryParameters = {
resource,
"api-version": "2019-08-01",
};
if (clientId) {
queryParameters.client_id = clientId;
}
if (resourceId) {
queryParameters.mi_res_id = resourceId;
}
const query = new URLSearchParams(queryParameters);
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
if (!process.env.IDENTITY_ENDPOINT) {
throw new Error(`${msiName}: Missing environment variable: IDENTITY_ENDPOINT`);
}
if (!process.env.IDENTITY_HEADER) {
throw new Error(`${msiName}: Missing environment variable: IDENTITY_HEADER`);
}
return {
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
method: "GET",
headers: createHttpHeaders({
Accept: "application/json",
"X-IDENTITY-HEADER": process.env.IDENTITY_HEADER,
}),
};
}
/**
* Defines how to determine whether the Azure App Service MSI is available, and also how to retrieve a token from the Azure App Service MSI.
*/
export const appServiceMsi2019 = {
async isAvailable({ scopes }) {
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
const env = process.env;
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
if (!result) {
logger.info(`${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
const { identityClient, scopes, clientId, resourceId } = configuration;
logger.info(`${msiName}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
const request = createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), {
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
allowInsecureConnection: true }));
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser);
return (tokenResponse && tokenResponse.accessToken) || null;
},
};
//# sourceMappingURL=appServiceMsi2019.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,116 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { readFile } from "fs";
import { AuthenticationError } from "../../errors";
import { credentialLogger } from "../../util/logging";
import { mapScopesToResource } from "./utils";
import { azureArcAPIVersion } from "./constants";
const msiName = "ManagedIdentityCredential - Azure Arc MSI";
const logger = credentialLogger(msiName);
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId, resourceId) {
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const queryParameters = {
resource,
"api-version": azureArcAPIVersion,
};
if (clientId) {
queryParameters.client_id = clientId;
}
if (resourceId) {
queryParameters.msi_res_id = resourceId;
}
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
if (!process.env.IDENTITY_ENDPOINT) {
throw new Error(`${msiName}: Missing environment variable: IDENTITY_ENDPOINT`);
}
const query = new URLSearchParams(queryParameters);
return createPipelineRequest({
// Should be similar to: http://localhost:40342/metadata/identity/oauth2/token
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
method: "GET",
headers: createHttpHeaders({
Accept: "application/json",
Metadata: "true",
}),
});
}
/**
* Retrieves the file contents at the given path using promises.
* Useful since `fs`'s readFileSync locks the thread, and to avoid extra dependencies.
*/
function readFileAsync(path, options) {
return new Promise((resolve, reject) => readFile(path, options, (err, data) => {
if (err) {
reject(err);
}
resolve(data);
}));
}
/**
* Does a request to the authentication provider that results in a file path.
*/
async function filePathRequest(identityClient, requestPrepareOptions) {
const response = await identityClient.sendRequest(createPipelineRequest(requestPrepareOptions));
if (response.status !== 401) {
let message = "";
if (response.bodyAsText) {
message = ` Response: ${response.bodyAsText}`;
}
throw new AuthenticationError(response.status, `${msiName}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`);
}
const authHeader = response.headers.get("www-authenticate") || "";
try {
return authHeader.split("=").slice(1)[0];
}
catch (e) {
throw Error(`Invalid www-authenticate header format: ${authHeader}`);
}
}
/**
* Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
*/
export const arcMsi = {
async isAvailable({ scopes }) {
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
if (!result) {
logger.info(`${msiName}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
var _a;
const { identityClient, scopes, clientId, resourceId } = configuration;
if (clientId) {
logger.warning(`${msiName}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
}
if (resourceId) {
logger.warning(`${msiName}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
}
logger.info(`${msiName}: Authenticating.`);
const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), { allowInsecureConnection: true });
const filePath = await filePathRequest(identityClient, requestOptions);
if (!filePath) {
throw new Error(`${msiName}: Failed to find the token file.`);
}
const key = await readFileAsync(filePath, { encoding: "utf-8" });
(_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
const request = createPipelineRequest(Object.assign(Object.assign({}, requestOptions), {
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
allowInsecureConnection: true }));
const tokenResponse = await identityClient.sendTokenRequest(request);
return (tokenResponse && tokenResponse.accessToken) || null;
},
};
//# sourceMappingURL=arcMsi.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,74 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { credentialLogger } from "../../util/logging";
import { mapScopesToResource } from "./utils";
const msiName = "ManagedIdentityCredential - CloudShellMSI";
export const logger = credentialLogger(msiName);
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId, resourceId) {
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const body = {
resource,
};
if (clientId) {
body.client_id = clientId;
}
if (resourceId) {
body.msi_res_id = resourceId;
}
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
if (!process.env.MSI_ENDPOINT) {
throw new Error(`${msiName}: Missing environment variable: MSI_ENDPOINT`);
}
const params = new URLSearchParams(body);
return {
url: process.env.MSI_ENDPOINT,
method: "POST",
body: params.toString(),
headers: createHttpHeaders({
Accept: "application/json",
Metadata: "true",
"Content-Type": "application/x-www-form-urlencoded",
}),
};
}
/**
* Defines how to determine whether the Azure Cloud Shell MSI is available, and also how to retrieve a token from the Azure Cloud Shell MSI.
* Since Azure Managed Identities aren't available in the Azure Cloud Shell, we log a warning for users that try to access cloud shell using user assigned identity.
*/
export const cloudShellMsi = {
async isAvailable({ scopes }) {
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
const result = Boolean(process.env.MSI_ENDPOINT);
if (!result) {
logger.info(`${msiName}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
const { identityClient, scopes, clientId, resourceId } = configuration;
if (clientId) {
logger.warning(`${msiName}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
}
if (resourceId) {
logger.warning(`${msiName}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
}
logger.info(`${msiName}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
const request = createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), {
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
allowInsecureConnection: true }));
const tokenResponse = await identityClient.sendTokenRequest(request);
return (tokenResponse && tokenResponse.accessToken) || null;
},
};
//# sourceMappingURL=cloudShellMsi.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,9 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export const DefaultScopeSuffix = "/.default";
export const imdsHost = "http://169.254.169.254";
export const imdsEndpointPath = "/metadata/identity/oauth2/token";
export const imdsApiVersion = "2018-02-01";
export const azureArcAPIVersion = "2019-11-01";
export const azureFabricVersion = "2019-07-01-preview";
//# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/constants.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAC9C,MAAM,CAAC,MAAM,QAAQ,GAAG,wBAAwB,CAAC;AACjD,MAAM,CAAC,MAAM,gBAAgB,GAAG,iCAAiC,CAAC;AAClE,MAAM,CAAC,MAAM,cAAc,GAAG,YAAY,CAAC;AAC3C,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAC/C,MAAM,CAAC,MAAM,kBAAkB,GAAG,oBAAoB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nexport const DefaultScopeSuffix = \"/.default\";\nexport const imdsHost = \"http://169.254.169.254\";\nexport const imdsEndpointPath = \"/metadata/identity/oauth2/token\";\nexport const imdsApiVersion = \"2018-02-01\";\nexport const azureArcAPIVersion = \"2019-11-01\";\nexport const azureFabricVersion = \"2019-07-01-preview\";\n"]}
@@ -0,0 +1,101 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import https from "https";
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { credentialLogger } from "../../util/logging";
import { mapScopesToResource } from "./utils";
import { azureFabricVersion } from "./constants";
// This MSI can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
//
// FROM node:12
// RUN wget https://host.any/path/bash.sh
// CMD ["bash", "bash.sh"]
//
// Where the bash script contains:
//
// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
//
const msiName = "ManagedIdentityCredential - Fabric MSI";
const logger = credentialLogger(msiName);
/**
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
*/
function expiresOnParser(requestBody) {
// Parses a string representation of the milliseconds since epoch into a number value
return Number(requestBody.expires_on);
}
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId, resourceId) {
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const queryParameters = {
resource,
"api-version": azureFabricVersion,
};
if (clientId) {
queryParameters.client_id = clientId;
}
if (resourceId) {
queryParameters.msi_res_id = resourceId;
}
const query = new URLSearchParams(queryParameters);
// This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
if (!process.env.IDENTITY_ENDPOINT) {
throw new Error("Missing environment variable: IDENTITY_ENDPOINT");
}
if (!process.env.IDENTITY_HEADER) {
throw new Error("Missing environment variable: IDENTITY_HEADER");
}
return {
url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
method: "GET",
headers: createHttpHeaders({
Accept: "application/json",
secret: process.env.IDENTITY_HEADER,
}),
};
}
/**
* Defines how to determine whether the Azure Service Fabric MSI is available, and also how to retrieve a token from the Azure Service Fabric MSI.
*/
export const fabricMsi = {
async isAvailable({ scopes }) {
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
const env = process.env;
const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
if (!result) {
logger.info(`${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
const { scopes, identityClient, clientId, resourceId } = configuration;
if (resourceId) {
logger.warning(`${msiName}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
}
logger.info([
`${msiName}:`,
"Using the endpoint and the secret coming from the environment variables:",
`IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
"IDENTITY_HEADER=[REDACTED] and",
"IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
].join(" "));
const request = createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)));
request.agent = new https.Agent({
// This is necessary because Service Fabric provides a self-signed certificate.
// The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
rejectUnauthorized: false,
});
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser);
return (tokenResponse && tokenResponse.accessToken) || null;
},
};
//# sourceMappingURL=fabricMsi.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,161 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { delay } from "@azure/core-util";
import { RestError, createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { credentialLogger } from "../../util/logging";
import { AuthenticationError } from "../../errors";
import { tracingClient } from "../../util/tracing";
import { imdsApiVersion, imdsEndpointPath, imdsHost } from "./constants";
import { mapScopesToResource } from "./utils";
const msiName = "ManagedIdentityCredential - IMDS";
const logger = credentialLogger(msiName);
/**
* Formats the expiration date of the received token into the number of milliseconds between that date and midnight, January 1, 1970.
*/
function expiresOnParser(requestBody) {
if (requestBody.expires_on) {
// Use the expires_on timestamp if it's available
const expires = +requestBody.expires_on * 1000;
logger.info(`${msiName}: Using expires_on: ${expires} (original value: ${requestBody.expires_on})`);
return expires;
}
else {
// If these aren't possible, use expires_in and calculate a timestamp
const expires = Date.now() + requestBody.expires_in * 1000;
logger.info(`${msiName}: IMDS using expires_in: ${expires} (original value: ${requestBody.expires_in})`);
return expires;
}
}
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId, resourceId, options) {
var _a;
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const { skipQuery, skipMetadataHeader } = options || {};
let query = "";
// Pod Identity will try to process this request even if the Metadata header is missing.
// We can exclude the request query to ensure no IMDS endpoint tries to process the ping request.
if (!skipQuery) {
const queryParameters = {
resource,
"api-version": imdsApiVersion,
};
if (clientId) {
queryParameters.client_id = clientId;
}
if (resourceId) {
queryParameters.msi_res_id = resourceId;
}
const params = new URLSearchParams(queryParameters);
query = `?${params.toString()}`;
}
const url = new URL(imdsEndpointPath, (_a = process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : imdsHost);
const rawHeaders = {
Accept: "application/json",
Metadata: "true",
};
// Remove the Metadata header to invoke a request error from some IMDS endpoints.
if (skipMetadataHeader) {
delete rawHeaders.Metadata;
}
return {
// In this case, the `?` should be added in the "query" variable `skipQuery` is not set.
url: `${url}${query}`,
method: "GET",
headers: createHttpHeaders(rawHeaders),
};
}
// 800ms -> 1600ms -> 3200ms
export const imdsMsiRetryConfig = {
maxRetries: 3,
startDelayInMs: 800,
intervalIncrement: 2,
};
/**
* Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
*/
export const imdsMsi = {
async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
// if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
return true;
}
if (!identityClient) {
throw new Error("Missing IdentityClient");
}
const requestOptions = prepareRequestOptions(resource, clientId, resourceId, {
skipMetadataHeader: true,
skipQuery: true,
});
return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions, async (options) => {
var _a, _b;
requestOptions.tracingOptions = options.tracingOptions;
try {
// Create a request with a timeout since we expect that
// not having a "Metadata" header should cause an error to be
// returned quickly from the endpoint, proving its availability.
const request = createPipelineRequest(requestOptions);
request.timeout = (_b = (_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) !== null && _b !== void 0 ? _b : 300;
// This MSI uses the imdsEndpoint to get the token, which only uses http://
request.allowInsecureConnection = true;
try {
logger.info(`${msiName}: Pinging the Azure IMDS endpoint`);
await identityClient.sendRequest(request);
}
catch (err) {
if ((err.name === "RestError" && err.code === RestError.REQUEST_SEND_ERROR) ||
err.name === "AbortError" ||
err.code === "ENETUNREACH" || // Network unreachable
err.code === "ECONNREFUSED" || // connection refused
err.code === "EHOSTDOWN" // host is down
) {
// If the request failed, or Node.js was unable to establish a connection,
// or the host was down, we'll assume the IMDS endpoint isn't available.
logger.info(`${msiName}: The Azure IMDS endpoint is unavailable`);
return false;
}
}
// If we received any response, the endpoint is available
logger.info(`${msiName}: The Azure IMDS endpoint is available`);
return true;
}
catch (err) {
// createWebResource failed.
// This error should bubble up to the user.
logger.info(`${msiName}: Error when creating the WebResource for the Azure IMDS endpoint: ${err.message}`);
throw err;
}
});
},
async getToken(configuration, getTokenOptions = {}) {
const { identityClient, scopes, clientId, resourceId } = configuration;
logger.info(`${msiName}: Using the Azure IMDS endpoint coming from the environment variable MSI_ENDPOINT=${process.env.MSI_ENDPOINT}, and using the cloud shell to proceed with the authentication.`);
let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
try {
const request = createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser);
return (tokenResponse && tokenResponse.accessToken) || null;
}
catch (error) {
if (error.statusCode === 404) {
await delay(nextDelayInMs);
nextDelayInMs *= imdsMsiRetryConfig.intervalIncrement;
continue;
}
throw error;
}
}
throw new AuthenticationError(404, `${msiName}: Failed to retrieve IMDS token after ${imdsMsiRetryConfig.maxRetries} retries.`);
},
};
//# sourceMappingURL=imdsMsi.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../../util/logging";
const BrowserNotSupportedError = new Error("ManagedIdentityCredential is not supported in the browser.");
const logger = credentialLogger("ManagedIdentityCredential");
export class ManagedIdentityCredential {
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
async getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=index.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"index.browser.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/index.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEnE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,4DAA4D,CAC7D,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,2BAA2B,CAAC,CAAC;AAE7D,MAAM,OAAO,yBAAyB;IAGpC;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,KAAK,CAAC,QAAQ;QACnB,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { TokenCredentialOptions } from \"../../tokenCredentialOptions\";\nimport { credentialLogger, formatError } from \"../../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\n \"ManagedIdentityCredential is not supported in the browser.\"\n);\nconst logger = credentialLogger(\"ManagedIdentityCredential\");\n\nexport class ManagedIdentityCredential implements TokenCredential {\n constructor(clientId: string, options?: TokenCredentialOptions);\n constructor(options?: TokenCredentialOptions);\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public async getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,194 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { IdentityClient } from "../../client/identityClient";
import { AuthenticationError, CredentialUnavailableError } from "../../errors";
import { credentialLogger, formatError, formatSuccess } from "../../util/logging";
import { appServiceMsi2017 } from "./appServiceMsi2017";
import { tracingClient } from "../../util/tracing";
import { cloudShellMsi } from "./cloudShellMsi";
import { imdsMsi } from "./imdsMsi";
import { arcMsi } from "./arcMsi";
import { tokenExchangeMsi } from "./tokenExchangeMsi";
import { fabricMsi } from "./fabricMsi";
import { appServiceMsi2019 } from "./appServiceMsi2019";
const logger = credentialLogger("ManagedIdentityCredential");
/**
* Attempts authentication using a managed identity available at the deployment environment.
* This authentication type works in Azure VMs, App Service instances, Azure Functions applications,
* Azure Kubernetes Services, Azure Service Fabric instances and inside of the Azure Cloud Shell.
*
* More information about configuring managed identities can be found here:
* https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
*/
export class ManagedIdentityCredential {
/**
* @internal
* @hidden
*/
constructor(clientIdOrOptions, options) {
this.isEndpointUnavailable = null;
let _options;
if (typeof clientIdOrOptions === "string") {
this.clientId = clientIdOrOptions;
_options = options;
}
else {
this.clientId = clientIdOrOptions === null || clientIdOrOptions === void 0 ? void 0 : clientIdOrOptions.clientId;
_options = clientIdOrOptions;
}
this.resourceId = _options === null || _options === void 0 ? void 0 : _options.resourceId;
// For JavaScript users.
if (this.clientId && this.resourceId) {
throw new Error(`${ManagedIdentityCredential.name} - Client Id and Resource Id can't be provided at the same time.`);
}
this.identityClient = new IdentityClient(_options);
this.isAvailableIdentityClient = new IdentityClient(Object.assign(Object.assign({}, _options), { retryOptions: {
maxRetries: 0,
} }));
}
async cachedAvailableMSI(scopes, getTokenOptions) {
if (this.cachedMSI) {
return this.cachedMSI;
}
const MSIs = [
arcMsi,
fabricMsi,
appServiceMsi2019,
appServiceMsi2017,
cloudShellMsi,
tokenExchangeMsi(),
imdsMsi,
];
for (const msi of MSIs) {
if (await msi.isAvailable({
scopes,
identityClient: this.isAvailableIdentityClient,
clientId: this.clientId,
resourceId: this.resourceId,
getTokenOptions,
})) {
this.cachedMSI = msi;
return msi;
}
}
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name} - No MSI credential available`);
}
async authenticateManagedIdentity(scopes, getTokenOptions) {
const { span, updatedOptions } = tracingClient.startSpan(`${ManagedIdentityCredential.name}.authenticateManagedIdentity`, getTokenOptions);
try {
// Determining the available MSI, and avoiding checking for other MSIs while the program is running.
const availableMSI = await this.cachedAvailableMSI(scopes, updatedOptions);
return availableMSI.getToken({
identityClient: this.identityClient,
scopes,
clientId: this.clientId,
resourceId: this.resourceId,
}, updatedOptions);
}
catch (err) {
span.setStatus({
status: "error",
error: err,
});
throw err;
}
finally {
span.end();
}
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
* If an unexpected error occurs, an {@link AuthenticationError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options) {
let result = null;
const { span, updatedOptions } = tracingClient.startSpan(`${ManagedIdentityCredential.name}.getToken`, options);
try {
// isEndpointAvailable can be true, false, or null,
// If it's null, it means we don't yet know whether
// the endpoint is available and need to check for it.
if (this.isEndpointUnavailable !== true) {
result = await this.authenticateManagedIdentity(scopes, updatedOptions);
if (result === null) {
// If authenticateManagedIdentity returns null,
// it means no MSI endpoints are available.
// If so, we avoid trying to reach to them in future requests.
this.isEndpointUnavailable = true;
// It also means that the endpoint answered with either 200 or 201 (see the sendTokenRequest method),
// yet we had no access token. For this reason, we'll throw once with a specific message:
const error = new CredentialUnavailableError("The managed identity endpoint was reached, yet no tokens were received.");
logger.getToken.info(formatError(scopes, error));
throw error;
}
// Since `authenticateManagedIdentity` didn't throw, and the result was not null,
// We will assume that this endpoint is reachable from this point forward,
// and avoid pinging again to it.
this.isEndpointUnavailable = false;
}
else {
// We've previously determined that the endpoint was unavailable,
// either because it was unreachable or permanently unable to authenticate.
const error = new CredentialUnavailableError("The managed identity endpoint is not currently available");
logger.getToken.info(formatError(scopes, error));
throw error;
}
logger.getToken.info(formatSuccess(scopes));
return result;
}
catch (err) {
// CredentialUnavailable errors are expected to reach here.
// We intend them to bubble up, so that DefaultAzureCredential can catch them.
if (err.name === "AuthenticationRequiredError") {
throw err;
}
// Expected errors to reach this point:
// - Errors coming from a method unexpectedly breaking.
// - When identityClient.sendTokenRequest throws, in which case
// if the status code was 400, it means that the endpoint is working,
// but no identity is available.
span.setStatus({
status: "error",
error: err,
});
// If either the network is unreachable,
// we can safely assume the credential is unavailable.
if (err.code === "ENETUNREACH") {
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. Network unreachable. Message: ${err.message}`);
logger.getToken.info(formatError(scopes, error));
throw error;
}
// If either the host was unreachable,
// we can safely assume the credential is unavailable.
if (err.code === "EHOSTUNREACH") {
const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. No managed identity endpoint found. Message: ${err.message}`);
logger.getToken.info(formatError(scopes, error));
throw error;
}
// If err.statusCode has a value of 400, it comes from sendTokenRequest,
// and it means that the endpoint is working, but that no identity is available.
if (err.statusCode === 400) {
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name}: The managed identity endpoint is indicating there's no available identity. Message: ${err.message}`);
}
// If the error has no status code, we can assume there was no available identity.
// This will throw silently during any ChainedTokenCredential.
if (err.statusCode === undefined) {
throw new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Authentication failed. Message ${err.message}`);
}
// Any other error should break the chain.
throw new AuthenticationError(err.statusCode, {
error: `${ManagedIdentityCredential.name} authentication failed.`,
error_description: err.message,
});
}
finally {
// Finally is always called, both if we return and if we throw in the above try/catch.
span.end();
}
}
}
//# sourceMappingURL=index.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/models.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { IdentityClient, TokenResponseParsedBody } from \"../../client/identityClient\";\n\n/**\n * @internal\n */\nexport type MSIExpiresInParser = (requestBody: TokenResponseParsedBody) => number;\n\n/**\n * @internal\n */\nexport interface MSIConfiguration {\n identityClient: IdentityClient;\n scopes: string | string[];\n clientId?: string;\n resourceId?: string;\n}\n\n/**\n * @internal\n */\nexport interface MSI {\n isAvailable(options: {\n scopes: string | string[];\n identityClient?: IdentityClient;\n clientId?: string;\n resourceId?: string;\n getTokenOptions?: GetTokenOptions;\n }): Promise<boolean>;\n getToken(\n configuration: MSIConfiguration,\n getTokenOptions?: GetTokenOptions\n ): Promise<AccessToken | null>;\n}\n"]}
@@ -0,0 +1,87 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import fs from "fs";
import { createHttpHeaders, createPipelineRequest, } from "@azure/core-rest-pipeline";
import { promisify } from "util";
import { DefaultAuthorityHost } from "../../constants";
import { credentialLogger } from "../../util/logging";
const msiName = "ManagedIdentityCredential - Token Exchange";
const logger = credentialLogger(msiName);
const readFileAsync = promisify(fs.readFile);
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientAssertion, clientId) {
var _a;
const bodyParams = {
scope: Array.isArray(scopes) ? scopes.join(" ") : scopes,
client_assertion: clientAssertion,
client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
client_id: clientId,
grant_type: "client_credentials",
};
const urlParams = new URLSearchParams(bodyParams);
const url = new URL(`${process.env.AZURE_TENANT_ID}/oauth2/v2.0/token`, (_a = process.env.AZURE_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : DefaultAuthorityHost);
return {
url: url.toString(),
method: "POST",
body: urlParams.toString(),
headers: createHttpHeaders({
Accept: "application/json",
}),
};
}
/**
* Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
*/
export function tokenExchangeMsi() {
const azureFederatedTokenFilePath = process.env.AZURE_FEDERATED_TOKEN_FILE;
let azureFederatedTokenFileContent = undefined;
let cacheDate = undefined;
// Only reads from the assertion file once every 5 minutes
async function readAssertion() {
// Cached assertions expire after 5 minutes
if (cacheDate !== undefined && Date.now() - cacheDate >= 1000 * 60 * 5) {
azureFederatedTokenFileContent = undefined;
}
if (!azureFederatedTokenFileContent) {
const file = await readFileAsync(azureFederatedTokenFilePath, "utf8");
const value = file.trim();
if (!value) {
throw new Error(`No content on the file ${azureFederatedTokenFilePath}, indicated by the environment variable AZURE_FEDERATED_TOKEN_FILE`);
}
else {
azureFederatedTokenFileContent = value;
cacheDate = Date.now();
}
}
return azureFederatedTokenFileContent;
}
return {
async isAvailable({ clientId }) {
const env = process.env;
const result = Boolean((clientId || env.AZURE_CLIENT_ID) && env.AZURE_TENANT_ID && azureFederatedTokenFilePath);
if (!result) {
logger.info(`${msiName}: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
const { identityClient, scopes, clientId } = configuration;
logger.info(`${msiName}: Using the client assertion coming from environment variables.`);
let assertion;
try {
assertion = await readAssertion();
}
catch (err) {
throw new Error(`${msiName}: Failed to read ${azureFederatedTokenFilePath}, indicated by the environment variable AZURE_FEDERATED_TOKEN_FILE`);
}
const request = createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, assertion, clientId || process.env.AZURE_CLIENT_ID)), {
// Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
allowInsecureConnection: true }));
const tokenResponse = await identityClient.sendTokenRequest(request);
return (tokenResponse && tokenResponse.accessToken) || null;
},
};
}
//# sourceMappingURL=tokenExchangeMsi.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { DefaultScopeSuffix } from "./constants";
/**
* Most MSIs send requests to the IMDS endpoint, or a similar endpoint.
* These are GET requests that require sending a `resource` parameter on the query.
* This resource can be derived from the scopes received through the getToken call, as long as only one scope is received.
* Multiple scopes assume that the resulting token will have access to multiple resources, which won't be the case.
*
* For that reason, when we encounter multiple scopes, we return undefined.
* It's up to the individual MSI implementations to throw the errors (which helps us provide less generic errors).
*/
export function mapScopesToResource(scopes) {
let scope = "";
if (Array.isArray(scopes)) {
if (scopes.length !== 1) {
return;
}
scope = scopes[0];
}
else if (typeof scopes === "string") {
scope = scopes;
}
if (!scope.endsWith(DefaultScopeSuffix)) {
return scope;
}
return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));
}
//# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/utils.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAyB;IAC3D,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACzB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;YACvB,OAAO;SACR;QAED,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;KACnB;SAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;QACrC,KAAK,GAAG,MAAM,CAAC;KAChB;IAED,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE;QACvC,OAAO,KAAK,CAAC;KACd;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAChE,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { DefaultScopeSuffix } from \"./constants\";\n\n/**\n * Most MSIs send requests to the IMDS endpoint, or a similar endpoint.\n * These are GET requests that require sending a `resource` parameter on the query.\n * This resource can be derived from the scopes received through the getToken call, as long as only one scope is received.\n * Multiple scopes assume that the resulting token will have access to multiple resources, which won't be the case.\n *\n * For that reason, when we encounter multiple scopes, we return undefined.\n * It's up to the individual MSI implementations to throw the errors (which helps us provide less generic errors).\n */\nexport function mapScopesToResource(scopes: string | string[]): string | undefined {\n let scope = \"\";\n if (Array.isArray(scopes)) {\n if (scopes.length !== 1) {\n return;\n }\n\n scope = scopes[0];\n } else if (typeof scopes === \"string\") {\n scope = scopes;\n }\n\n if (!scope.endsWith(DefaultScopeSuffix)) {\n return scope;\n }\n\n return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));\n}\n"]}
@@ -0,0 +1,23 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger, formatError } from "../util/logging";
const credentialName = "OnBehalfOfCredential";
const BrowserNotSupportedError = new Error(`${credentialName}: Not supported in the browser.`);
const logger = credentialLogger(credentialName);
/**
* Enables authentication to Azure Active Directory using the [On Behalf Of flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).
*/
export class OnBehalfOfCredential {
/**
* Only available in Node.js
*/
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=onBehalfOfCredential.browser.js.map
@@ -0,0 +1 @@
{"version":3,"file":"onBehalfOfCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/onBehalfOfCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEhE,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAC9C,MAAM,wBAAwB,GAAG,IAAI,KAAK,CAAC,GAAG,cAAc,iCAAiC,CAAC,CAAC;AAC/F,MAAM,MAAM,GAAG,gBAAgB,CAAC,cAAc,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,OAAO,oBAAoB;IAC/B;;OAEG;IACH;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,QAAQ;QACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential } from \"@azure/core-auth\";\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst credentialName = \"OnBehalfOfCredential\";\nconst BrowserNotSupportedError = new Error(`${credentialName}: Not supported in the browser.`);\nconst logger = credentialLogger(credentialName);\n\n/**\n * Enables authentication to Azure Active Directory using the [On Behalf Of flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).\n */\nexport class OnBehalfOfCredential implements TokenCredential {\n /**\n * Only available in Node.js\n */\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { MsalOnBehalfOf } from "../msal/nodeFlows/msalOnBehalfOf";
import { credentialLogger } from "../util/logging";
import { tracingClient } from "../util/tracing";
const credentialName = "OnBehalfOfCredential";
const logger = credentialLogger(credentialName);
/**
* Enables authentication to Azure Active Directory using the [On Behalf Of flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-on-behalf-of-flow).
*/
export class OnBehalfOfCredential {
constructor(options) {
this.options = options;
const { clientSecret } = options;
const { certificatePath } = options;
const { tenantId, clientId, userAssertionToken } = options;
if (!tenantId || !clientId || !(clientSecret || certificatePath) || !userAssertionToken) {
throw new Error(`${credentialName}: tenantId, clientId, clientSecret (or certificatePath) and userAssertionToken are required parameters.`);
}
this.msalFlow = new MsalOnBehalfOf(Object.assign(Object.assign({}, this.options), { logger, tokenCredentialOptions: this.options }));
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure the underlying network requests.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, newOptions);
});
}
}
//# sourceMappingURL=onBehalfOfCredential.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
export {};
//# sourceMappingURL=onBehalfOfCredentialOptions.js.map
@@ -0,0 +1 @@
{"version":3,"file":"onBehalfOfCredentialOptions.js","sourceRoot":"","sources":["../../../src/credentials/onBehalfOfCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredentialOptions } from \"../tokenCredentialOptions\";\nimport { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\n\n/**\n * Defines the parameters to authenticate the {@link OnBehalfOfCredential} with a secret.\n */\nexport interface OnBehalfOfCredentialSecretOptions {\n /**\n * The Azure Active Directory tenant (directory) ID.\n */\n tenantId: string;\n /**\n * The client (application) ID of an App Registration in the tenant.\n */\n clientId: string;\n /**\n * A client secret that was generated for the App Registration.\n */\n clientSecret: string;\n /**\n * The user assertion for the On-Behalf-Of flow.\n */\n userAssertionToken: string;\n}\n\n/**\n * Defines the parameters to authenticate the {@link OnBehalfOfCredential} with a certificate.\n */\nexport interface OnBehalfOfCredentialCertificateOptions {\n /**\n * The Azure Active Directory tenant (directory) ID.\n */\n tenantId: string;\n /**\n * The client (application) ID of an App Registration in the tenant.\n */\n clientId: string;\n /**\n * The path to a PEM-encoded public/private key certificate on the filesystem.\n */\n certificatePath: string;\n /**\n * The user assertion for the On-Behalf-Of flow.\n */\n userAssertionToken: string;\n /**\n * Option to include x5c header for SubjectName and Issuer name authorization.\n * Set this option to send base64 encoded public certificate in the client assertion header as an x5c claim\n */\n sendCertificateChain?: boolean;\n}\n\n/**\n * Optional parameters for the {@link OnBehalfOfCredential} class.\n */\nexport type OnBehalfOfCredentialOptions = (\n | OnBehalfOfCredentialSecretOptions\n | OnBehalfOfCredentialCertificateOptions\n) &\n TokenCredentialOptions &\n CredentialPersistenceOptions;\n"]}
@@ -0,0 +1,86 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { createHttpHeaders, createPipelineRequest } from "@azure/core-rest-pipeline";
import { IdentityClient } from "../client/identityClient";
import { credentialLogger, formatError, formatSuccess } from "../util/logging";
import { getIdentityTokenEndpointSuffix } from "../util/identityTokenEndpoint";
import { tracingClient } from "../util/tracing";
import { checkTenantId } from "../util/checkTenantId";
const logger = credentialLogger("UsernamePasswordCredential");
/**
* Enables authentication to Azure Active Directory with a user's
* username and password. This credential requires a high degree of
* trust so you should only use it when other, more secure credential
* types can't be used.
*/
export class UsernamePasswordCredential {
/**
* Creates an instance of the UsernamePasswordCredential with the details
* needed to authenticate against Azure Active Directory with a username
* and password.
*
* @param tenantIdOrName - The Azure Active Directory tenant (directory) ID or name.
* @param clientId - The client (application) ID of an App Registration in the tenant.
* @param username - The user account's e-mail address (user name).
* @param password - The user account's account password
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(tenantIdOrName, clientId, username, password, options) {
checkTenantId(logger, tenantIdOrName);
this.identityClient = new IdentityClient(options);
this.tenantId = tenantIdOrName;
this.clientId = clientId;
this.username = username;
this.password = password;
}
/**
* Authenticates with Azure Active Directory and returns an access token if
* successful. If authentication cannot be performed at this time, this method may
* return null. If an error occurs during authentication, an {@link AuthenticationError}
* containing failure details will be thrown.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options) {
const { span, updatedOptions: newOptions } = tracingClient.startSpan("UsernamePasswordCredential.getToken", options);
try {
const urlSuffix = getIdentityTokenEndpointSuffix(this.tenantId);
const params = new URLSearchParams({
response_type: "token",
grant_type: "password",
client_id: this.clientId,
username: this.username,
password: this.password,
scope: typeof scopes === "string" ? scopes : scopes.join(" "),
});
const webResource = createPipelineRequest({
url: `${this.identityClient.authorityHost}/${this.tenantId}/${urlSuffix}`,
method: "POST",
body: params.toString(),
headers: createHttpHeaders({
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded",
}),
abortSignal: options && options.abortSignal,
tracingOptions: newOptions.tracingOptions,
});
const tokenResponse = await this.identityClient.sendTokenRequest(webResource);
logger.getToken.info(formatSuccess(scopes));
return (tokenResponse && tokenResponse.accessToken) || null;
}
catch (err) {
span.setStatus({
status: "error",
error: err,
});
logger.getToken.info(formatError(scopes, err));
throw err;
}
finally {
span.end();
}
}
}
//# sourceMappingURL=usernamePasswordCredential.browser.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,54 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
import { credentialLogger } from "../util/logging";
import { MsalUsernamePassword } from "../msal/nodeFlows/msalUsernamePassword";
import { tracingClient } from "../util/tracing";
const logger = credentialLogger("UsernamePasswordCredential");
/**
* Enables authentication to Azure Active Directory with a user's
* username and password. This credential requires a high degree of
* trust so you should only use it when other, more secure credential
* types can't be used.
*/
export class UsernamePasswordCredential {
/**
* Creates an instance of the UsernamePasswordCredential with the details
* needed to authenticate against Azure Active Directory with a username
* and password.
*
* @param tenantId - The Azure Active Directory tenant (directory).
* @param clientId - The client (application) ID of an App Registration in the tenant.
* @param username - The user account's e-mail address (user name).
* @param password - The user account's account password
* @param options - Options for configuring the client which makes the authentication request.
*/
constructor(tenantId, clientId, username, password, options = {}) {
if (!tenantId || !clientId || !username || !password) {
throw new Error("UsernamePasswordCredential: tenantId, clientId, username and password are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot.");
}
this.msalFlow = new MsalUsernamePassword(Object.assign(Object.assign({}, options), { logger,
clientId,
tenantId,
username,
password, tokenCredentialOptions: options || {} }));
}
/**
* Authenticates with Azure Active Directory and returns an access token if successful.
* If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
*
* If the user provided the option `disableAutomaticAuthentication`,
* once the token can't be retrieved silently,
* this method won't attempt to request user interaction to retrieve the token.
*
* @param scopes - The list of scopes for which the token will have access.
* @param options - The options used to configure any requests this
* TokenCredential implementation might make.
*/
async getToken(scopes, options = {}) {
return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
return this.msalFlow.getToken(arrayScopes, newOptions);
});
}
}
//# sourceMappingURL=usernamePasswordCredential.js.map
@@ -0,0 +1 @@
{"version":3,"file":"usernamePasswordCredential.js","sourceRoot":"","sources":["../../../src/credentials/usernamePasswordCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAE9E,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,MAAM,MAAM,GAAG,gBAAgB,CAAC,4BAA4B,CAAC,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,OAAO,0BAA0B;IAGrC;;;;;;;;;;OAUG;IACH,YACE,QAAgB,EAChB,QAAgB,EAChB,QAAgB,EAChB,QAAgB,EAChB,UAA6C,EAAE;QAE/C,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,IAAI,CAAC,QAAQ,EAAE;YACpD,MAAM,IAAI,KAAK,CACb,iMAAiM,CAClM,CAAC;SACH;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,oBAAoB,iCACnC,OAAO,KACV,MAAM;YACN,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,QAAQ,EACR,sBAAsB,EAAE,OAAO,IAAI,EAAE,IACrC,CAAC;IACL,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,QAAQ,CAAC,MAAyB,EAAE,UAA2B,EAAE;QACrE,OAAO,aAAa,CAAC,QAAQ,CAC3B,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,WAAW,EACnC,OAAO,EACP,KAAK,EAAE,UAAU,EAAE,EAAE;YACnB,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC9D,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;QACzD,CAAC,CACF,CAAC;IACJ,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\n\nimport { credentialLogger } from \"../util/logging\";\nimport { MsalUsernamePassword } from \"../msal/nodeFlows/msalUsernamePassword\";\nimport { MsalFlow } from \"../msal/flows\";\nimport { tracingClient } from \"../util/tracing\";\nimport { UsernamePasswordCredentialOptions } from \"./usernamePasswordCredentialOptions\";\n\nconst logger = credentialLogger(\"UsernamePasswordCredential\");\n\n/**\n * Enables authentication to Azure Active Directory with a user's\n * username and password. This credential requires a high degree of\n * trust so you should only use it when other, more secure credential\n * types can't be used.\n */\nexport class UsernamePasswordCredential implements TokenCredential {\n private msalFlow: MsalFlow;\n\n /**\n * Creates an instance of the UsernamePasswordCredential with the details\n * needed to authenticate against Azure Active Directory with a username\n * and password.\n *\n * @param tenantId - The Azure Active Directory tenant (directory).\n * @param clientId - The client (application) ID of an App Registration in the tenant.\n * @param username - The user account's e-mail address (user name).\n * @param password - The user account's account password\n * @param options - Options for configuring the client which makes the authentication request.\n */\n constructor(\n tenantId: string,\n clientId: string,\n username: string,\n password: string,\n options: UsernamePasswordCredentialOptions = {}\n ) {\n if (!tenantId || !clientId || !username || !password) {\n throw new Error(\n \"UsernamePasswordCredential: tenantId, clientId, username and password are required parameters. To troubleshoot, visit https://aka.ms/azsdk/js/identity/usernamepasswordcredential/troubleshoot.\"\n );\n }\n this.msalFlow = new MsalUsernamePassword({\n ...options,\n logger,\n clientId,\n tenantId,\n username,\n password,\n tokenCredentialOptions: options || {},\n });\n }\n\n /**\n * Authenticates with Azure Active Directory and returns an access token if successful.\n * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n *\n * If the user provided the option `disableAutomaticAuthentication`,\n * once the token can't be retrieved silently,\n * this method won't attempt to request user interaction to retrieve the token.\n *\n * @param scopes - The list of scopes for which the token will have access.\n * @param options - The options used to configure any requests this\n * TokenCredential implementation might make.\n */\n async getToken(scopes: string | string[], options: GetTokenOptions = {}): Promise<AccessToken> {\n return tracingClient.withSpan(\n `${this.constructor.name}.getToken`,\n options,\n async (newOptions) => {\n const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];\n return this.msalFlow.getToken(arrayScopes, newOptions);\n }\n );\n }\n}\n"]}

Some files were not shown because too many files have changed in this diff Show More