@azure/identity 1.2.0-beta.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of @azure/identity might be problematic. Click here for more details.
- package/CHANGELOG.md +24 -2
- package/README.md +75 -55
- package/dist/index.js +533 -396
- package/dist/index.js.map +1 -1
- package/dist-esm/src/client/msalClient.js +138 -0
- package/dist-esm/src/client/msalClient.js.map +1 -0
- package/dist-esm/src/credentials/authorizationCodeCredential.browser.js +2 -2
- package/dist-esm/src/credentials/authorizationCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.js +3 -1
- package/dist-esm/src/credentials/authorizationCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/azureCliCredential.browser.js +2 -2
- package/dist-esm/src/credentials/azureCliCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/azureCliCredential.js +5 -5
- package/dist-esm/src/credentials/azureCliCredential.js.map +1 -1
- package/dist-esm/src/credentials/chainedTokenCredential.js +2 -2
- package/dist-esm/src/credentials/chainedTokenCredential.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredential.browser.js +2 -2
- package/dist-esm/src/credentials/clientCertificateCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredential.js +5 -3
- package/dist-esm/src/credentials/clientCertificateCredential.js.map +1 -1
- package/dist-esm/src/credentials/clientCertificateCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/clientSecretCredential.js +2 -2
- package/dist-esm/src/credentials/clientSecretCredential.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.browser.js +2 -2
- package/dist-esm/src/credentials/deviceCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/deviceCodeCredential.js +53 -47
- package/dist-esm/src/credentials/deviceCodeCredential.js.map +1 -1
- package/dist-esm/src/credentials/environmentCredential.browser.js +2 -2
- package/dist-esm/src/credentials/environmentCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/environmentCredential.js +6 -2
- package/dist-esm/src/credentials/environmentCredential.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js +7 -5
- package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredential.js +30 -69
- package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -1
- package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.js.map +1 -1
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js +44 -0
- package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +74 -0
- package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js +41 -0
- package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/constants.js +8 -0
- package/dist-esm/src/credentials/managedIdentityCredential/constants.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js +59 -0
- package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +109 -0
- package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -0
- package/dist-esm/src/credentials/{managedIdentityCredential.browser.js → managedIdentityCredential/index.browser.js} +4 -4
- package/dist-esm/src/credentials/managedIdentityCredential/index.browser.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/index.js +165 -0
- package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/models.js +3 -0
- package/dist-esm/src/credentials/managedIdentityCredential/models.js.map +1 -0
- package/dist-esm/src/credentials/managedIdentityCredential/utils.js +28 -0
- package/dist-esm/src/credentials/managedIdentityCredential/utils.js.map +1 -0
- package/dist-esm/src/credentials/usernamePasswordCredential.js +3 -1
- package/dist-esm/src/credentials/usernamePasswordCredential.js.map +1 -1
- package/dist-esm/src/credentials/visualStudioCodeCredential.browser.js +2 -2
- package/dist-esm/src/credentials/visualStudioCodeCredential.browser.js.map +1 -1
- package/dist-esm/src/credentials/visualStudioCodeCredential.js +19 -8
- package/dist-esm/src/credentials/visualStudioCodeCredential.js.map +1 -1
- package/dist-esm/src/index.js.map +1 -1
- package/dist-esm/src/util/checkTenantId.js +11 -0
- package/dist-esm/src/util/checkTenantId.js.map +1 -0
- package/dist-esm/src/util/logging.js +7 -3
- package/dist-esm/src/util/logging.js.map +1 -1
- package/package.json +7 -5
- package/types/identity.d.ts +9 -33
- package/dist-esm/src/credentials/managedIdentityCredential.browser.js.map +0 -1
- package/dist-esm/src/credentials/managedIdentityCredential.js +0 -376
- package/dist-esm/src/credentials/managedIdentityCredential.js.map +0 -1
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
// Copyright (c) Microsoft Corporation.
|
|
2
|
+
// Licensed under the MIT license.
|
|
3
|
+
import { __awaiter } from "tslib";
|
|
4
|
+
import { CredentialUnavailable } from "./errors";
|
|
5
|
+
import { PublicClientApplication } from "@azure/msal-node";
|
|
6
|
+
import axios from "axios";
|
|
7
|
+
import { IdentityClient } from "./identityClient";
|
|
8
|
+
import { credentialLogger } from "../util/logging";
|
|
9
|
+
const logger = credentialLogger("InteractiveBrowserCredential");
|
|
10
|
+
export class AuthenticationRequired extends CredentialUnavailable {
|
|
11
|
+
}
|
|
12
|
+
export class MsalClient {
|
|
13
|
+
constructor(msalConfig, persistenceEnabled, authenticationRecord, options) {
|
|
14
|
+
this.identityClient = new IdentityClient(options);
|
|
15
|
+
this.msalConfig = msalConfig;
|
|
16
|
+
this.persistenceEnabled = persistenceEnabled;
|
|
17
|
+
this.authenticationRecord = authenticationRecord;
|
|
18
|
+
}
|
|
19
|
+
prepareClientApplications() {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
// If we've already initialized the public client application, return
|
|
22
|
+
if (this.pca) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
// Construct the public client application, since it hasn't been initialized, yet
|
|
26
|
+
const clientConfig = {
|
|
27
|
+
auth: this.msalConfig,
|
|
28
|
+
cache: undefined,
|
|
29
|
+
system: { networkClient: this.identityClient }
|
|
30
|
+
};
|
|
31
|
+
this.pca = new PublicClientApplication(clientConfig);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
acquireTokenFromCache(scopes) {
|
|
35
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
+
yield this.prepareClientApplications();
|
|
37
|
+
if (!this.persistenceEnabled || !this.authenticationRecord) {
|
|
38
|
+
throw new AuthenticationRequired();
|
|
39
|
+
}
|
|
40
|
+
const silentRequest = {
|
|
41
|
+
account: this.authenticationRecord,
|
|
42
|
+
scopes
|
|
43
|
+
};
|
|
44
|
+
try {
|
|
45
|
+
const response = yield this.pca.acquireTokenSilent(silentRequest);
|
|
46
|
+
logger.info("Successful silent token acquisition");
|
|
47
|
+
return {
|
|
48
|
+
expiresOnTimestamp: response.expiresOn.getTime(),
|
|
49
|
+
token: response.accessToken
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
throw new AuthenticationRequired("Could not authenticate silently using the cache");
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
getAuthCodeUrl(request) {
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
yield this.prepareClientApplications();
|
|
60
|
+
return this.pca.getAuthCodeUrl(request);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
acquireTokenByCode(request) {
|
|
64
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
+
yield this.prepareClientApplications();
|
|
66
|
+
return this.pca.acquireTokenByCode(request);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
acquireTokenByDeviceCode(request) {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
yield this.prepareClientApplications();
|
|
72
|
+
return this.pca.acquireTokenByDeviceCode(request);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
acquireTokenByClientCredential(request) {
|
|
76
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
77
|
+
yield this.prepareClientApplications();
|
|
78
|
+
return this.cca.acquireTokenByClientCredential(request);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
export var HttpMethod;
|
|
83
|
+
(function (HttpMethod) {
|
|
84
|
+
HttpMethod["GET"] = "get";
|
|
85
|
+
HttpMethod["POST"] = "post";
|
|
86
|
+
})(HttpMethod || (HttpMethod = {}));
|
|
87
|
+
/**
|
|
88
|
+
* This class implements the API for network requests.
|
|
89
|
+
*/
|
|
90
|
+
export class HttpClient {
|
|
91
|
+
constructor() {
|
|
92
|
+
axios.defaults.validateStatus = () => true;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Http Get request
|
|
96
|
+
* @param url
|
|
97
|
+
* @param options
|
|
98
|
+
*/
|
|
99
|
+
sendGetRequestAsync(url, options) {
|
|
100
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
+
const request = {
|
|
102
|
+
method: HttpMethod.GET,
|
|
103
|
+
url: url,
|
|
104
|
+
headers: options && options.headers
|
|
105
|
+
};
|
|
106
|
+
const response = yield axios(request);
|
|
107
|
+
const out = {
|
|
108
|
+
headers: response.headers,
|
|
109
|
+
body: response.data,
|
|
110
|
+
status: response.status
|
|
111
|
+
};
|
|
112
|
+
return out;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Http Post request
|
|
117
|
+
* @param url
|
|
118
|
+
* @param options
|
|
119
|
+
*/
|
|
120
|
+
sendPostRequestAsync(url, options) {
|
|
121
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
122
|
+
const request = {
|
|
123
|
+
method: HttpMethod.POST,
|
|
124
|
+
url: url,
|
|
125
|
+
data: (options && options.body) || "",
|
|
126
|
+
headers: options && options.headers
|
|
127
|
+
};
|
|
128
|
+
const response = yield axios(request);
|
|
129
|
+
const out = {
|
|
130
|
+
headers: response.headers,
|
|
131
|
+
body: response.data,
|
|
132
|
+
status: response.status
|
|
133
|
+
};
|
|
134
|
+
return out;
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=msalClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"msalClient.js","sourceRoot":"","sources":["../../../src/client/msalClient.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { CredentialUnavailable } from \"./errors\";\nimport {\n PublicClientApplication,\n Configuration,\n AuthorizationCodeRequest,\n AuthenticationResult,\n DeviceCodeRequest,\n ConfidentialClientApplication,\n ClientCredentialRequest,\n NetworkRequestOptions,\n NetworkResponse,\n INetworkModule\n} from \"@azure/msal-node\";\nimport axios, { AxiosRequestConfig } from \"axios\";\n\nimport { IdentityClient, TokenCredentialOptions } from \"./identityClient\";\nimport { AccessToken } from \"@azure/core-http\";\nimport { credentialLogger } from \"../util/logging\";\nimport { NodeAuthOptions } from \"@azure/msal-node/dist/config/Configuration\";\n\nconst logger = credentialLogger(\"InteractiveBrowserCredential\");\n\n/**\n * The record to use to find the cached tokens in the cache\n */\nexport interface AuthenticationRecord {\n /**\n * The associated authority, if used\n */\n authority?: string;\n\n /**\n * The home account Id\n */\n homeAccountId: string;\n\n /**\n * The login environment, eg \"login.windows.net\"\n */\n environment: string;\n\n /**\n * The associated tenant ID\n */\n tenantId: string;\n\n /**\n * The username of the logged in account\n */\n username: string;\n}\n\nexport class AuthenticationRequired extends CredentialUnavailable {}\n\nexport class MsalClient {\n private persistenceEnabled: boolean;\n private authenticationRecord: AuthenticationRecord | undefined;\n private identityClient: IdentityClient;\n private pca: PublicClientApplication | undefined;\n private cca: ConfidentialClientApplication | undefined;\n private msalConfig: NodeAuthOptions;\n\n constructor(\n msalConfig: NodeAuthOptions,\n persistenceEnabled: boolean,\n authenticationRecord?: AuthenticationRecord,\n options?: TokenCredentialOptions\n ) {\n this.identityClient = new IdentityClient(options);\n this.msalConfig = msalConfig;\n this.persistenceEnabled = persistenceEnabled;\n this.authenticationRecord = authenticationRecord;\n }\n\n async prepareClientApplications() {\n // If we've already initialized the public client application, return\n if (this.pca) {\n return;\n }\n\n // Construct the public client application, since it hasn't been initialized, yet\n const clientConfig: Configuration = {\n auth: this.msalConfig,\n cache: undefined,\n system: { networkClient: this.identityClient }\n };\n\n this.pca = new PublicClientApplication(clientConfig);\n }\n\n async acquireTokenFromCache(scopes: string[]): Promise<AccessToken | null> {\n await this.prepareClientApplications();\n\n if (!this.persistenceEnabled || !this.authenticationRecord) {\n throw new AuthenticationRequired();\n }\n\n const silentRequest = {\n account: this.authenticationRecord!,\n scopes\n };\n\n try {\n const response = await this.pca!.acquireTokenSilent(silentRequest);\n logger.info(\"Successful silent token acquisition\");\n return {\n expiresOnTimestamp: response.expiresOn.getTime(),\n token: response.accessToken\n };\n } catch (e) {\n throw new AuthenticationRequired(\"Could not authenticate silently using the cache\");\n }\n }\n\n async getAuthCodeUrl(request: { scopes: string[]; redirectUri: string }): Promise<string> {\n await this.prepareClientApplications();\n\n return this.pca!.getAuthCodeUrl(request);\n }\n\n async acquireTokenByCode(request: AuthorizationCodeRequest): Promise<AuthenticationResult> {\n await this.prepareClientApplications();\n\n return this.pca!.acquireTokenByCode(request);\n }\n\n async acquireTokenByDeviceCode(request: DeviceCodeRequest): Promise<AuthenticationResult> {\n await this.prepareClientApplications();\n\n return this.pca!.acquireTokenByDeviceCode(request);\n }\n\n async acquireTokenByClientCredential(\n request: ClientCredentialRequest\n ): Promise<AuthenticationResult> {\n await this.prepareClientApplications();\n\n return this.cca!.acquireTokenByClientCredential(request);\n }\n}\n\nexport enum HttpMethod {\n GET = \"get\",\n POST = \"post\"\n}\n/**\n * This class implements the API for network requests.\n */\nexport class HttpClient implements INetworkModule {\n constructor() {\n axios.defaults.validateStatus = () => true;\n }\n\n /**\n * Http Get request\n * @param url\n * @param options\n */\n async sendGetRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions\n ): Promise<NetworkResponse<T>> {\n const request: AxiosRequestConfig = {\n method: HttpMethod.GET,\n url: url,\n headers: options && options.headers\n };\n\n const response = await axios(request);\n const out = {\n headers: response.headers,\n body: response.data as T,\n status: response.status\n };\n return out;\n }\n\n /**\n * Http Post request\n * @param url\n * @param options\n */\n async sendPostRequestAsync<T>(\n url: string,\n options?: NetworkRequestOptions\n ): Promise<NetworkResponse<T>> {\n const request: AxiosRequestConfig = {\n method: HttpMethod.POST,\n url: url,\n data: (options && options.body) || \"\",\n headers: options && options.headers\n };\n\n const response = await axios(request);\n const out = {\n headers: response.headers,\n body: response.data as T,\n status: response.status\n };\n\n return out;\n }\n}\n"]}
|
|
@@ -5,11 +5,11 @@ const BrowserNotSupportedError = new Error("AuthorizationCodeCredential is not s
|
|
|
5
5
|
const logger = credentialLogger("AuthorizationCodeCredential");
|
|
6
6
|
export class AuthorizationCodeCredential {
|
|
7
7
|
constructor() {
|
|
8
|
-
logger.info(formatError(BrowserNotSupportedError));
|
|
8
|
+
logger.info(formatError("", BrowserNotSupportedError));
|
|
9
9
|
throw BrowserNotSupportedError;
|
|
10
10
|
}
|
|
11
11
|
getToken() {
|
|
12
|
-
logger.getToken.info(formatError(BrowserNotSupportedError));
|
|
12
|
+
logger.getToken.info(formatError("", BrowserNotSupportedError));
|
|
13
13
|
throw BrowserNotSupportedError;
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorizationCodeCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/authorizationCodeCredential.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,mIAAmI,CACpI,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,6BAA6B,CAAC,CAAC;AAE/D,MAAM,OAAO,2BAA2B;IAgBtC;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"authorizationCodeCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/authorizationCodeCredential.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,mIAAmI,CACpI,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,6BAA6B,CAAC,CAAC;AAE/D,MAAM,OAAO,2BAA2B;IAgBtC;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 { TokenCredential, AccessToken } from \"@azure/core-http\";\nimport { TokenCredentialOptions } from \"../client/identityClient\";\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 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"]}
|
|
@@ -8,6 +8,7 @@ import { IdentityClient } from "../client/identityClient";
|
|
|
8
8
|
import { CanonicalCode } from "@opentelemetry/api";
|
|
9
9
|
import { credentialLogger, formatSuccess, formatError } from "../util/logging";
|
|
10
10
|
import { getIdentityTokenEndpointSuffix } from "../util/identityTokenEndpoint";
|
|
11
|
+
import { checkTenantId } from "../util/checkTenantId";
|
|
11
12
|
const logger = credentialLogger("AuthorizationCodeCredential");
|
|
12
13
|
/**
|
|
13
14
|
* Enables authentication to Azure Active Directory using an authorization code
|
|
@@ -23,6 +24,7 @@ export class AuthorizationCodeCredential {
|
|
|
23
24
|
*/
|
|
24
25
|
constructor(tenantId, clientId, clientSecretOrAuthorizationCode, authorizationCodeOrRedirectUri, redirectUriOrOptions, options) {
|
|
25
26
|
this.lastTokenResponse = null;
|
|
27
|
+
checkTenantId(logger, tenantId);
|
|
26
28
|
this.clientId = clientId;
|
|
27
29
|
this.tenantId = tenantId;
|
|
28
30
|
if (typeof redirectUriOrOptions === "string") {
|
|
@@ -100,7 +102,7 @@ export class AuthorizationCodeCredential {
|
|
|
100
102
|
code,
|
|
101
103
|
message: err.message
|
|
102
104
|
});
|
|
103
|
-
logger.getToken.info(formatError(err));
|
|
105
|
+
logger.getToken.info(formatError(scopes, err));
|
|
104
106
|
throw err;
|
|
105
107
|
}
|
|
106
108
|
finally {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorizationCodeCredential.js","sourceRoot":"","sources":["../../../src/credentials/authorizationCodeCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport qs from \"qs\";\nimport { createSpan } from \"../util/tracing\";\nimport { AuthenticationErrorName } from \"../client/errors\";\nimport { TokenCredential, GetTokenOptions, AccessToken } from \"@azure/core-http\";\nimport { IdentityClient, TokenResponse, TokenCredentialOptions } from \"../client/identityClient\";\nimport { CanonicalCode } from \"@opentelemetry/api\";\nimport { credentialLogger, formatSuccess, formatError } from \"../util/logging\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint\";\n\nconst logger = credentialLogger(\"AuthorizationCodeCredential\");\n\n/**\n * Enables authentication to Azure Active Directory using an authorization code\n * that was obtained through the authorization code flow, described in more detail\n * in the Azure Active Directory documentation:\n *\n * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow\n */\nexport class AuthorizationCodeCredential implements TokenCredential {\n private identityClient: IdentityClient;\n private tenantId: string;\n private clientId: string;\n private clientSecret: string | undefined;\n private authorizationCode: string;\n private redirectUri: string;\n private lastTokenResponse: TokenResponse | null = null;\n\n /**\n * Creates an instance of CodeFlowCredential with the details needed\n * to request an access token using an authentication that was obtained\n * from Azure Active Directory.\n *\n * It is currently necessary for the user of this credential to initiate\n * the authorization code flow to obtain an authorization code to be used\n * with this credential. A full example of this flow is provided here:\n *\n * https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/identity/identity/samples/authorizationCodeSample.ts\n *\n * @param tenantId The Azure Active Directory tenant (directory) ID or name.\n * 'common' may be used when dealing with multi-tenant scenarios.\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 authorizationCode An authorization code that was received from following the\n authorization code flow. This authorization code must not\n have already been used to obtain an access token.\n * @param redirectUri The redirect URI that was used to request the authorization code.\n Must be the same URI that is configured for the App Registration.\n * @param options Options for configuring the client which makes the access token request.\n */\n constructor(\n tenantId: string | \"common\",\n clientId: string,\n clientSecret: string,\n authorizationCode: string,\n redirectUri: string,\n options?: TokenCredentialOptions\n );\n /**\n * Creates an instance of CodeFlowCredential with the details needed\n * to request an access token using an authentication that was obtained\n * from Azure Active Directory.\n *\n * It is currently necessary for the user of this credential to initiate\n * the authorization code flow to obtain an authorization code to be used\n * with this credential. A full example of this flow is provided here:\n *\n * https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/identity/identity/samples/authorizationCodeSample.ts\n *\n * @param tenantId The Azure Active Directory tenant (directory) ID or name.\n * 'common' may be used when dealing with multi-tenant scenarios.\n * @param clientId The client (application) ID of an App Registration in the tenant.\n * @param authorizationCode An authorization code that was received from following the\n authorization code flow. This authorization code must not\n have already been used to obtain an access token.\n * @param redirectUri The redirect URI that was used to request the authorization code.\n Must be the same URI that is configured for the App Registration.\n * @param options Options for configuring the client which makes the access token request.\n */\n constructor(\n tenantId: string | \"common\",\n clientId: string,\n authorizationCode: string,\n redirectUri: string,\n options?: TokenCredentialOptions\n );\n /**\n * @ignore\n * @internal\n */\n constructor(\n tenantId: string | \"common\",\n clientId: string,\n clientSecretOrAuthorizationCode: string,\n authorizationCodeOrRedirectUri: string,\n redirectUriOrOptions: string | TokenCredentialOptions | undefined,\n options?: TokenCredentialOptions\n ) {\n this.clientId = clientId;\n this.tenantId = tenantId;\n\n if (typeof redirectUriOrOptions === \"string\") {\n // the clientId+clientSecret constructor\n this.clientSecret = clientSecretOrAuthorizationCode;\n this.authorizationCode = authorizationCodeOrRedirectUri;\n this.redirectUri = redirectUriOrOptions;\n // options okay\n } else {\n // clientId only\n this.clientSecret = undefined;\n this.authorizationCode = clientSecretOrAuthorizationCode;\n this.redirectUri = authorizationCodeOrRedirectUri as string;\n options = redirectUriOrOptions as TokenCredentialOptions;\n }\n\n this.identityClient = new IdentityClient(options);\n }\n\n /**\n * Authenticates with Azure Active Directory and returns an access token if\n * successful. If authentication cannot be performed at this time, this method may\n * return null. If an error occurs during authentication, an {@link AuthenticationError}\n * containing failure details will be thrown.\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 public async getToken(\n scopes: string | string[],\n options?: GetTokenOptions\n ): Promise<AccessToken | null> {\n const { span, options: newOptions } = createSpan(\n \"AuthorizationCodeCredential-getToken\",\n options\n );\n try {\n let tokenResponse: TokenResponse | null = null;\n let scopeString = typeof scopes === \"string\" ? scopes : scopes.join(\" \");\n if (scopeString.indexOf(\"offline_access\") < 0) {\n scopeString += \" offline_access\";\n }\n\n // Try to use the refresh token first\n if (this.lastTokenResponse && this.lastTokenResponse.refreshToken) {\n tokenResponse = await this.identityClient.refreshAccessToken(\n this.tenantId,\n this.clientId,\n scopeString,\n this.lastTokenResponse.refreshToken,\n this.clientSecret,\n undefined,\n newOptions\n );\n }\n\n if (tokenResponse === null) {\n const urlSuffix = getIdentityTokenEndpointSuffix(this.tenantId);\n const webResource = this.identityClient.createWebResource({\n url: `${this.identityClient.authorityHost}/${this.tenantId}/${urlSuffix}`,\n method: \"POST\",\n disableJsonStringifyOnBody: true,\n deserializationMapper: undefined,\n body: qs.stringify({\n client_id: this.clientId,\n grant_type: \"authorization_code\",\n scope: scopeString,\n code: this.authorizationCode,\n redirect_uri: this.redirectUri,\n client_secret: this.clientSecret\n }),\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\"\n },\n abortSignal: options && options.abortSignal,\n spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions\n });\n\n tokenResponse = await this.identityClient.sendTokenRequest(webResource);\n }\n\n this.lastTokenResponse = tokenResponse;\n logger.getToken.info(formatSuccess(scopes));\n return (tokenResponse && tokenResponse.accessToken) || null;\n } catch (err) {\n const code =\n err.name === AuthenticationErrorName\n ? CanonicalCode.UNAUTHENTICATED\n : CanonicalCode.UNKNOWN;\n span.setStatus({\n code,\n message: err.message\n });\n logger.getToken.info(formatError(err));\n throw err;\n } finally {\n span.end();\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"authorizationCodeCredential.js","sourceRoot":"","sources":["../../../src/credentials/authorizationCodeCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport qs from \"qs\";\nimport { createSpan } from \"../util/tracing\";\nimport { AuthenticationErrorName } from \"../client/errors\";\nimport { TokenCredential, GetTokenOptions, AccessToken } from \"@azure/core-http\";\nimport { IdentityClient, TokenResponse, TokenCredentialOptions } from \"../client/identityClient\";\nimport { CanonicalCode } from \"@opentelemetry/api\";\nimport { credentialLogger, formatSuccess, formatError } from \"../util/logging\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint\";\nimport { checkTenantId } from \"../util/checkTenantId\";\n\nconst logger = credentialLogger(\"AuthorizationCodeCredential\");\n\n/**\n * Enables authentication to Azure Active Directory using an authorization code\n * that was obtained through the authorization code flow, described in more detail\n * in the Azure Active Directory documentation:\n *\n * https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow\n */\nexport class AuthorizationCodeCredential implements TokenCredential {\n private identityClient: IdentityClient;\n private tenantId: string;\n private clientId: string;\n private clientSecret: string | undefined;\n private authorizationCode: string;\n private redirectUri: string;\n private lastTokenResponse: TokenResponse | null = null;\n\n /**\n * Creates an instance of CodeFlowCredential with the details needed\n * to request an access token using an authentication that was obtained\n * from Azure Active Directory.\n *\n * It is currently necessary for the user of this credential to initiate\n * the authorization code flow to obtain an authorization code to be used\n * with this credential. A full example of this flow is provided here:\n *\n * https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/identity/identity/samples/authorizationCodeSample.ts\n *\n * @param tenantId The Azure Active Directory tenant (directory) ID or name.\n * 'common' may be used when dealing with multi-tenant scenarios.\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 authorizationCode An authorization code that was received from following the\n authorization code flow. This authorization code must not\n have already been used to obtain an access token.\n * @param redirectUri The redirect URI that was used to request the authorization code.\n Must be the same URI that is configured for the App Registration.\n * @param options Options for configuring the client which makes the access token request.\n */\n constructor(\n tenantId: string | \"common\",\n clientId: string,\n clientSecret: string,\n authorizationCode: string,\n redirectUri: string,\n options?: TokenCredentialOptions\n );\n /**\n * Creates an instance of CodeFlowCredential with the details needed\n * to request an access token using an authentication that was obtained\n * from Azure Active Directory.\n *\n * It is currently necessary for the user of this credential to initiate\n * the authorization code flow to obtain an authorization code to be used\n * with this credential. A full example of this flow is provided here:\n *\n * https://github.com/Azure/azure-sdk-for-js/blob/master/sdk/identity/identity/samples/authorizationCodeSample.ts\n *\n * @param tenantId The Azure Active Directory tenant (directory) ID or name.\n * 'common' may be used when dealing with multi-tenant scenarios.\n * @param clientId The client (application) ID of an App Registration in the tenant.\n * @param authorizationCode An authorization code that was received from following the\n authorization code flow. This authorization code must not\n have already been used to obtain an access token.\n * @param redirectUri The redirect URI that was used to request the authorization code.\n Must be the same URI that is configured for the App Registration.\n * @param options Options for configuring the client which makes the access token request.\n */\n constructor(\n tenantId: string | \"common\",\n clientId: string,\n authorizationCode: string,\n redirectUri: string,\n options?: TokenCredentialOptions\n );\n /**\n * @ignore\n * @internal\n */\n constructor(\n tenantId: string | \"common\",\n clientId: string,\n clientSecretOrAuthorizationCode: string,\n authorizationCodeOrRedirectUri: string,\n redirectUriOrOptions: string | TokenCredentialOptions | undefined,\n options?: TokenCredentialOptions\n ) {\n checkTenantId(logger, tenantId);\n\n this.clientId = clientId;\n this.tenantId = tenantId;\n\n if (typeof redirectUriOrOptions === \"string\") {\n // the clientId+clientSecret constructor\n this.clientSecret = clientSecretOrAuthorizationCode;\n this.authorizationCode = authorizationCodeOrRedirectUri;\n this.redirectUri = redirectUriOrOptions;\n // options okay\n } else {\n // clientId only\n this.clientSecret = undefined;\n this.authorizationCode = clientSecretOrAuthorizationCode;\n this.redirectUri = authorizationCodeOrRedirectUri as string;\n options = redirectUriOrOptions as TokenCredentialOptions;\n }\n\n this.identityClient = new IdentityClient(options);\n }\n\n /**\n * Authenticates with Azure Active Directory and returns an access token if\n * successful. If authentication cannot be performed at this time, this method may\n * return null. If an error occurs during authentication, an {@link AuthenticationError}\n * containing failure details will be thrown.\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 public async getToken(\n scopes: string | string[],\n options?: GetTokenOptions\n ): Promise<AccessToken | null> {\n const { span, options: newOptions } = createSpan(\n \"AuthorizationCodeCredential-getToken\",\n options\n );\n try {\n let tokenResponse: TokenResponse | null = null;\n let scopeString = typeof scopes === \"string\" ? scopes : scopes.join(\" \");\n if (scopeString.indexOf(\"offline_access\") < 0) {\n scopeString += \" offline_access\";\n }\n\n // Try to use the refresh token first\n if (this.lastTokenResponse && this.lastTokenResponse.refreshToken) {\n tokenResponse = await this.identityClient.refreshAccessToken(\n this.tenantId,\n this.clientId,\n scopeString,\n this.lastTokenResponse.refreshToken,\n this.clientSecret,\n undefined,\n newOptions\n );\n }\n\n if (tokenResponse === null) {\n const urlSuffix = getIdentityTokenEndpointSuffix(this.tenantId);\n const webResource = this.identityClient.createWebResource({\n url: `${this.identityClient.authorityHost}/${this.tenantId}/${urlSuffix}`,\n method: \"POST\",\n disableJsonStringifyOnBody: true,\n deserializationMapper: undefined,\n body: qs.stringify({\n client_id: this.clientId,\n grant_type: \"authorization_code\",\n scope: scopeString,\n code: this.authorizationCode,\n redirect_uri: this.redirectUri,\n client_secret: this.clientSecret\n }),\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\"\n },\n abortSignal: options && options.abortSignal,\n spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions\n });\n\n tokenResponse = await this.identityClient.sendTokenRequest(webResource);\n }\n\n this.lastTokenResponse = tokenResponse;\n logger.getToken.info(formatSuccess(scopes));\n return (tokenResponse && tokenResponse.accessToken) || null;\n } catch (err) {\n const code =\n err.name === AuthenticationErrorName\n ? CanonicalCode.UNAUTHENTICATED\n : CanonicalCode.UNKNOWN;\n span.setStatus({\n code,\n message: err.message\n });\n logger.getToken.info(formatError(scopes, err));\n throw err;\n } finally {\n span.end();\n }\n }\n}\n"]}
|
|
@@ -5,11 +5,11 @@ const BrowserNotSupportedError = new Error("AzureCliCredential is not supported
|
|
|
5
5
|
const logger = credentialLogger("AzureCliCredential");
|
|
6
6
|
export class AzureCliCredential {
|
|
7
7
|
constructor() {
|
|
8
|
-
logger.info(formatError(BrowserNotSupportedError));
|
|
8
|
+
logger.info(formatError("", BrowserNotSupportedError));
|
|
9
9
|
throw BrowserNotSupportedError;
|
|
10
10
|
}
|
|
11
11
|
getToken() {
|
|
12
|
-
logger.getToken.info(formatError(BrowserNotSupportedError));
|
|
12
|
+
logger.getToken.info(formatError("", BrowserNotSupportedError));
|
|
13
13
|
throw BrowserNotSupportedError;
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"azureCliCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/azureCliCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,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,MAAM,OAAO,kBAAkB;IAC7B;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"azureCliCredential.browser.js","sourceRoot":"","sources":["../../../src/credentials/azureCliCredential.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,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,MAAM,OAAO,kBAAkB;IAC7B;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-http\";\nimport { credentialLogger, formatError } from \"../util/logging\";\n\nconst BrowserNotSupportedError = new Error(\"AzureCliCredential is not supported in the browser.\");\nconst logger = credentialLogger(\"AzureCliCredential\");\n\nexport class AzureCliCredential implements TokenCredential {\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"]}
|
|
@@ -64,7 +64,7 @@ export class AzureCliCredential {
|
|
|
64
64
|
// Check to make sure the scope we get back is a valid scope
|
|
65
65
|
if (!scope.match(/^[0-9a-zA-Z-.:/]+$/)) {
|
|
66
66
|
const error = new Error("Invalid scope was specified by the user or calling client");
|
|
67
|
-
logger.getToken.info(formatError(error));
|
|
67
|
+
logger.getToken.info(formatError(scopes, error));
|
|
68
68
|
throw error;
|
|
69
69
|
}
|
|
70
70
|
let responseData = "";
|
|
@@ -77,16 +77,16 @@ export class AzureCliCredential {
|
|
|
77
77
|
obj.stderr.startsWith("'az' is not recognized");
|
|
78
78
|
if (isNotInstallError) {
|
|
79
79
|
const error = new CredentialUnavailable("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'.");
|
|
80
|
-
logger.getToken.info(formatError(error));
|
|
80
|
+
logger.getToken.info(formatError(scopes, error));
|
|
81
81
|
throw error;
|
|
82
82
|
}
|
|
83
83
|
else if (isLoginError) {
|
|
84
84
|
const error = new CredentialUnavailable("Please run 'az login' from a command prompt to authenticate before using this credential.");
|
|
85
|
-
logger.getToken.info(formatError(error));
|
|
85
|
+
logger.getToken.info(formatError(scopes, error));
|
|
86
86
|
throw error;
|
|
87
87
|
}
|
|
88
88
|
const error = new CredentialUnavailable(obj.stderr);
|
|
89
|
-
logger.getToken.info(formatError(error));
|
|
89
|
+
logger.getToken.info(formatError(scopes, error));
|
|
90
90
|
throw error;
|
|
91
91
|
}
|
|
92
92
|
else {
|
|
@@ -109,7 +109,7 @@ export class AzureCliCredential {
|
|
|
109
109
|
code,
|
|
110
110
|
message: err.message
|
|
111
111
|
});
|
|
112
|
-
logger.getToken.info(formatError(err));
|
|
112
|
+
logger.getToken.info(formatError(scopes, err));
|
|
113
113
|
reject(err);
|
|
114
114
|
});
|
|
115
115
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"azureCliCredential.js","sourceRoot":"","sources":["../../../src/credentials/azureCliCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAGlC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAClF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC/E,OAAO,KAAK,aAAa,MAAM,eAAe,CAAC;AAE/C,SAAS,iBAAiB;IACxB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE;QAChC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE;YAC3B,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;SACrF;QACD,OAAO,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;KAC/B;SAAM;QACL,OAAO,MAAM,CAAC;KACf;AACH,CAAC;AAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,oBAAoB,CAAC,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,OAAO,kBAAkB;IAC7B;;;OAGG;IACa,sBAAsB,CACpC,QAAgB;;YAEhB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,IAAI;oBACF,aAAa,CAAC,IAAI,CAChB,wDAAwD,QAAQ,EAAE,EAClE,EAAE,GAAG,EAAE,iBAAiB,EAAE,EAAE,EAC5B,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;wBACxB,OAAO,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;oBACrD,CAAC,CACF,CAAC;iBACH;gBAAC,OAAO,GAAG,EAAE;oBACZ,MAAM,CAAC,GAAG,CAAC,CAAC;iBACb;YACH,CAAC,CAAC,CAAC;QACL,CAAC;KAAA;IAED;;;;;;;;;OASG;IACU,QAAQ,CACnB,MAAyB,EACzB,OAAyB;;YAEzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,MAAM,KAAK,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAC9D,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,mBAAmB,KAAK,EAAE,CAAC,CAAC;gBAEjD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;gBAElD,4DAA4D;gBAC5D,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE;oBACtC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;oBACrF,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"azureCliCredential.js","sourceRoot":"","sources":["../../../src/credentials/azureCliCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { TokenCredential, GetTokenOptions, AccessToken } from \"@azure/core-http\";\nimport { createSpan } from \"../util/tracing\";\nimport { AuthenticationErrorName, CredentialUnavailable } from \"../client/errors\";\nimport { CanonicalCode } from \"@opentelemetry/api\";\nimport { credentialLogger, formatSuccess, formatError } from \"../util/logging\";\nimport * as child_process from \"child_process\";\n\nfunction getSafeWorkingDir(): string {\n if (process.platform === \"win32\") {\n if (!process.env.SystemRoot) {\n throw new Error(\"Azure CLI credential expects a 'SystemRoot' environment variable\");\n }\n return process.env.SystemRoot;\n } else {\n return \"/bin\";\n }\n}\n\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 * To do so, it will read the user access token and expire time\n * with Azure CLI command \"az account get-access-token\".\n * To be able to use this credential, ensure that you have already logged\n * in via the 'az' tool using the command \"az login\" from the commandline.\n */\nexport class AzureCliCredential implements TokenCredential {\n /**\n * Gets the access token from Azure CLI\n * @param resource The resource to use when getting the token\n */\n protected async getAzureCliAccessToken(\n resource: string\n ): Promise<{ stdout: string; stderr: string; error: Error | null }> {\n return new Promise((resolve, reject) => {\n try {\n child_process.exec(\n `az account get-access-token --output json --resource ${resource}`,\n { cwd: getSafeWorkingDir() },\n (error, stdout, stderr) => {\n resolve({ stdout: stdout, stderr: stderr, error });\n }\n );\n } catch (err) {\n reject(err);\n }\n });\n }\n\n /**\n * Authenticates with Azure Active Directory and returns an access token if\n * successful. If authentication cannot be performed at this time, this method may\n * return null. If an error occurs during authentication, an {@link AuthenticationError}\n * containing failure details will be thrown.\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 public async getToken(\n scopes: string | string[],\n options?: GetTokenOptions\n ): Promise<AccessToken | null> {\n return new Promise((resolve, reject) => {\n const scope = typeof scopes === \"string\" ? scopes : scopes[0];\n logger.getToken.info(`Using the scope ${scope}`);\n\n const resource = scope.replace(/\\/.default$/, \"\");\n\n // Check to make sure the scope we get back is a valid scope\n if (!scope.match(/^[0-9a-zA-Z-.:/]+$/)) {\n const error = new Error(\"Invalid scope was specified by the user or calling client\");\n logger.getToken.info(formatError(scopes, error));\n throw error;\n }\n\n let responseData = \"\";\n\n const { span } = createSpan(\"AzureCliCredential-getToken\", options);\n this.getAzureCliAccessToken(resource)\n .then((obj: any) => {\n if (obj.stderr) {\n const isLoginError = obj.stderr.match(\"(.*)az login(.*)\");\n const isNotInstallError =\n obj.stderr.match(\"az:(.*)not found\") ||\n obj.stderr.startsWith(\"'az' is not recognized\");\n if (isNotInstallError) {\n const error = new CredentialUnavailable(\n \"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'.\"\n );\n logger.getToken.info(formatError(scopes, error));\n throw error;\n } else if (isLoginError) {\n const error = new CredentialUnavailable(\n \"Please run 'az login' from a command prompt to authenticate before using this credential.\"\n );\n logger.getToken.info(formatError(scopes, error));\n throw error;\n }\n const error = new CredentialUnavailable(obj.stderr);\n logger.getToken.info(formatError(scopes, error));\n throw error;\n } else {\n responseData = obj.stdout;\n const response: { accessToken: string; expiresOn: string } = JSON.parse(responseData);\n logger.getToken.info(formatSuccess(scopes));\n const returnValue = {\n token: response.accessToken,\n expiresOnTimestamp: new Date(response.expiresOn).getTime()\n };\n resolve(returnValue);\n return returnValue;\n }\n })\n .catch((err) => {\n const code =\n err.name === AuthenticationErrorName\n ? CanonicalCode.UNAUTHENTICATED\n : CanonicalCode.UNKNOWN;\n span.setStatus({\n code,\n message: err.message\n });\n logger.getToken.info(formatError(scopes, err));\n reject(err);\n });\n });\n }\n}\n"]}
|
|
@@ -58,7 +58,7 @@ export class ChainedTokenCredential {
|
|
|
58
58
|
errors.push(err);
|
|
59
59
|
}
|
|
60
60
|
else {
|
|
61
|
-
logger.getToken.info(formatError(err));
|
|
61
|
+
logger.getToken.info(formatError(scopes, err));
|
|
62
62
|
throw err;
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -69,7 +69,7 @@ export class ChainedTokenCredential {
|
|
|
69
69
|
code: CanonicalCode.UNAUTHENTICATED,
|
|
70
70
|
message: err.message
|
|
71
71
|
});
|
|
72
|
-
logger.getToken.info(formatError(err));
|
|
72
|
+
logger.getToken.info(formatError(scopes, err));
|
|
73
73
|
throw err;
|
|
74
74
|
}
|
|
75
75
|
span.end();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chainedTokenCredential.js","sourceRoot":"","sources":["../../../src/credentials/chainedTokenCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAGlC,OAAO,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE/E,MAAM,MAAM,GAAG,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;AAE1D;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IASjC;;;;;;;;;;;OAWG;IACH,YAAY,GAAG,OAA0B;QApBzC;;WAEG;QACO,uBAAkB,GAC1B,oFAAoF,CAAC;QAE/E,aAAQ,GAAsB,EAAE,CAAC;QAevC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED;;;;;;;;;;;;OAYG;IACG,QAAQ,CACZ,MAAyB,EACzB,OAAyB;;YAEzB,IAAI,KAAK,GAAG,IAAI,CAAC;YACjB,MAAM,MAAM,GAAG,EAAE,CAAC;YAElB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,UAAU,CAAC,iCAAiC,EAAE,OAAO,CAAC,CAAC;YAE7F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE;gBAC/D,IAAI;oBACF,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;iBAC7D;gBAAC,OAAO,GAAG,EAAE;oBACZ,IAAI,GAAG,YAAY,qBAAqB,EAAE;wBACxC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;qBAClB;yBAAM;wBACL,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"chainedTokenCredential.js","sourceRoot":"","sources":["../../../src/credentials/chainedTokenCredential.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAGlC,OAAO,EAAE,4BAA4B,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACvF,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE/E,MAAM,MAAM,GAAG,gBAAgB,CAAC,wBAAwB,CAAC,CAAC;AAE1D;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IASjC;;;;;;;;;;;OAWG;IACH,YAAY,GAAG,OAA0B;QApBzC;;WAEG;QACO,uBAAkB,GAC1B,oFAAoF,CAAC;QAE/E,aAAQ,GAAsB,EAAE,CAAC;QAevC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED;;;;;;;;;;;;OAYG;IACG,QAAQ,CACZ,MAAyB,EACzB,OAAyB;;YAEzB,IAAI,KAAK,GAAG,IAAI,CAAC;YACjB,MAAM,MAAM,GAAG,EAAE,CAAC;YAElB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,UAAU,CAAC,iCAAiC,EAAE,OAAO,CAAC,CAAC;YAE7F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC,EAAE,EAAE;gBAC/D,IAAI;oBACF,KAAK,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;iBAC7D;gBAAC,OAAO,GAAG,EAAE;oBACZ,IAAI,GAAG,YAAY,qBAAqB,EAAE;wBACxC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;qBAClB;yBAAM;wBACL,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;wBAC/C,MAAM,GAAG,CAAC;qBACX;iBACF;aACF;YAED,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC/B,MAAM,GAAG,GAAG,IAAI,4BAA4B,CAAC,MAAM,CAAC,CAAC;gBACrD,IAAI,CAAC,SAAS,CAAC;oBACb,IAAI,EAAE,aAAa,CAAC,eAAe;oBACnC,OAAO,EAAE,GAAG,CAAC,OAAO;iBACrB,CAAC,CAAC;gBACH,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;gBAC/C,MAAM,GAAG,CAAC;aACX;YAED,IAAI,CAAC,GAAG,EAAE,CAAC;YAEX,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5C,OAAO,KAAK,CAAC;QACf,CAAC;KAAA;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, TokenCredential, GetTokenOptions } from \"@azure/core-http\";\nimport { AggregateAuthenticationError, CredentialUnavailable } from \"../client/errors\";\nimport { createSpan } from \"../util/tracing\";\nimport { CanonicalCode } from \"@opentelemetry/api\";\nimport { credentialLogger, formatSuccess, formatError } from \"../util/logging\";\n\nconst logger = credentialLogger(\"ChainedTokenCredential\");\n\n/**\n * Enables multiple `TokenCredential` implementations to be tried in order\n * until one of the getToken methods returns an access token.\n */\nexport class ChainedTokenCredential implements TokenCredential {\n /**\n * The message to use when the chained token fails to get a token\n */\n protected UnavailableMessage =\n \"ChainedTokenCredential => failed to retrieve a token from the included credentials\";\n\n private _sources: TokenCredential[] = [];\n\n /**\n * Creates an instance of ChainedTokenCredential using the given credentials.\n *\n * @param sources `TokenCredential` implementations to be tried in order.\n *\n * Example usage:\n * ```javascript\n * const firstCredential = new ClientSecretCredential(tenantId, clientId, clientSecret);\n * const secondCredential = new ClientSecretCredential(tenantId, anotherClientId, anotherSecret);\n * const credentialChain = new ChainedTokenCredential(firstCredential, secondCredential);\n * ```\n */\n constructor(...sources: TokenCredential[]) {\n this._sources = sources;\n }\n\n /**\n * Returns the first access token returned by one of the chained\n * `TokenCredential` implementations. Throws an {@link AggregateAuthenticationError}\n * when one or more credentials throws an {@link AuthenticationError} and\n * no credentials have returned an access token.\n *\n * This method is called automatically by Azure SDK client libraries. You may call this method\n * directly, but you must also handle token caching and token refreshing.\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(\n scopes: string | string[],\n options?: GetTokenOptions\n ): Promise<AccessToken | null> {\n let token = null;\n const errors = [];\n\n const { span, options: newOptions } = createSpan(\"ChainedTokenCredential-getToken\", options);\n\n for (let i = 0; i < this._sources.length && token === null; i++) {\n try {\n token = await this._sources[i].getToken(scopes, newOptions);\n } catch (err) {\n if (err instanceof CredentialUnavailable) {\n errors.push(err);\n } else {\n logger.getToken.info(formatError(scopes, err));\n throw err;\n }\n }\n }\n\n if (!token && errors.length > 0) {\n const err = new AggregateAuthenticationError(errors);\n span.setStatus({\n code: CanonicalCode.UNAUTHENTICATED,\n message: err.message\n });\n logger.getToken.info(formatError(scopes, err));\n throw err;\n }\n\n span.end();\n\n logger.getToken.info(formatSuccess(scopes));\n return token;\n }\n}\n"]}
|
|
@@ -5,11 +5,11 @@ const BrowserNotSupportedError = new Error("ClientCertificateCredential is not s
|
|
|
5
5
|
const logger = credentialLogger("ClientCertificateCredential");
|
|
6
6
|
export class ClientCertificateCredential {
|
|
7
7
|
constructor() {
|
|
8
|
-
logger.info(formatError(BrowserNotSupportedError));
|
|
8
|
+
logger.info(formatError("", BrowserNotSupportedError));
|
|
9
9
|
throw BrowserNotSupportedError;
|
|
10
10
|
}
|
|
11
11
|
getToken() {
|
|
12
|
-
logger.getToken.info(formatError(BrowserNotSupportedError));
|
|
12
|
+
logger.getToken.info(formatError("", BrowserNotSupportedError));
|
|
13
13
|
throw BrowserNotSupportedError;
|
|
14
14
|
}
|
|
15
15
|
}
|
|
@@ -1 +1 @@
|
|
|
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,MAAM,OAAO,2BAA2B;IACtC;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC,CAAC;
|
|
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,MAAM,OAAO,2BAA2B;IACtC;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 { TokenCredential, AccessToken } from \"@azure/core-http\";\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\nexport class ClientCertificateCredential implements TokenCredential {\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"]}
|
|
@@ -12,6 +12,7 @@ import { AuthenticationErrorName } from "../client/errors";
|
|
|
12
12
|
import { CanonicalCode } from "@opentelemetry/api";
|
|
13
13
|
import { credentialLogger, formatSuccess, formatError } from "../util/logging";
|
|
14
14
|
import { getIdentityTokenEndpointSuffix } from "../util/identityTokenEndpoint";
|
|
15
|
+
import { checkTenantId } from "../util/checkTenantId";
|
|
15
16
|
const SelfSignedJwtLifetimeMins = 10;
|
|
16
17
|
function timestampInSeconds(date) {
|
|
17
18
|
return Math.floor(date.getTime() / 1000);
|
|
@@ -40,6 +41,7 @@ export class ClientCertificateCredential {
|
|
|
40
41
|
* @param options Options for configuring the client which makes the authentication request.
|
|
41
42
|
*/
|
|
42
43
|
constructor(tenantId, clientId, certificatePath, options) {
|
|
44
|
+
checkTenantId(logger, tenantId);
|
|
43
45
|
this.identityClient = new IdentityClient(options);
|
|
44
46
|
this.tenantId = tenantId;
|
|
45
47
|
this.clientId = clientId;
|
|
@@ -56,7 +58,7 @@ export class ClientCertificateCredential {
|
|
|
56
58
|
} while (match);
|
|
57
59
|
if (publicKeys.length === 0) {
|
|
58
60
|
const error = new Error("The file at the specified path does not contain a PEM-encoded certificate.");
|
|
59
|
-
logger.info(formatError(error));
|
|
61
|
+
logger.info(formatError("", error));
|
|
60
62
|
throw error;
|
|
61
63
|
}
|
|
62
64
|
this.certificateThumbprint = createHash("sha1")
|
|
@@ -64,7 +66,7 @@ export class ClientCertificateCredential {
|
|
|
64
66
|
.digest("hex")
|
|
65
67
|
.toUpperCase();
|
|
66
68
|
this.certificateX5t = Buffer.from(this.certificateThumbprint, "hex").toString("base64");
|
|
67
|
-
if (options && options.
|
|
69
|
+
if (options && options.sendCertificateChain) {
|
|
68
70
|
this.certificateX5c = publicKeys;
|
|
69
71
|
}
|
|
70
72
|
}
|
|
@@ -146,7 +148,7 @@ export class ClientCertificateCredential {
|
|
|
146
148
|
code,
|
|
147
149
|
message: err.message
|
|
148
150
|
});
|
|
149
|
-
logger.getToken.info(formatError(err));
|
|
151
|
+
logger.getToken.info(formatError("", err));
|
|
150
152
|
throw err;
|
|
151
153
|
}
|
|
152
154
|
finally {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clientCertificateCredential.js","sourceRoot":"","sources":["../../../src/credentials/clientCertificateCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport qs from \"qs\";\nimport jws from \"jws\";\nimport { v4 as uuidV4 } from \"uuid\";\nimport { readFileSync } from \"fs\";\nimport { createHash } from \"crypto\";\nimport { TokenCredential, GetTokenOptions, AccessToken } from \"@azure/core-http\";\nimport { IdentityClient } from \"../client/identityClient\";\nimport { ClientCertificateCredentialOptions } from \"./clientCertificateCredentialOptions\";\nimport { createSpan } from \"../util/tracing\";\nimport { AuthenticationErrorName } from \"../client/errors\";\nimport { CanonicalCode } from \"@opentelemetry/api\";\nimport { credentialLogger, formatSuccess, formatError } from \"../util/logging\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint\";\n\nconst SelfSignedJwtLifetimeMins = 10;\n\nfunction timestampInSeconds(date: Date): number {\n return Math.floor(date.getTime() / 1000);\n}\n\nfunction addMinutes(date: Date, minutes: number): Date {\n date.setMinutes(date.getMinutes() + minutes);\n return date;\n}\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. More information\n * on how to configure certificate authentication can be found here:\n *\n * https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials#register-your-certificate-with-azure-ad\n *\n */\nexport class ClientCertificateCredential implements TokenCredential {\n private identityClient: IdentityClient;\n private tenantId: string;\n private clientId: string;\n private certificateString: string;\n private certificateThumbprint: string;\n private certificateX5t: string;\n private certificateX5c?: Array<string>;\n\n /**\n * Creates an instance of the ClientCertificateCredential with the details\n * needed to authenticate against Azure Active Directory with a certificate.\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 certificatePath The path to a PEM-encoded public/private key certificate on the filesystem.\n * @param options Options for configuring the client which makes the authentication request.\n */\n constructor(\n tenantId: string,\n clientId: string,\n certificatePath: string,\n options?: ClientCertificateCredentialOptions\n ) {\n this.identityClient = new IdentityClient(options);\n this.tenantId = tenantId;\n this.clientId = clientId;\n this.certificateString = readFileSync(certificatePath, \"utf8\");\n\n const certificatePattern = /(-+BEGIN CERTIFICATE-+)(\\n\\r?|\\r\\n?)([A-Za-z0-9+/\\n\\r]+=*)(\\n\\r?|\\r\\n?)(-+END CERTIFICATE-+)/g;\n\n const publicKeys: string[] = [];\n\n // Match all possible certificates, in the order they are in the file. These will form the chain that is used for x5c\n let match;\n do {\n match = certificatePattern.exec(this.certificateString);\n if (match) {\n publicKeys.push(match[3]);\n }\n } while (match);\n\n if (publicKeys.length === 0) {\n const error = new Error(\n \"The file at the specified path does not contain a PEM-encoded certificate.\"\n );\n logger.info(formatError(error));\n throw error;\n }\n\n this.certificateThumbprint = createHash(\"sha1\")\n .update(Buffer.from(publicKeys[0], \"base64\"))\n .digest(\"hex\")\n .toUpperCase();\n\n this.certificateX5t = Buffer.from(this.certificateThumbprint, \"hex\").toString(\"base64\");\n if (options && options.includeX5c) {\n this.certificateX5c = publicKeys;\n }\n }\n\n /**\n * Authenticates with Azure Active Directory and returns an access token if\n * successful. If authentication cannot be performed at this time, this method may\n * return null. If an error occurs during authentication, an {@link AuthenticationError}\n * containing failure details will be thrown.\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 public async getToken(\n scopes: string | string[],\n options?: GetTokenOptions\n ): Promise<AccessToken | null> {\n const { span, options: newOptions } = createSpan(\n \"ClientCertificateCredential-getToken\",\n options\n );\n try {\n const tokenId = uuidV4();\n const urlSuffix = getIdentityTokenEndpointSuffix(this.tenantId);\n const audienceUrl = `${this.identityClient.authorityHost}/${this.tenantId}/${urlSuffix}`;\n let header: jws.Header;\n\n if (this.certificateX5c) {\n header = {\n typ: \"JWT\",\n alg: \"RS256\",\n x5t: this.certificateX5t,\n x5c: this.certificateX5c\n };\n } else {\n header = {\n typ: \"JWT\",\n alg: \"RS256\",\n x5t: this.certificateX5t\n };\n }\n\n const payload = {\n iss: this.clientId,\n sub: this.clientId,\n aud: audienceUrl,\n jti: tokenId,\n nbf: timestampInSeconds(new Date()),\n exp: timestampInSeconds(addMinutes(new Date(), SelfSignedJwtLifetimeMins))\n };\n\n const clientAssertion = jws.sign({\n header,\n payload,\n secret: this.certificateString\n });\n\n const webResource = this.identityClient.createWebResource({\n url: audienceUrl,\n method: \"POST\",\n disableJsonStringifyOnBody: true,\n deserializationMapper: undefined,\n body: qs.stringify({\n response_type: \"token\",\n grant_type: \"client_credentials\",\n client_id: this.clientId,\n client_assertion_type: \"urn:ietf:params:oauth:client-assertion-type:jwt-bearer\",\n client_assertion: clientAssertion,\n scope: typeof scopes === \"string\" ? scopes : scopes.join(\" \")\n }),\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\"\n },\n abortSignal: options && options.abortSignal,\n spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions\n });\n\n const tokenResponse = await this.identityClient.sendTokenRequest(webResource);\n logger.getToken.info(formatSuccess(scopes));\n return (tokenResponse && tokenResponse.accessToken) || null;\n } catch (err) {\n const code =\n err.name === AuthenticationErrorName\n ? CanonicalCode.UNAUTHENTICATED\n : CanonicalCode.UNKNOWN;\n span.setStatus({\n code,\n message: err.message\n });\n logger.getToken.info(formatError(err));\n throw err;\n } finally {\n span.end();\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"clientCertificateCredential.js","sourceRoot":"","sources":["../../../src/credentials/clientCertificateCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport qs from \"qs\";\nimport jws from \"jws\";\nimport { v4 as uuidV4 } from \"uuid\";\nimport { readFileSync } from \"fs\";\nimport { createHash } from \"crypto\";\nimport { TokenCredential, GetTokenOptions, AccessToken } from \"@azure/core-http\";\nimport { IdentityClient } from \"../client/identityClient\";\nimport { ClientCertificateCredentialOptions } from \"./clientCertificateCredentialOptions\";\nimport { createSpan } from \"../util/tracing\";\nimport { AuthenticationErrorName } from \"../client/errors\";\nimport { CanonicalCode } from \"@opentelemetry/api\";\nimport { credentialLogger, formatSuccess, formatError } from \"../util/logging\";\nimport { getIdentityTokenEndpointSuffix } from \"../util/identityTokenEndpoint\";\nimport { checkTenantId } from \"../util/checkTenantId\";\n\nconst SelfSignedJwtLifetimeMins = 10;\n\nfunction timestampInSeconds(date: Date): number {\n return Math.floor(date.getTime() / 1000);\n}\n\nfunction addMinutes(date: Date, minutes: number): Date {\n date.setMinutes(date.getMinutes() + minutes);\n return date;\n}\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. More information\n * on how to configure certificate authentication can be found here:\n *\n * https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-certificate-credentials#register-your-certificate-with-azure-ad\n *\n */\nexport class ClientCertificateCredential implements TokenCredential {\n private identityClient: IdentityClient;\n private tenantId: string;\n private clientId: string;\n private certificateString: string;\n private certificateThumbprint: string;\n private certificateX5t: string;\n private certificateX5c?: Array<string>;\n\n /**\n * Creates an instance of the ClientCertificateCredential with the details\n * needed to authenticate against Azure Active Directory with a certificate.\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 certificatePath The path to a PEM-encoded public/private key certificate on the filesystem.\n * @param options Options for configuring the client which makes the authentication request.\n */\n constructor(\n tenantId: string,\n clientId: string,\n certificatePath: string,\n options?: ClientCertificateCredentialOptions\n ) {\n checkTenantId(logger, tenantId);\n\n this.identityClient = new IdentityClient(options);\n this.tenantId = tenantId;\n this.clientId = clientId;\n this.certificateString = readFileSync(certificatePath, \"utf8\");\n\n const certificatePattern = /(-+BEGIN CERTIFICATE-+)(\\n\\r?|\\r\\n?)([A-Za-z0-9+/\\n\\r]+=*)(\\n\\r?|\\r\\n?)(-+END CERTIFICATE-+)/g;\n\n const publicKeys: string[] = [];\n\n // Match all possible certificates, in the order they are in the file. These will form the chain that is used for x5c\n let match;\n do {\n match = certificatePattern.exec(this.certificateString);\n if (match) {\n publicKeys.push(match[3]);\n }\n } while (match);\n\n if (publicKeys.length === 0) {\n const error = new Error(\n \"The file at the specified path does not contain a PEM-encoded certificate.\"\n );\n logger.info(formatError(\"\", error));\n throw error;\n }\n\n this.certificateThumbprint = createHash(\"sha1\")\n .update(Buffer.from(publicKeys[0], \"base64\"))\n .digest(\"hex\")\n .toUpperCase();\n\n this.certificateX5t = Buffer.from(this.certificateThumbprint, \"hex\").toString(\"base64\");\n if (options && options.sendCertificateChain) {\n this.certificateX5c = publicKeys;\n }\n }\n\n /**\n * Authenticates with Azure Active Directory and returns an access token if\n * successful. If authentication cannot be performed at this time, this method may\n * return null. If an error occurs during authentication, an {@link AuthenticationError}\n * containing failure details will be thrown.\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 public async getToken(\n scopes: string | string[],\n options?: GetTokenOptions\n ): Promise<AccessToken | null> {\n const { span, options: newOptions } = createSpan(\n \"ClientCertificateCredential-getToken\",\n options\n );\n try {\n const tokenId = uuidV4();\n const urlSuffix = getIdentityTokenEndpointSuffix(this.tenantId);\n const audienceUrl = `${this.identityClient.authorityHost}/${this.tenantId}/${urlSuffix}`;\n let header: jws.Header;\n\n if (this.certificateX5c) {\n header = {\n typ: \"JWT\",\n alg: \"RS256\",\n x5t: this.certificateX5t,\n x5c: this.certificateX5c\n };\n } else {\n header = {\n typ: \"JWT\",\n alg: \"RS256\",\n x5t: this.certificateX5t\n };\n }\n\n const payload = {\n iss: this.clientId,\n sub: this.clientId,\n aud: audienceUrl,\n jti: tokenId,\n nbf: timestampInSeconds(new Date()),\n exp: timestampInSeconds(addMinutes(new Date(), SelfSignedJwtLifetimeMins))\n };\n\n const clientAssertion = jws.sign({\n header,\n payload,\n secret: this.certificateString\n });\n\n const webResource = this.identityClient.createWebResource({\n url: audienceUrl,\n method: \"POST\",\n disableJsonStringifyOnBody: true,\n deserializationMapper: undefined,\n body: qs.stringify({\n response_type: \"token\",\n grant_type: \"client_credentials\",\n client_id: this.clientId,\n client_assertion_type: \"urn:ietf:params:oauth:client-assertion-type:jwt-bearer\",\n client_assertion: clientAssertion,\n scope: typeof scopes === \"string\" ? scopes : scopes.join(\" \")\n }),\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/x-www-form-urlencoded\"\n },\n abortSignal: options && options.abortSignal,\n spanOptions: newOptions.tracingOptions && newOptions.tracingOptions.spanOptions\n });\n\n const tokenResponse = await this.identityClient.sendTokenRequest(webResource);\n logger.getToken.info(formatSuccess(scopes));\n return (tokenResponse && tokenResponse.accessToken) || null;\n } catch (err) {\n const code =\n err.name === AuthenticationErrorName\n ? CanonicalCode.UNAUTHENTICATED\n : CanonicalCode.UNKNOWN;\n span.setStatus({\n code,\n message: err.message\n });\n logger.getToken.info(formatError(\"\", err));\n throw err;\n } finally {\n span.end();\n }\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
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 \"../client/identityClient\";\n\n/**\n * Defines options for the SubjectNameAndIssuerCredential class.\n */\nexport interface ClientCertificateCredentialOptions extends TokenCredentialOptions {\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
|
|
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 \"../client/identityClient\";\n\n/**\n * Defines options for the SubjectNameAndIssuerCredential class.\n */\nexport interface ClientCertificateCredentialOptions extends TokenCredentialOptions {\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"]}
|
|
@@ -6,7 +6,7 @@ import { IdentityClient } from "../client/identityClient";
|
|
|
6
6
|
import { createSpan } from "../util/tracing";
|
|
7
7
|
import { AuthenticationErrorName } from "../client/errors";
|
|
8
8
|
import { CanonicalCode } from "@opentelemetry/api";
|
|
9
|
-
import { credentialLogger, formatSuccess } from "../util/logging";
|
|
9
|
+
import { credentialLogger, formatError, formatSuccess } from "../util/logging";
|
|
10
10
|
import { getIdentityTokenEndpointSuffix } from "../util/identityTokenEndpoint";
|
|
11
11
|
const logger = credentialLogger("ClientSecretCredential");
|
|
12
12
|
/**
|
|
@@ -80,7 +80,7 @@ export class ClientSecretCredential {
|
|
|
80
80
|
code,
|
|
81
81
|
message: err.message
|
|
82
82
|
});
|
|
83
|
-
logger.getToken.info(err);
|
|
83
|
+
logger.getToken.info(formatError(scopes, err));
|
|
84
84
|
throw err;
|
|
85
85
|
}
|
|
86
86
|
finally {
|