@azure/identity 2.0.0-beta.3 → 2.0.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.

Files changed (149) hide show
  1. package/CHANGELOG.md +232 -6
  2. package/README.md +124 -39
  3. package/dist/index.js +2317 -1596
  4. package/dist/index.js.map +1 -1
  5. package/dist-esm/src/client/identityClient.js +147 -133
  6. package/dist-esm/src/client/identityClient.js.map +1 -1
  7. package/dist-esm/src/constants.js +1 -1
  8. package/dist-esm/src/constants.js.map +1 -1
  9. package/dist-esm/src/credentials/authorizationCodeCredential.browser.js +1 -1
  10. package/dist-esm/src/credentials/authorizationCodeCredential.browser.js.map +1 -1
  11. package/dist-esm/src/credentials/authorizationCodeCredential.js +13 -76
  12. package/dist-esm/src/credentials/authorizationCodeCredential.js.map +1 -1
  13. package/dist-esm/src/credentials/azureApplicationCredential.browser.js +34 -0
  14. package/dist-esm/src/credentials/azureApplicationCredential.browser.js.map +1 -0
  15. package/dist-esm/src/credentials/azureApplicationCredential.js +36 -0
  16. package/dist-esm/src/credentials/azureApplicationCredential.js.map +1 -0
  17. package/dist-esm/src/credentials/azureCliCredential.browser.js +7 -0
  18. package/dist-esm/src/credentials/azureCliCredential.browser.js.map +1 -1
  19. package/dist-esm/src/credentials/azureCliCredential.js +110 -83
  20. package/dist-esm/src/credentials/azureCliCredential.js.map +1 -1
  21. package/dist-esm/src/credentials/azureCliCredentialOptions.js +4 -0
  22. package/dist-esm/src/credentials/azureCliCredentialOptions.js.map +1 -0
  23. package/dist-esm/src/credentials/azurePowerShellCredential.browser.js +3 -1
  24. package/dist-esm/src/credentials/azurePowerShellCredential.browser.js.map +1 -1
  25. package/dist-esm/src/credentials/azurePowerShellCredential.js +93 -83
  26. package/dist-esm/src/credentials/azurePowerShellCredential.js.map +1 -1
  27. package/dist-esm/src/credentials/azurePowerShellCredentialOptions.js +4 -0
  28. package/dist-esm/src/credentials/azurePowerShellCredentialOptions.js.map +1 -0
  29. package/dist-esm/src/credentials/chainedTokenCredential.js +34 -37
  30. package/dist-esm/src/credentials/chainedTokenCredential.js.map +1 -1
  31. package/dist-esm/src/credentials/clientCertificateCredential.browser.js +7 -0
  32. package/dist-esm/src/credentials/clientCertificateCredential.browser.js.map +1 -1
  33. package/dist-esm/src/credentials/clientCertificateCredential.js +24 -23
  34. package/dist-esm/src/credentials/clientCertificateCredential.js.map +1 -1
  35. package/dist-esm/src/credentials/clientCertificateCredentialOptions.js.map +1 -1
  36. package/dist-esm/src/credentials/clientSecretCredential.browser.js +39 -44
  37. package/dist-esm/src/credentials/clientSecretCredential.browser.js.map +1 -1
  38. package/dist-esm/src/credentials/clientSecretCredential.js +9 -11
  39. package/dist-esm/src/credentials/clientSecretCredential.js.map +1 -1
  40. package/dist-esm/src/credentials/clientSecretCredentialOptions.js.map +1 -1
  41. package/dist-esm/src/credentials/credentialPersistenceOptions.js +4 -0
  42. package/dist-esm/src/credentials/credentialPersistenceOptions.js.map +1 -0
  43. package/dist-esm/src/credentials/defaultAzureCredential.browser.js +1 -1
  44. package/dist-esm/src/credentials/defaultAzureCredential.browser.js.map +1 -1
  45. package/dist-esm/src/credentials/defaultAzureCredential.js +50 -27
  46. package/dist-esm/src/credentials/defaultAzureCredential.js.map +1 -1
  47. package/dist-esm/src/credentials/deviceCodeCredential.browser.js +7 -0
  48. package/dist-esm/src/credentials/deviceCodeCredential.browser.js.map +1 -1
  49. package/dist-esm/src/credentials/deviceCodeCredential.js +27 -22
  50. package/dist-esm/src/credentials/deviceCodeCredential.js.map +1 -1
  51. package/dist-esm/src/credentials/deviceCodeCredentialOptions.js.map +1 -1
  52. package/dist-esm/src/credentials/environmentCredential.browser.js +7 -0
  53. package/dist-esm/src/credentials/environmentCredential.browser.js.map +1 -1
  54. package/dist-esm/src/credentials/environmentCredential.js +39 -38
  55. package/dist-esm/src/credentials/environmentCredential.js.map +1 -1
  56. package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js +20 -29
  57. package/dist-esm/src/credentials/interactiveBrowserCredential.browser.js.map +1 -1
  58. package/dist-esm/src/credentials/interactiveBrowserCredential.js +23 -29
  59. package/dist-esm/src/credentials/interactiveBrowserCredential.js.map +1 -1
  60. package/dist-esm/src/credentials/interactiveBrowserCredentialOptions.js.map +1 -1
  61. package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js +36 -22
  62. package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -1
  63. package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +62 -47
  64. package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -1
  65. package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js +33 -22
  66. package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -1
  67. package/dist-esm/src/credentials/managedIdentityCredential/constants.js +2 -1
  68. package/dist-esm/src/credentials/managedIdentityCredential/constants.js.map +1 -1
  69. package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js +42 -27
  70. package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -1
  71. package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +115 -91
  72. package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -1
  73. package/dist-esm/src/credentials/managedIdentityCredential/index.browser.js +3 -6
  74. package/dist-esm/src/credentials/managedIdentityCredential/index.browser.js.map +1 -1
  75. package/dist-esm/src/credentials/managedIdentityCredential/index.js +120 -125
  76. package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -1
  77. package/dist-esm/src/credentials/managedIdentityCredential/models.js.map +1 -1
  78. package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js +82 -0
  79. package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js.map +1 -0
  80. package/dist-esm/src/credentials/managedIdentityCredential/utils.js +14 -8
  81. package/dist-esm/src/credentials/managedIdentityCredential/utils.js.map +1 -1
  82. package/dist-esm/src/credentials/onBehalfOfCredential.browser.js +23 -0
  83. package/dist-esm/src/credentials/onBehalfOfCredential.browser.js.map +1 -0
  84. package/dist-esm/src/credentials/onBehalfOfCredential.js +57 -0
  85. package/dist-esm/src/credentials/onBehalfOfCredential.js.map +1 -0
  86. package/dist-esm/src/credentials/onBehalfOfCredentialOptions.js +4 -0
  87. package/dist-esm/src/credentials/onBehalfOfCredentialOptions.js.map +1 -0
  88. package/dist-esm/src/credentials/usernamePasswordCredential.browser.js +41 -46
  89. package/dist-esm/src/credentials/usernamePasswordCredential.browser.js.map +1 -1
  90. package/dist-esm/src/credentials/usernamePasswordCredential.js +9 -13
  91. package/dist-esm/src/credentials/usernamePasswordCredential.js.map +1 -1
  92. package/dist-esm/src/credentials/usernamePasswordCredentialOptions.js.map +1 -1
  93. package/dist-esm/src/credentials/visualStudioCodeCredential.browser.js +27 -0
  94. package/dist-esm/src/credentials/visualStudioCodeCredential.browser.js.map +1 -0
  95. package/dist-esm/src/credentials/visualStudioCodeCredential.js +183 -0
  96. package/dist-esm/src/credentials/visualStudioCodeCredential.js.map +1 -0
  97. package/dist-esm/src/credentials/visualStudioCodeCredentialPlugin.js +4 -0
  98. package/dist-esm/src/credentials/visualStudioCodeCredentialPlugin.js.map +1 -0
  99. package/dist-esm/src/{client/errors.js → errors.js} +16 -1
  100. package/dist-esm/src/errors.js.map +1 -0
  101. package/dist-esm/src/index.js +4 -2
  102. package/dist-esm/src/index.js.map +1 -1
  103. package/dist-esm/src/msal/browserFlows/browserCommon.js +33 -31
  104. package/dist-esm/src/msal/browserFlows/browserCommon.js.map +1 -1
  105. package/dist-esm/src/msal/browserFlows/msalAuthCode.js +113 -115
  106. package/dist-esm/src/msal/browserFlows/msalAuthCode.js.map +1 -1
  107. package/dist-esm/src/msal/credentials.js.map +1 -1
  108. package/dist-esm/src/msal/flows.js.map +1 -1
  109. package/dist-esm/src/msal/nodeFlows/msalAuthorizationCode.js +41 -0
  110. package/dist-esm/src/msal/nodeFlows/msalAuthorizationCode.js.map +1 -0
  111. package/dist-esm/src/msal/nodeFlows/msalClientCertificate.js +65 -46
  112. package/dist-esm/src/msal/nodeFlows/msalClientCertificate.js.map +1 -1
  113. package/dist-esm/src/msal/nodeFlows/msalClientSecret.js +15 -16
  114. package/dist-esm/src/msal/nodeFlows/msalClientSecret.js.map +1 -1
  115. package/dist-esm/src/msal/nodeFlows/msalDeviceCode.js +20 -22
  116. package/dist-esm/src/msal/nodeFlows/msalDeviceCode.js.map +1 -1
  117. package/dist-esm/src/msal/nodeFlows/msalOnBehalfOf.js +56 -0
  118. package/dist-esm/src/msal/nodeFlows/msalOnBehalfOf.js.map +1 -0
  119. package/dist-esm/src/msal/nodeFlows/msalOpenBrowser.js +44 -33
  120. package/dist-esm/src/msal/nodeFlows/msalOpenBrowser.js.map +1 -1
  121. package/dist-esm/src/msal/nodeFlows/msalUsernamePassword.js +15 -17
  122. package/dist-esm/src/msal/nodeFlows/msalUsernamePassword.js.map +1 -1
  123. package/dist-esm/src/msal/nodeFlows/nodeCommon.js +141 -98
  124. package/dist-esm/src/msal/nodeFlows/nodeCommon.js.map +1 -1
  125. package/dist-esm/src/msal/nodeFlows/tokenCachePersistenceOptions.js +4 -0
  126. package/dist-esm/src/msal/nodeFlows/tokenCachePersistenceOptions.js.map +1 -0
  127. package/dist-esm/src/msal/utils.js +23 -15
  128. package/dist-esm/src/msal/utils.js.map +1 -1
  129. package/dist-esm/src/plugins/consumer.browser.js +7 -0
  130. package/dist-esm/src/plugins/consumer.browser.js.map +1 -0
  131. package/dist-esm/src/plugins/consumer.js +44 -0
  132. package/dist-esm/src/plugins/consumer.js.map +1 -0
  133. package/dist-esm/src/plugins/provider.js +4 -0
  134. package/dist-esm/src/plugins/provider.js.map +1 -0
  135. package/dist-esm/src/regionalAuthority.js +115 -0
  136. package/dist-esm/src/regionalAuthority.js.map +1 -0
  137. package/dist-esm/src/util/tracing.js +24 -27
  138. package/dist-esm/src/util/tracing.js.map +1 -1
  139. package/dist-esm/src/util/validateMultiTenant.browser.js +22 -0
  140. package/dist-esm/src/util/validateMultiTenant.browser.js.map +1 -0
  141. package/dist-esm/src/util/validateMultiTenant.js +29 -0
  142. package/dist-esm/src/util/validateMultiTenant.js.map +1 -0
  143. package/package.json +44 -28
  144. package/types/identity.d.ts +482 -126
  145. package/dist-esm/src/client/errors.js.map +0 -1
  146. package/dist-esm/src/msal/errors.js +0 -22
  147. package/dist-esm/src/msal/errors.js.map +0 -1
  148. package/dist-esm/src/util/authHostEnv.js +0 -13
  149. package/dist-esm/src/util/authHostEnv.js.map +0 -1
@@ -1,29 +1,38 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { __awaiter } from "tslib";
3
+ import { createHttpHeaders, createPipelineRequest } from "@azure/core-rest-pipeline";
4
+ import { readFile } from "fs";
4
5
  import { credentialLogger } from "../../util/logging";
5
- import { msiGenericGetToken } from "./utils";
6
+ import { mapScopesToResource, msiGenericGetToken } from "./utils";
6
7
  import { azureArcAPIVersion } from "./constants";
7
- import { AuthenticationError } from "../../client/errors";
8
- import { readFile } from "fs";
9
- const logger = credentialLogger("ManagedIdentityCredential - ArcMSI");
8
+ import { AuthenticationError } from "../../errors";
9
+ const msiName = "ManagedIdentityCredential - Azure Arc MSI";
10
+ const logger = credentialLogger(msiName);
10
11
  // Azure Arc MSI doesn't have a special expiresIn parser.
11
12
  const expiresInParser = undefined;
12
- function prepareRequestOptions(resource) {
13
+ function prepareRequestOptions(scopes) {
14
+ const resource = mapScopesToResource(scopes);
15
+ if (!resource) {
16
+ throw new Error(`${msiName}: Multiple scopes are not supported.`);
17
+ }
13
18
  const queryParameters = {
14
19
  resource,
15
20
  "api-version": azureArcAPIVersion
16
21
  };
17
- return {
22
+ const query = new URLSearchParams(queryParameters);
23
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
24
+ if (!process.env.IDENTITY_ENDPOINT) {
25
+ throw new Error(`${msiName}: Missing environment variable: IDENTITY_ENDPOINT`);
26
+ }
27
+ return createPipelineRequest({
18
28
  // Should be similar to: http://localhost:40342/metadata/identity/oauth2/token
19
- url: process.env.IDENTITY_ENDPOINT,
29
+ url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
20
30
  method: "GET",
21
- queryParameters,
22
- headers: {
31
+ headers: createHttpHeaders({
23
32
  Accept: "application/json",
24
- Metadata: true
25
- }
26
- };
33
+ Metadata: "true"
34
+ })
35
+ });
27
36
  }
28
37
  // Since "fs"'s readFileSync locks the thread, and to avoid extra dependencies.
29
38
  function readFileAsync(path, options) {
@@ -34,45 +43,51 @@ function readFileAsync(path, options) {
34
43
  resolve(data);
35
44
  }));
36
45
  }
37
- function filePathRequest(identityClient, requestPrepareOptions) {
38
- return __awaiter(this, void 0, void 0, function* () {
39
- const response = yield identityClient.sendRequest(identityClient.createWebResource(requestPrepareOptions));
40
- if (response.status !== 401) {
41
- let message = "";
42
- if (response.bodyAsText) {
43
- message = ` Response: ${response.bodyAsText}`;
44
- }
45
- throw new AuthenticationError(response.status, `To authenticate with Azure Arc MSI, status code 401 is expected on the first request.${message}`);
46
+ async function filePathRequest(identityClient, requestPrepareOptions) {
47
+ const response = await identityClient.sendRequest(createPipelineRequest(requestPrepareOptions));
48
+ if (response.status !== 401) {
49
+ let message = "";
50
+ if (response.bodyAsText) {
51
+ message = ` Response: ${response.bodyAsText}`;
46
52
  }
47
- const authHeader = response.headers.get("www-authenticate") || "";
53
+ throw new AuthenticationError(response.status, `${msiName}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`);
54
+ }
55
+ const authHeader = response.headers.get("www-authenticate") || "";
56
+ try {
48
57
  return authHeader.split("=").slice(1)[0];
49
- });
58
+ }
59
+ catch (e) {
60
+ throw Error(`Invalid www-authenticate header format: ${authHeader}`);
61
+ }
50
62
  }
51
63
  export const arcMsi = {
52
- isAvailable() {
53
- return __awaiter(this, void 0, void 0, function* () {
54
- const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
55
- if (!result) {
56
- logger.info("The Azure Arc MSI is unavailable.");
57
- }
58
- return result;
59
- });
64
+ async isAvailable(scopes) {
65
+ const resource = mapScopesToResource(scopes);
66
+ if (!resource) {
67
+ logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
68
+ return false;
69
+ }
70
+ const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
71
+ if (!result) {
72
+ logger.info(`${msiName}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
73
+ }
74
+ return result;
60
75
  },
61
- getToken(identityClient, resource, clientId, getTokenOptions = {}) {
62
- return __awaiter(this, void 0, void 0, function* () {
63
- logger.info(`Using the Azure Arc MSI to authenticate.`);
64
- if (clientId) {
65
- throw new Error("User assigned identity is not supported by the Azure Arc Managed Identity Endpoint. To authenticate with the system assigned identity omit the client id when constructing the ManagedIdentityCredential, or if authenticating with the DefaultAzureCredential ensure the AZURE_CLIENT_ID environment variable is not set.");
66
- }
67
- const requestOptions = Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal, spanOptions: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.spanOptions }, prepareRequestOptions(resource));
68
- const filePath = yield filePathRequest(identityClient, requestOptions);
69
- if (!filePath) {
70
- throw new Error("Azure Arc MSI failed to find the token file.");
71
- }
72
- const key = yield readFileAsync(filePath, { encoding: "utf-8" });
73
- requestOptions.headers["Authorization"] = `Basic ${key}`;
74
- return msiGenericGetToken(identityClient, requestOptions, expiresInParser, getTokenOptions);
75
- });
76
+ async getToken(configuration, getTokenOptions = {}) {
77
+ var _a;
78
+ const { identityClient, scopes, clientId } = configuration;
79
+ logger.info(`${msiName}: Authenticating.`);
80
+ if (clientId) {
81
+ throw new Error(`${msiName}: User assigned identity is not supported by the Azure Arc Managed Identity Endpoint. To authenticate with the system assigned identity, omit the client id when constructing the ManagedIdentityCredential, or if authenticating with the DefaultAzureCredential ensure the AZURE_CLIENT_ID environment variable is not set.`);
82
+ }
83
+ const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes)), { allowInsecureConnection: true });
84
+ const filePath = await filePathRequest(identityClient, requestOptions);
85
+ if (!filePath) {
86
+ throw new Error(`${msiName}: Failed to find the token file.`);
87
+ }
88
+ const key = await readFileAsync(filePath, { encoding: "utf-8" });
89
+ (_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
90
+ return msiGenericGetToken(identityClient, requestOptions, expiresInParser, getTokenOptions);
76
91
  }
77
92
  };
78
93
  //# sourceMappingURL=arcMsi.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"arcMsi.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/arcMsi.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions, RequestPrepareOptions } from \"@azure/core-http\";\nimport { MSI } from \"./models\";\nimport { credentialLogger } from \"../../util/logging\";\nimport { IdentityClient } from \"../../client/identityClient\";\nimport { msiGenericGetToken } from \"./utils\";\nimport { azureArcAPIVersion } from \"./constants\";\nimport { AuthenticationError } from \"../../client/errors\";\nimport { readFile } from \"fs\";\n\nconst logger = credentialLogger(\"ManagedIdentityCredential - ArcMSI\");\n\n// Azure Arc MSI doesn't have a special expiresIn parser.\nconst expiresInParser = undefined;\n\nfunction prepareRequestOptions(resource?: string): RequestPrepareOptions {\n const queryParameters: any = {\n resource,\n \"api-version\": azureArcAPIVersion\n };\n\n return {\n // Should be similar to: http://localhost:40342/metadata/identity/oauth2/token\n url: process.env.IDENTITY_ENDPOINT,\n method: \"GET\",\n queryParameters,\n headers: {\n Accept: \"application/json\",\n Metadata: true\n }\n };\n}\n\n// Since \"fs\"'s readFileSync locks the thread, and to avoid extra dependencies.\nfunction readFileAsync(path: string, options: { encoding: string }): Promise<string> {\n return new Promise((resolve, reject) =>\n readFile(path, options, (err, data) => {\n if (err) {\n reject(err);\n }\n resolve(data);\n })\n );\n}\n\nasync function filePathRequest(\n identityClient: IdentityClient,\n requestPrepareOptions: RequestPrepareOptions\n): Promise<string | undefined> {\n const response = await identityClient.sendRequest(\n identityClient.createWebResource(requestPrepareOptions)\n );\n\n if (response.status !== 401) {\n let message = \"\";\n if (response.bodyAsText) {\n message = ` Response: ${response.bodyAsText}`;\n }\n throw new AuthenticationError(\n response.status,\n `To authenticate with Azure Arc MSI, status code 401 is expected on the first request.${message}`\n );\n }\n\n const authHeader = response.headers.get(\"www-authenticate\") || \"\";\n return authHeader.split(\"=\").slice(1)[0];\n}\n\nexport const arcMsi: MSI = {\n async isAvailable(): Promise<boolean> {\n const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);\n if (!result) {\n logger.info(\"The Azure Arc MSI is unavailable.\");\n }\n return result;\n },\n async getToken(\n identityClient: IdentityClient,\n resource?: string,\n clientId?: string,\n getTokenOptions: GetTokenOptions = {}\n ): Promise<AccessToken | null> {\n logger.info(`Using the Azure Arc MSI to authenticate.`);\n\n if (clientId) {\n throw new Error(\n \"User assigned identity is not supported by the Azure Arc Managed Identity Endpoint. To authenticate with the system assigned identity omit the client id when constructing the ManagedIdentityCredential, or if authenticating with the DefaultAzureCredential ensure the AZURE_CLIENT_ID environment variable is not set.\"\n );\n }\n\n const requestOptions = {\n disableJsonStringifyOnBody: true,\n deserializationMapper: undefined,\n abortSignal: getTokenOptions.abortSignal,\n spanOptions: getTokenOptions.tracingOptions && getTokenOptions.tracingOptions.spanOptions,\n ...prepareRequestOptions(resource)\n };\n\n const filePath = await filePathRequest(identityClient, requestOptions);\n\n if (!filePath) {\n throw new Error(\"Azure Arc MSI failed to find the token file.\");\n }\n\n const key = await readFileAsync(filePath, { encoding: \"utf-8\" });\n requestOptions.headers![\"Authorization\"] = `Basic ${key}`;\n\n return msiGenericGetToken(identityClient, requestOptions, expiresInParser, getTokenOptions);\n }\n};\n"]}
1
+ {"version":3,"file":"arcMsi.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/arcMsi.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport {\n createHttpHeaders,\n createPipelineRequest,\n PipelineRequestOptions\n} from \"@azure/core-rest-pipeline\";\nimport { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { readFile } from \"fs\";\nimport { MSI, MSIConfiguration } from \"./models\";\nimport { credentialLogger } from \"../../util/logging\";\nimport { IdentityClient } from \"../../client/identityClient\";\nimport { mapScopesToResource, msiGenericGetToken } from \"./utils\";\nimport { azureArcAPIVersion } from \"./constants\";\nimport { AuthenticationError } from \"../../errors\";\n\nconst msiName = \"ManagedIdentityCredential - Azure Arc MSI\";\nconst logger = credentialLogger(msiName);\n\n// Azure Arc MSI doesn't have a special expiresIn parser.\nconst expiresInParser = undefined;\n\nfunction prepareRequestOptions(scopes: string | string[]): PipelineRequestOptions {\n const resource = mapScopesToResource(scopes);\n if (!resource) {\n throw new Error(`${msiName}: Multiple scopes are not supported.`);\n }\n const queryParameters: any = {\n resource,\n \"api-version\": azureArcAPIVersion\n };\n\n const query = new URLSearchParams(queryParameters);\n\n // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.\n if (!process.env.IDENTITY_ENDPOINT) {\n throw new Error(`${msiName}: Missing environment variable: IDENTITY_ENDPOINT`);\n }\n\n return createPipelineRequest({\n // Should be similar to: http://localhost:40342/metadata/identity/oauth2/token\n url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,\n method: \"GET\",\n headers: createHttpHeaders({\n Accept: \"application/json\",\n Metadata: \"true\"\n })\n });\n}\n\n// Since \"fs\"'s readFileSync locks the thread, and to avoid extra dependencies.\nfunction readFileAsync(path: string, options: { encoding: string }): Promise<string> {\n return new Promise((resolve, reject) =>\n readFile(path, options, (err, data) => {\n if (err) {\n reject(err);\n }\n resolve(data);\n })\n );\n}\n\nasync function filePathRequest(\n identityClient: IdentityClient,\n requestPrepareOptions: PipelineRequestOptions\n): Promise<string | undefined> {\n const response = await identityClient.sendRequest(createPipelineRequest(requestPrepareOptions));\n\n if (response.status !== 401) {\n let message = \"\";\n if (response.bodyAsText) {\n message = ` Response: ${response.bodyAsText}`;\n }\n throw new AuthenticationError(\n response.status,\n `${msiName}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`\n );\n }\n\n const authHeader = response.headers.get(\"www-authenticate\") || \"\";\n try {\n return authHeader.split(\"=\").slice(1)[0];\n } catch (e) {\n throw Error(`Invalid www-authenticate header format: ${authHeader}`);\n }\n}\n\nexport const arcMsi: MSI = {\n async isAvailable(scopes): Promise<boolean> {\n const resource = mapScopesToResource(scopes);\n if (!resource) {\n logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);\n return false;\n }\n const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);\n if (!result) {\n logger.info(\n `${msiName}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`\n );\n }\n return result;\n },\n async getToken(\n configuration: MSIConfiguration,\n getTokenOptions: GetTokenOptions = {}\n ): Promise<AccessToken | null> {\n const { identityClient, scopes, clientId } = configuration;\n\n logger.info(`${msiName}: Authenticating.`);\n\n if (clientId) {\n throw new Error(\n `${msiName}: User assigned identity is not supported by the Azure Arc Managed Identity Endpoint. To authenticate with the system assigned identity, omit the client id when constructing the ManagedIdentityCredential, or if authenticating with the DefaultAzureCredential ensure the AZURE_CLIENT_ID environment variable is not set.`\n );\n }\n\n const requestOptions = {\n disableJsonStringifyOnBody: true,\n deserializationMapper: undefined,\n abortSignal: getTokenOptions.abortSignal,\n ...prepareRequestOptions(scopes),\n allowInsecureConnection: true\n };\n\n const filePath = await filePathRequest(identityClient, requestOptions);\n\n if (!filePath) {\n throw new Error(`${msiName}: Failed to find the token file.`);\n }\n\n const key = await readFileAsync(filePath, { encoding: \"utf-8\" });\n requestOptions.headers?.set(\"Authorization\", `Basic ${key}`);\n\n return msiGenericGetToken(identityClient, requestOptions, expiresInParser, getTokenOptions);\n }\n};\n"]}
@@ -1,45 +1,56 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { __awaiter } from "tslib";
4
- import qs from "qs";
3
+ import { createHttpHeaders } from "@azure/core-rest-pipeline";
5
4
  import { credentialLogger } from "../../util/logging";
6
- import { msiGenericGetToken } from "./utils";
7
- const logger = credentialLogger("ManagedIdentityCredential - CloudShellMSI");
5
+ import { mapScopesToResource, msiGenericGetToken } from "./utils";
6
+ const msiName = "ManagedIdentityCredential - CloudShellMSI";
7
+ const logger = credentialLogger(msiName);
8
8
  // Cloud Shell MSI doesn't have a special expiresIn parser.
9
9
  const expiresInParser = undefined;
10
- function prepareRequestOptions(resource, clientId) {
10
+ function prepareRequestOptions(scopes, clientId) {
11
+ const resource = mapScopesToResource(scopes);
12
+ if (!resource) {
13
+ throw new Error(`${msiName}: Multiple scopes are not supported.`);
14
+ }
11
15
  const body = {
12
16
  resource
13
17
  };
14
18
  if (clientId) {
15
19
  body.client_id = clientId;
16
20
  }
21
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
22
+ if (!process.env.MSI_ENDPOINT) {
23
+ throw new Error(`${msiName}: Missing environment variable: MSI_ENDPOINT`);
24
+ }
25
+ const params = new URLSearchParams(body);
17
26
  return {
18
27
  url: process.env.MSI_ENDPOINT,
19
28
  method: "POST",
20
- body: qs.stringify(body),
21
- headers: {
29
+ body: params.toString(),
30
+ headers: createHttpHeaders({
22
31
  Accept: "application/json",
23
- Metadata: true,
32
+ Metadata: "true",
24
33
  "Content-Type": "application/x-www-form-urlencoded"
25
- }
34
+ })
26
35
  };
27
36
  }
28
37
  export const cloudShellMsi = {
29
- isAvailable() {
30
- return __awaiter(this, void 0, void 0, function* () {
31
- const result = Boolean(process.env.MSI_ENDPOINT);
32
- if (!result) {
33
- logger.info("The Azure Cloud Shell MSI is unavailable.");
34
- }
35
- return result;
36
- });
38
+ async isAvailable(scopes) {
39
+ const resource = mapScopesToResource(scopes);
40
+ if (!resource) {
41
+ logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
42
+ return false;
43
+ }
44
+ const result = Boolean(process.env.MSI_ENDPOINT);
45
+ if (!result) {
46
+ logger.info(`${msiName}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
47
+ }
48
+ return result;
37
49
  },
38
- getToken(identityClient, resource, clientId, getTokenOptions = {}) {
39
- return __awaiter(this, void 0, void 0, function* () {
40
- logger.info(`Using the endpoint coming form the environment variable MSI_ENDPOINT=${process.env.MSI_ENDPOINT}, and using the Cloud Shell to proceed with the authentication.`);
41
- return msiGenericGetToken(identityClient, prepareRequestOptions(resource, clientId), expiresInParser, getTokenOptions);
42
- });
50
+ async getToken(configuration, getTokenOptions = {}) {
51
+ const { identityClient, scopes, clientId } = configuration;
52
+ logger.info(`${msiName}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
53
+ return msiGenericGetToken(identityClient, prepareRequestOptions(scopes, clientId), expiresInParser, getTokenOptions);
43
54
  }
44
55
  };
45
56
  //# sourceMappingURL=cloudShellMsi.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cloudShellMsi.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/cloudShellMsi.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAElC,OAAO,EAAE,MAAM,IAAI,CAAC;AAGpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,MAAM,GAAG,gBAAgB,CAAC,2CAA2C,CAAC,CAAC;AAE7E,2DAA2D;AAC3D,MAAM,eAAe,GAAG,SAAS,CAAC;AAElC,SAAS,qBAAqB,CAAC,QAAgB,EAAE,QAAiB;IAChE,MAAM,IAAI,GAAQ;QAChB,QAAQ;KACT,CAAC;IAEF,IAAI,QAAQ,EAAE;QACZ,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;KAC3B;IAED,OAAO;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QAC7B,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC;QACxB,OAAO,EAAE;YACP,MAAM,EAAE,kBAAkB;YAC1B,QAAQ,EAAE,IAAI;YACd,cAAc,EAAE,mCAAmC;SACpD;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAQ;IAC1B,WAAW;;YACf,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,EAAE;gBACX,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;aAC1D;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;KAAA;IACK,QAAQ,CACZ,cAA8B,EAC9B,QAAgB,EAChB,QAAiB,EACjB,kBAAmC,EAAE;;YAErC,MAAM,CAAC,IAAI,CACT,wEAAwE,OAAO,CAAC,GAAG,CAAC,YAAY,iEAAiE,CAClK,CAAC;YAEF,OAAO,kBAAkB,CACvB,cAAc,EACd,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EACzC,eAAe,EACf,eAAe,CAChB,CAAC;QACJ,CAAC;KAAA;CACF,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport qs from \"qs\";\nimport { AccessToken, GetTokenOptions, RequestPrepareOptions } from \"@azure/core-http\";\nimport { MSI } from \"./models\";\nimport { credentialLogger } from \"../../util/logging\";\nimport { IdentityClient } from \"../../client/identityClient\";\nimport { msiGenericGetToken } from \"./utils\";\n\nconst logger = credentialLogger(\"ManagedIdentityCredential - CloudShellMSI\");\n\n// Cloud Shell MSI doesn't have a special expiresIn parser.\nconst expiresInParser = undefined;\n\nfunction prepareRequestOptions(resource: string, clientId?: string): RequestPrepareOptions {\n const body: any = {\n resource\n };\n\n if (clientId) {\n body.client_id = clientId;\n }\n\n return {\n url: process.env.MSI_ENDPOINT,\n method: \"POST\",\n body: qs.stringify(body),\n headers: {\n Accept: \"application/json\",\n Metadata: true,\n \"Content-Type\": \"application/x-www-form-urlencoded\"\n }\n };\n}\n\nexport const cloudShellMsi: MSI = {\n async isAvailable(): Promise<boolean> {\n const result = Boolean(process.env.MSI_ENDPOINT);\n if (!result) {\n logger.info(\"The Azure Cloud Shell MSI is unavailable.\");\n }\n return result;\n },\n async getToken(\n identityClient: IdentityClient,\n resource: string,\n clientId?: string,\n getTokenOptions: GetTokenOptions = {}\n ): Promise<AccessToken | null> {\n logger.info(\n `Using the endpoint coming form the environment variable MSI_ENDPOINT=${process.env.MSI_ENDPOINT}, and using the Cloud Shell to proceed with the authentication.`\n );\n\n return msiGenericGetToken(\n identityClient,\n prepareRequestOptions(resource, clientId),\n expiresInParser,\n getTokenOptions\n );\n }\n};\n"]}
1
+ {"version":3,"file":"cloudShellMsi.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/cloudShellMsi.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,iBAAiB,EAA0B,MAAM,2BAA2B,CAAC;AAGtF,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElE,MAAM,OAAO,GAAG,2CAA2C,CAAC;AAC5D,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAEzC,2DAA2D;AAC3D,MAAM,eAAe,GAAG,SAAS,CAAC;AAElC,SAAS,qBAAqB,CAC5B,MAAyB,EACzB,QAAiB;IAEjB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,QAAQ,EAAE;QACb,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,sCAAsC,CAAC,CAAC;KACnE;IAED,MAAM,IAAI,GAAQ;QAChB,QAAQ;KACT,CAAC;IAEF,IAAI,QAAQ,EAAE;QACZ,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;KAC3B;IAED,wIAAwI;IACxI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE;QAC7B,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,8CAA8C,CAAC,CAAC;KAC3E;IACD,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY;QAC7B,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,MAAM,CAAC,QAAQ,EAAE;QACvB,OAAO,EAAE,iBAAiB,CAAC;YACzB,MAAM,EAAE,kBAAkB;YAC1B,QAAQ,EAAE,MAAM;YAChB,cAAc,EAAE,mCAAmC;SACpD,CAAC;KACH,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAQ;IAChC,KAAK,CAAC,WAAW,CAAC,MAAM;QACtB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,CAAC,QAAQ,EAAE;YACb,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,mDAAmD,CAAC,CAAC;YAC3E,OAAO,KAAK,CAAC;SACd;QACD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,EAAE;YACX,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,iEAAiE,CAAC,CAAC;SAC1F;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,KAAK,CAAC,QAAQ,CACZ,aAA+B,EAC/B,kBAAmC,EAAE;QAErC,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC;QAE3D,MAAM,CAAC,IAAI,CACT,GAAG,OAAO,4EAA4E,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,CAClH,CAAC;QAEF,OAAO,kBAAkB,CACvB,cAAc,EACd,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,EACvC,eAAe,EACf,eAAe,CAChB,CAAC;IACJ,CAAC;CACF,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { createHttpHeaders, PipelineRequestOptions } from \"@azure/core-rest-pipeline\";\nimport { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { MSI, MSIConfiguration } from \"./models\";\nimport { credentialLogger } from \"../../util/logging\";\nimport { mapScopesToResource, msiGenericGetToken } from \"./utils\";\n\nconst msiName = \"ManagedIdentityCredential - CloudShellMSI\";\nconst logger = credentialLogger(msiName);\n\n// Cloud Shell MSI doesn't have a special expiresIn parser.\nconst expiresInParser = undefined;\n\nfunction prepareRequestOptions(\n scopes: string | string[],\n clientId?: string\n): PipelineRequestOptions {\n const resource = mapScopesToResource(scopes);\n if (!resource) {\n throw new Error(`${msiName}: Multiple scopes are not supported.`);\n }\n\n const body: any = {\n resource\n };\n\n if (clientId) {\n body.client_id = clientId;\n }\n\n // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.\n if (!process.env.MSI_ENDPOINT) {\n throw new Error(`${msiName}: Missing environment variable: MSI_ENDPOINT`);\n }\n const params = new URLSearchParams(body);\n return {\n url: process.env.MSI_ENDPOINT,\n method: \"POST\",\n body: params.toString(),\n headers: createHttpHeaders({\n Accept: \"application/json\",\n Metadata: \"true\",\n \"Content-Type\": \"application/x-www-form-urlencoded\"\n })\n };\n}\n\nexport const cloudShellMsi: MSI = {\n async isAvailable(scopes): Promise<boolean> {\n const resource = mapScopesToResource(scopes);\n if (!resource) {\n logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);\n return false;\n }\n const result = Boolean(process.env.MSI_ENDPOINT);\n if (!result) {\n logger.info(`${msiName}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);\n }\n return result;\n },\n async getToken(\n configuration: MSIConfiguration,\n getTokenOptions: GetTokenOptions = {}\n ): Promise<AccessToken | null> {\n const { identityClient, scopes, clientId } = configuration;\n\n logger.info(\n `${msiName}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`\n );\n\n return msiGenericGetToken(\n identityClient,\n prepareRequestOptions(scopes, clientId),\n expiresInParser,\n getTokenOptions\n );\n }\n};\n"]}
@@ -1,7 +1,8 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
3
  export const DefaultScopeSuffix = "/.default";
4
- export const imdsEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token";
4
+ export const imdsHost = "http://169.254.169.254";
5
+ export const imdsEndpointPath = "/metadata/identity/oauth2/token";
5
6
  export const imdsApiVersion = "2018-02-01";
6
7
  export const azureArcAPIVersion = "2019-11-01";
7
8
  export const azureFabricVersion = "2019-07-01-preview";
@@ -1 +1 @@
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;AAE9C,MAAM,CAAC,MAAM,YAAY,GAAG,uDAAuD,CAAC;AACpF,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\";\n\nexport const imdsEndpoint = \"http://169.254.169.254/metadata/identity/oauth2/token\";\nexport const imdsApiVersion = \"2018-02-01\";\nexport const azureArcAPIVersion = \"2019-11-01\";\nexport const azureFabricVersion = \"2019-07-01-preview\";\n"]}
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;AAE9C,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\";\n\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"]}
@@ -1,15 +1,20 @@
1
1
  // Copyright (c) Microsoft Corporation.
2
2
  // Licensed under the MIT license.
3
- import { __awaiter } from "tslib";
3
+ import { createHttpHeaders } from "@azure/core-rest-pipeline";
4
4
  import { credentialLogger } from "../../util/logging";
5
- import { msiGenericGetToken } from "./utils";
5
+ import { mapScopesToResource, msiGenericGetToken } from "./utils";
6
6
  import { azureFabricVersion } from "./constants";
7
- const logger = credentialLogger("ManagedIdentityCredential - Fabric MSI");
7
+ const msiName = "ManagedIdentityCredential - Fabric MSI";
8
+ const logger = credentialLogger(msiName);
8
9
  function expiresInParser(requestBody) {
9
10
  // Parses a string representation of the seconds since epoch into a number value
10
11
  return Number(requestBody.expires_on);
11
12
  }
12
- function prepareRequestOptions(resource, clientId) {
13
+ function prepareRequestOptions(scopes, clientId) {
14
+ const resource = mapScopesToResource(scopes);
15
+ if (!resource) {
16
+ throw new Error(`${msiName}: Multiple scopes are not supported.`);
17
+ }
13
18
  const queryParameters = {
14
19
  resource,
15
20
  "api-version": azureFabricVersion
@@ -17,14 +22,21 @@ function prepareRequestOptions(resource, clientId) {
17
22
  if (clientId) {
18
23
  queryParameters.client_id = clientId;
19
24
  }
25
+ const query = new URLSearchParams(queryParameters);
26
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
27
+ if (!process.env.IDENTITY_ENDPOINT) {
28
+ throw new Error("Missing environment variable: IDENTITY_ENDPOINT");
29
+ }
30
+ if (!process.env.IDENTITY_HEADER) {
31
+ throw new Error("Missing environment variable: IDENTITY_HEADER");
32
+ }
20
33
  return {
21
- url: process.env.IDENTITY_ENDPOINT,
34
+ url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
22
35
  method: "GET",
23
- queryParameters,
24
- headers: {
36
+ headers: createHttpHeaders({
25
37
  Accept: "application/json",
26
38
  Secret: process.env.IDENTITY_HEADER
27
- }
39
+ })
28
40
  };
29
41
  }
30
42
  // This credential can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
@@ -38,26 +50,29 @@ function prepareRequestOptions(resource, clientId) {
38
50
  // curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
39
51
  //
40
52
  export const fabricMsi = {
41
- isAvailable() {
42
- return __awaiter(this, void 0, void 0, function* () {
43
- const env = process.env;
44
- const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
45
- if (!result) {
46
- logger.info("The Azure App Service Fabric MSI is unavailable.");
47
- }
48
- return result;
49
- });
53
+ async isAvailable(scopes) {
54
+ const resource = mapScopesToResource(scopes);
55
+ if (!resource) {
56
+ logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
57
+ return false;
58
+ }
59
+ const env = process.env;
60
+ const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
61
+ if (!result) {
62
+ logger.info(`${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
63
+ }
64
+ return result;
50
65
  },
51
- getToken(identityClient, resource, clientId, getTokenOptions = {}) {
52
- return __awaiter(this, void 0, void 0, function* () {
53
- logger.info([
54
- "Using the endpoint and the secret coming from the environment variables:",
55
- `IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
56
- "IDENTITY_HEADER=[REDACTED] and",
57
- "IDENTITY_SERVER_THUMBPRINT=[REDACTED]."
58
- ].join(" "));
59
- return msiGenericGetToken(identityClient, prepareRequestOptions(resource, clientId), expiresInParser, getTokenOptions);
60
- });
66
+ async getToken(configuration, getTokenOptions = {}) {
67
+ const { identityClient, scopes, clientId } = configuration;
68
+ logger.info([
69
+ `${msiName}:`,
70
+ "Using the endpoint and the secret coming from the environment variables:",
71
+ `IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
72
+ "IDENTITY_HEADER=[REDACTED] and",
73
+ "IDENTITY_SERVER_THUMBPRINT=[REDACTED]."
74
+ ].join(" "));
75
+ return msiGenericGetToken(identityClient, prepareRequestOptions(scopes, clientId), expiresInParser, getTokenOptions);
61
76
  }
62
77
  };
63
78
  //# sourceMappingURL=fabricMsi.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fabricMsi.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/fabricMsi.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAIlC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,MAAM,GAAG,gBAAgB,CAAC,wCAAwC,CAAC,CAAC;AAE1E,SAAS,eAAe,CAAC,WAAgB;IACvC,gFAAgF;IAChF,OAAO,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,qBAAqB,CAAC,QAAgB,EAAE,QAAiB;IAChE,MAAM,eAAe,GAAQ;QAC3B,QAAQ;QACR,aAAa,EAAE,kBAAkB;KAClC,CAAC;IAEF,IAAI,QAAQ,EAAE;QACZ,eAAe,CAAC,SAAS,GAAG,QAAQ,CAAC;KACtC;IAED,OAAO;QACL,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAClC,MAAM,EAAE,KAAK;QACb,eAAe;QACf,OAAO,EAAE;YACP,MAAM,EAAE,kBAAkB;YAC1B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe;SACpC;KACF,CAAC;AACJ,CAAC;AAED,6GAA6G;AAC7G,EAAE;AACF,iBAAiB;AACjB,2CAA2C;AAC3C,4BAA4B;AAC5B,EAAE;AACF,kCAAkC;AAClC,EAAE;AACF,wIAAwI;AACxI,EAAE;AAEF,MAAM,CAAC,MAAM,SAAS,GAAQ;IACtB,WAAW;;YACf,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;YACxB,MAAM,MAAM,GAAG,OAAO,CACpB,GAAG,CAAC,iBAAiB,IAAI,GAAG,CAAC,eAAe,IAAI,GAAG,CAAC,0BAA0B,CAC/E,CAAC;YACF,IAAI,CAAC,MAAM,EAAE;gBACX,MAAM,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAC;aACjE;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;KAAA;IACK,QAAQ,CACZ,cAA8B,EAC9B,QAAgB,EAChB,QAAiB,EACjB,kBAAmC,EAAE;;YAErC,MAAM,CAAC,IAAI,CACT;gBACE,0EAA0E;gBAC1E,qBAAqB,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG;gBACrD,gCAAgC;gBAChC,wCAAwC;aACzC,CAAC,IAAI,CAAC,GAAG,CAAC,CACZ,CAAC;YAEF,OAAO,kBAAkB,CACvB,cAAc,EACd,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EACzC,eAAe,EACf,eAAe,CAChB,CAAC;QACJ,CAAC;KAAA;CACF,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { AccessToken, GetTokenOptions, RequestPrepareOptions } from \"@azure/core-http\";\nimport { MSI } from \"./models\";\nimport { credentialLogger } from \"../../util/logging\";\nimport { IdentityClient } from \"../../client/identityClient\";\nimport { msiGenericGetToken } from \"./utils\";\nimport { azureFabricVersion } from \"./constants\";\n\nconst logger = credentialLogger(\"ManagedIdentityCredential - Fabric MSI\");\n\nfunction expiresInParser(requestBody: any): number {\n // Parses a string representation of the seconds since epoch into a number value\n return Number(requestBody.expires_on);\n}\n\nfunction prepareRequestOptions(resource: string, clientId?: string): RequestPrepareOptions {\n const queryParameters: any = {\n resource,\n \"api-version\": azureFabricVersion\n };\n\n if (clientId) {\n queryParameters.client_id = clientId;\n }\n\n return {\n url: process.env.IDENTITY_ENDPOINT,\n method: \"GET\",\n queryParameters,\n headers: {\n Accept: \"application/json\",\n Secret: process.env.IDENTITY_HEADER\n }\n };\n}\n\n// This credential can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:\n//\n// FROM node:12\n// RUN wget https://host.any/path/bash.sh\n// CMD [\"bash\", \"bash.sh\"]\n//\n// Where the bash script contains:\n//\n// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H \"Secret: $IDENTITY_HEADER\"\n//\n\nexport const fabricMsi: MSI = {\n async isAvailable(): Promise<boolean> {\n const env = process.env;\n const result = Boolean(\n env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT\n );\n if (!result) {\n logger.info(\"The Azure App Service Fabric MSI is unavailable.\");\n }\n return result;\n },\n async getToken(\n identityClient: IdentityClient,\n resource: string,\n clientId?: string,\n getTokenOptions: GetTokenOptions = {}\n ): Promise<AccessToken | null> {\n logger.info(\n [\n \"Using the endpoint and the secret coming from the environment variables:\",\n `IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,\n \"IDENTITY_HEADER=[REDACTED] and\",\n \"IDENTITY_SERVER_THUMBPRINT=[REDACTED].\"\n ].join(\" \")\n );\n\n return msiGenericGetToken(\n identityClient,\n prepareRequestOptions(resource, clientId),\n expiresInParser,\n getTokenOptions\n );\n }\n};\n"]}
1
+ {"version":3,"file":"fabricMsi.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/fabricMsi.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { createHttpHeaders, PipelineRequestOptions } from \"@azure/core-rest-pipeline\";\nimport { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport { MSI, MSIConfiguration } from \"./models\";\nimport { credentialLogger } from \"../../util/logging\";\nimport { mapScopesToResource, msiGenericGetToken } from \"./utils\";\nimport { azureFabricVersion } from \"./constants\";\n\nconst msiName = \"ManagedIdentityCredential - Fabric MSI\";\nconst logger = credentialLogger(msiName);\n\nfunction expiresInParser(requestBody: any): number {\n // Parses a string representation of the seconds since epoch into a number value\n return Number(requestBody.expires_on);\n}\n\nfunction prepareRequestOptions(\n scopes: string | string[],\n clientId?: string\n): PipelineRequestOptions {\n const resource = mapScopesToResource(scopes);\n if (!resource) {\n throw new Error(`${msiName}: Multiple scopes are not supported.`);\n }\n\n const queryParameters: any = {\n resource,\n \"api-version\": azureFabricVersion\n };\n\n if (clientId) {\n queryParameters.client_id = clientId;\n }\n\n const query = new URLSearchParams(queryParameters);\n\n // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.\n if (!process.env.IDENTITY_ENDPOINT) {\n throw new Error(\"Missing environment variable: IDENTITY_ENDPOINT\");\n }\n if (!process.env.IDENTITY_HEADER) {\n throw new Error(\"Missing environment variable: IDENTITY_HEADER\");\n }\n\n return {\n url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,\n method: \"GET\",\n headers: createHttpHeaders({\n Accept: \"application/json\",\n Secret: process.env.IDENTITY_HEADER\n })\n };\n}\n\n// This credential can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:\n//\n// FROM node:12\n// RUN wget https://host.any/path/bash.sh\n// CMD [\"bash\", \"bash.sh\"]\n//\n// Where the bash script contains:\n//\n// curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H \"Secret: $IDENTITY_HEADER\"\n//\n\nexport const fabricMsi: MSI = {\n async isAvailable(scopes): Promise<boolean> {\n const resource = mapScopesToResource(scopes);\n if (!resource) {\n logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);\n return false;\n }\n const env = process.env;\n const result = Boolean(\n env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT\n );\n if (!result) {\n logger.info(\n `${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`\n );\n }\n return result;\n },\n async getToken(\n configuration: MSIConfiguration,\n getTokenOptions: GetTokenOptions = {}\n ): Promise<AccessToken | null> {\n const { identityClient, scopes, clientId } = configuration;\n\n logger.info(\n [\n `${msiName}:`,\n \"Using the endpoint and the secret coming from the environment variables:\",\n `IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,\n \"IDENTITY_HEADER=[REDACTED] and\",\n \"IDENTITY_SERVER_THUMBPRINT=[REDACTED].\"\n ].join(\" \")\n );\n\n return msiGenericGetToken(\n identityClient,\n prepareRequestOptions(scopes, clientId),\n expiresInParser,\n getTokenOptions\n );\n }\n};\n"]}