@azure/identity-cache-persistence 1.1.2-alpha.20241112.1 → 1.1.2-alpha.20241114.2

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.
Files changed (151) hide show
  1. package/dist/index.js.map +1 -1
  2. package/dist-esm/src/index.js.map +1 -0
  3. package/dist-esm/src/platforms.js.map +1 -0
  4. package/dist-esm/src/provider.js.map +1 -0
  5. package/package.json +3 -4
  6. package/dist-esm/identity/src/client/identityClient.js +0 -257
  7. package/dist-esm/identity/src/client/identityClient.js.map +0 -1
  8. package/dist-esm/identity/src/constants.js +0 -70
  9. package/dist-esm/identity/src/constants.js.map +0 -1
  10. package/dist-esm/identity/src/credentials/authorityValidationOptions.js +0 -4
  11. package/dist-esm/identity/src/credentials/authorityValidationOptions.js.map +0 -1
  12. package/dist-esm/identity/src/credentials/authorizationCodeCredential.js +0 -63
  13. package/dist-esm/identity/src/credentials/authorizationCodeCredential.js.map +0 -1
  14. package/dist-esm/identity/src/credentials/authorizationCodeCredentialOptions.js +0 -4
  15. package/dist-esm/identity/src/credentials/authorizationCodeCredentialOptions.js.map +0 -1
  16. package/dist-esm/identity/src/credentials/azureCliCredential.js +0 -194
  17. package/dist-esm/identity/src/credentials/azureCliCredential.js.map +0 -1
  18. package/dist-esm/identity/src/credentials/azureCliCredentialOptions.js +0 -4
  19. package/dist-esm/identity/src/credentials/azureCliCredentialOptions.js.map +0 -1
  20. package/dist-esm/identity/src/credentials/azureDeveloperCliCredential.js +0 -176
  21. package/dist-esm/identity/src/credentials/azureDeveloperCliCredential.js.map +0 -1
  22. package/dist-esm/identity/src/credentials/azureDeveloperCliCredentialOptions.js +0 -4
  23. package/dist-esm/identity/src/credentials/azureDeveloperCliCredentialOptions.js.map +0 -1
  24. package/dist-esm/identity/src/credentials/azurePipelinesCredential.js +0 -146
  25. package/dist-esm/identity/src/credentials/azurePipelinesCredential.js.map +0 -1
  26. package/dist-esm/identity/src/credentials/azurePipelinesCredentialOptions.js +0 -4
  27. package/dist-esm/identity/src/credentials/azurePipelinesCredentialOptions.js.map +0 -1
  28. package/dist-esm/identity/src/credentials/azurePowerShellCredential.js +0 -238
  29. package/dist-esm/identity/src/credentials/azurePowerShellCredential.js.map +0 -1
  30. package/dist-esm/identity/src/credentials/azurePowerShellCredentialOptions.js +0 -4
  31. package/dist-esm/identity/src/credentials/azurePowerShellCredentialOptions.js.map +0 -1
  32. package/dist-esm/identity/src/credentials/brokerAuthOptions.js +0 -2
  33. package/dist-esm/identity/src/credentials/brokerAuthOptions.js.map +0 -1
  34. package/dist-esm/identity/src/credentials/browserCustomizationOptions.js +0 -4
  35. package/dist-esm/identity/src/credentials/browserCustomizationOptions.js.map +0 -1
  36. package/dist-esm/identity/src/credentials/chainedTokenCredential.js +0 -95
  37. package/dist-esm/identity/src/credentials/chainedTokenCredential.js.map +0 -1
  38. package/dist-esm/identity/src/credentials/clientAssertionCredential.js +0 -58
  39. package/dist-esm/identity/src/credentials/clientAssertionCredential.js.map +0 -1
  40. package/dist-esm/identity/src/credentials/clientAssertionCredentialOptions.js +0 -4
  41. package/dist-esm/identity/src/credentials/clientAssertionCredentialOptions.js.map +0 -1
  42. package/dist-esm/identity/src/credentials/clientCertificateCredential.js +0 -126
  43. package/dist-esm/identity/src/credentials/clientCertificateCredential.js.map +0 -1
  44. package/dist-esm/identity/src/credentials/clientCertificateCredentialOptions.js +0 -4
  45. package/dist-esm/identity/src/credentials/clientCertificateCredentialOptions.js.map +0 -1
  46. package/dist-esm/identity/src/credentials/clientSecretCredential.js +0 -63
  47. package/dist-esm/identity/src/credentials/clientSecretCredential.js.map +0 -1
  48. package/dist-esm/identity/src/credentials/clientSecretCredentialOptions.js +0 -4
  49. package/dist-esm/identity/src/credentials/clientSecretCredentialOptions.js.map +0 -1
  50. package/dist-esm/identity/src/credentials/credentialPersistenceOptions.js +0 -4
  51. package/dist-esm/identity/src/credentials/credentialPersistenceOptions.js.map +0 -1
  52. package/dist-esm/identity/src/credentials/defaultAzureCredential.js +0 -164
  53. package/dist-esm/identity/src/credentials/defaultAzureCredential.js.map +0 -1
  54. package/dist-esm/identity/src/credentials/defaultAzureCredentialOptions.js +0 -4
  55. package/dist-esm/identity/src/credentials/defaultAzureCredentialOptions.js.map +0 -1
  56. package/dist-esm/identity/src/credentials/deviceCodeCredential.js +0 -96
  57. package/dist-esm/identity/src/credentials/deviceCodeCredential.js.map +0 -1
  58. package/dist-esm/identity/src/credentials/deviceCodeCredentialOptions.js +0 -4
  59. package/dist-esm/identity/src/credentials/deviceCodeCredentialOptions.js.map +0 -1
  60. package/dist-esm/identity/src/credentials/environmentCredential.js +0 -133
  61. package/dist-esm/identity/src/credentials/environmentCredential.js.map +0 -1
  62. package/dist-esm/identity/src/credentials/environmentCredentialOptions.js +0 -4
  63. package/dist-esm/identity/src/credentials/environmentCredentialOptions.js.map +0 -1
  64. package/dist-esm/identity/src/credentials/interactiveBrowserCredential.js +0 -96
  65. package/dist-esm/identity/src/credentials/interactiveBrowserCredential.js.map +0 -1
  66. package/dist-esm/identity/src/credentials/interactiveBrowserCredentialOptions.js +0 -4
  67. package/dist-esm/identity/src/credentials/interactiveBrowserCredentialOptions.js.map +0 -1
  68. package/dist-esm/identity/src/credentials/interactiveCredentialOptions.js +0 -4
  69. package/dist-esm/identity/src/credentials/interactiveCredentialOptions.js.map +0 -1
  70. package/dist-esm/identity/src/credentials/managedIdentityCredential/imdsMsi.js +0 -125
  71. package/dist-esm/identity/src/credentials/managedIdentityCredential/imdsMsi.js.map +0 -1
  72. package/dist-esm/identity/src/credentials/managedIdentityCredential/imdsRetryPolicy.js +0 -33
  73. package/dist-esm/identity/src/credentials/managedIdentityCredential/imdsRetryPolicy.js.map +0 -1
  74. package/dist-esm/identity/src/credentials/managedIdentityCredential/index.js +0 -220
  75. package/dist-esm/identity/src/credentials/managedIdentityCredential/index.js.map +0 -1
  76. package/dist-esm/identity/src/credentials/managedIdentityCredential/models.js +0 -4
  77. package/dist-esm/identity/src/credentials/managedIdentityCredential/models.js.map +0 -1
  78. package/dist-esm/identity/src/credentials/managedIdentityCredential/tokenExchangeMsi.js +0 -37
  79. package/dist-esm/identity/src/credentials/managedIdentityCredential/tokenExchangeMsi.js.map +0 -1
  80. package/dist-esm/identity/src/credentials/managedIdentityCredential/utils.js +0 -77
  81. package/dist-esm/identity/src/credentials/managedIdentityCredential/utils.js.map +0 -1
  82. package/dist-esm/identity/src/credentials/multiTenantTokenCredentialOptions.js +0 -4
  83. package/dist-esm/identity/src/credentials/multiTenantTokenCredentialOptions.js.map +0 -1
  84. package/dist-esm/identity/src/credentials/onBehalfOfCredential.js +0 -119
  85. package/dist-esm/identity/src/credentials/onBehalfOfCredential.js.map +0 -1
  86. package/dist-esm/identity/src/credentials/onBehalfOfCredentialOptions.js +0 -4
  87. package/dist-esm/identity/src/credentials/onBehalfOfCredentialOptions.js.map +0 -1
  88. package/dist-esm/identity/src/credentials/usernamePasswordCredential.js +0 -70
  89. package/dist-esm/identity/src/credentials/usernamePasswordCredential.js.map +0 -1
  90. package/dist-esm/identity/src/credentials/usernamePasswordCredentialOptions.js +0 -4
  91. package/dist-esm/identity/src/credentials/usernamePasswordCredentialOptions.js.map +0 -1
  92. package/dist-esm/identity/src/credentials/visualStudioCodeCredential.js +0 -195
  93. package/dist-esm/identity/src/credentials/visualStudioCodeCredential.js.map +0 -1
  94. package/dist-esm/identity/src/credentials/visualStudioCodeCredentialOptions.js +0 -4
  95. package/dist-esm/identity/src/credentials/visualStudioCodeCredentialOptions.js.map +0 -1
  96. package/dist-esm/identity/src/credentials/visualStudioCodeCredentialPlugin.js +0 -4
  97. package/dist-esm/identity/src/credentials/visualStudioCodeCredentialPlugin.js.map +0 -1
  98. package/dist-esm/identity/src/credentials/workloadIdentityCredential.js +0 -119
  99. package/dist-esm/identity/src/credentials/workloadIdentityCredential.js.map +0 -1
  100. package/dist-esm/identity/src/credentials/workloadIdentityCredentialOptions.js +0 -4
  101. package/dist-esm/identity/src/credentials/workloadIdentityCredentialOptions.js.map +0 -1
  102. package/dist-esm/identity/src/errors.js +0 -123
  103. package/dist-esm/identity/src/errors.js.map +0 -1
  104. package/dist-esm/identity/src/index.js +0 -34
  105. package/dist-esm/identity/src/index.js.map +0 -1
  106. package/dist-esm/identity/src/msal/msal.js +0 -5
  107. package/dist-esm/identity/src/msal/msal.js.map +0 -1
  108. package/dist-esm/identity/src/msal/nodeFlows/brokerOptions.js +0 -2
  109. package/dist-esm/identity/src/msal/nodeFlows/brokerOptions.js.map +0 -1
  110. package/dist-esm/identity/src/msal/nodeFlows/msalClient.js +0 -511
  111. package/dist-esm/identity/src/msal/nodeFlows/msalClient.js.map +0 -1
  112. package/dist-esm/identity/src/msal/nodeFlows/msalPlugins.js +0 -87
  113. package/dist-esm/identity/src/msal/nodeFlows/msalPlugins.js.map +0 -1
  114. package/dist-esm/identity/src/msal/nodeFlows/tokenCachePersistenceOptions.js +0 -4
  115. package/dist-esm/identity/src/msal/nodeFlows/tokenCachePersistenceOptions.js.map +0 -1
  116. package/dist-esm/identity/src/msal/types.js +0 -4
  117. package/dist-esm/identity/src/msal/types.js.map +0 -1
  118. package/dist-esm/identity/src/msal/utils.js +0 -232
  119. package/dist-esm/identity/src/msal/utils.js.map +0 -1
  120. package/dist-esm/identity/src/plugins/consumer.js +0 -43
  121. package/dist-esm/identity/src/plugins/consumer.js.map +0 -1
  122. package/dist-esm/identity/src/plugins/provider.js +0 -4
  123. package/dist-esm/identity/src/plugins/provider.js.map +0 -1
  124. package/dist-esm/identity/src/regionalAuthority.js +0 -140
  125. package/dist-esm/identity/src/regionalAuthority.js.map +0 -1
  126. package/dist-esm/identity/src/tokenCredentialOptions.js +0 -4
  127. package/dist-esm/identity/src/tokenCredentialOptions.js.map +0 -1
  128. package/dist-esm/identity/src/tokenProvider.js +0 -55
  129. package/dist-esm/identity/src/tokenProvider.js.map +0 -1
  130. package/dist-esm/identity/src/util/identityTokenEndpoint.js +0 -11
  131. package/dist-esm/identity/src/util/identityTokenEndpoint.js.map +0 -1
  132. package/dist-esm/identity/src/util/logging.js +0 -94
  133. package/dist-esm/identity/src/util/logging.js.map +0 -1
  134. package/dist-esm/identity/src/util/processMultiTenantRequest.js +0 -35
  135. package/dist-esm/identity/src/util/processMultiTenantRequest.js.map +0 -1
  136. package/dist-esm/identity/src/util/processUtils.js +0 -32
  137. package/dist-esm/identity/src/util/processUtils.js.map +0 -1
  138. package/dist-esm/identity/src/util/scopeUtils.js +0 -29
  139. package/dist-esm/identity/src/util/scopeUtils.js.map +0 -1
  140. package/dist-esm/identity/src/util/subscriptionUtils.js +0 -14
  141. package/dist-esm/identity/src/util/subscriptionUtils.js.map +0 -1
  142. package/dist-esm/identity/src/util/tenantIdUtils.js +0 -44
  143. package/dist-esm/identity/src/util/tenantIdUtils.js.map +0 -1
  144. package/dist-esm/identity/src/util/tracing.js +0 -14
  145. package/dist-esm/identity/src/util/tracing.js.map +0 -1
  146. package/dist-esm/identity-cache-persistence/src/index.js.map +0 -1
  147. package/dist-esm/identity-cache-persistence/src/platforms.js.map +0 -1
  148. package/dist-esm/identity-cache-persistence/src/provider.js.map +0 -1
  149. /package/dist-esm/{identity-cache-persistence/src → src}/index.js +0 -0
  150. /package/dist-esm/{identity-cache-persistence/src → src}/platforms.js +0 -0
  151. /package/dist-esm/{identity-cache-persistence/src → src}/provider.js +0 -0
@@ -1,220 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- import { __awaiter } from "tslib";
4
- import { getLogLevel } from "@azure/logger";
5
- import { ManagedIdentityApplication } from "@azure/msal-node";
6
- import { IdentityClient } from "../../client/identityClient";
7
- import { AuthenticationRequiredError, CredentialUnavailableError } from "../../errors";
8
- import { getMSALLogLevel, defaultLoggerCallback } from "../../msal/utils";
9
- import { imdsRetryPolicy } from "./imdsRetryPolicy";
10
- import { formatSuccess, formatError, credentialLogger } from "../../util/logging";
11
- import { tracingClient } from "../../util/tracing";
12
- import { imdsMsi } from "./imdsMsi";
13
- import { tokenExchangeMsi } from "./tokenExchangeMsi";
14
- import { mapScopesToResource } from "./utils";
15
- const logger = credentialLogger("ManagedIdentityCredential");
16
- /**
17
- * Attempts authentication using a managed identity available at the deployment environment.
18
- * This authentication type works in Azure VMs, App Service instances, Azure Functions applications,
19
- * Azure Kubernetes Services, Azure Service Fabric instances and inside of the Azure Cloud Shell.
20
- *
21
- * More information about configuring managed identities can be found here:
22
- * https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview
23
- */
24
- export class ManagedIdentityCredential {
25
- /**
26
- * @internal
27
- * @hidden
28
- */
29
- constructor(clientIdOrOptions, options) {
30
- var _a, _b;
31
- this.msiRetryConfig = {
32
- maxRetries: 5,
33
- startDelayInMs: 800,
34
- intervalIncrement: 2,
35
- };
36
- let _options;
37
- if (typeof clientIdOrOptions === "string") {
38
- this.clientId = clientIdOrOptions;
39
- _options = options !== null && options !== void 0 ? options : {};
40
- }
41
- else {
42
- this.clientId = clientIdOrOptions === null || clientIdOrOptions === void 0 ? void 0 : clientIdOrOptions.clientId;
43
- _options = clientIdOrOptions !== null && clientIdOrOptions !== void 0 ? clientIdOrOptions : {};
44
- }
45
- this.resourceId = _options === null || _options === void 0 ? void 0 : _options.resourceId;
46
- this.objectId = _options === null || _options === void 0 ? void 0 : _options.objectId;
47
- // For JavaScript users.
48
- const providedIds = [this.clientId, this.resourceId, this.objectId].filter(Boolean);
49
- if (providedIds.length > 1) {
50
- throw new Error(`ManagedIdentityCredential: only one of 'clientId', 'resourceId', or 'objectId' can be provided. Received values: ${JSON.stringify({ clientId: this.clientId, resourceId: this.resourceId, objectId: this.objectId })}`);
51
- }
52
- // ManagedIdentity uses http for local requests
53
- _options.allowInsecureConnection = true;
54
- if (((_a = _options.retryOptions) === null || _a === void 0 ? void 0 : _a.maxRetries) !== undefined) {
55
- this.msiRetryConfig.maxRetries = _options.retryOptions.maxRetries;
56
- }
57
- this.identityClient = new IdentityClient(Object.assign(Object.assign({}, _options), { additionalPolicies: [{ policy: imdsRetryPolicy(this.msiRetryConfig), position: "perCall" }] }));
58
- this.managedIdentityApp = new ManagedIdentityApplication({
59
- managedIdentityIdParams: {
60
- userAssignedClientId: this.clientId,
61
- userAssignedResourceId: this.resourceId,
62
- userAssignedObjectId: this.objectId,
63
- },
64
- system: {
65
- disableInternalRetries: true,
66
- networkClient: this.identityClient,
67
- loggerOptions: {
68
- logLevel: getMSALLogLevel(getLogLevel()),
69
- piiLoggingEnabled: (_b = _options.loggingOptions) === null || _b === void 0 ? void 0 : _b.enableUnsafeSupportLogging,
70
- loggerCallback: defaultLoggerCallback(logger),
71
- },
72
- },
73
- });
74
- this.isAvailableIdentityClient = new IdentityClient(Object.assign(Object.assign({}, _options), { retryOptions: {
75
- maxRetries: 0,
76
- } }));
77
- // CloudShell MSI will ignore any user-assigned identity passed as parameters. To avoid confusion, we prevent this from happening as early as possible.
78
- if (this.managedIdentityApp.getManagedIdentitySource() === "CloudShell") {
79
- if (this.clientId || this.resourceId || this.objectId) {
80
- logger.warning(`CloudShell MSI detected with user-provided IDs - throwing. Received values: ${JSON.stringify({
81
- clientId: this.clientId,
82
- resourceId: this.resourceId,
83
- objectId: this.objectId,
84
- })}.`);
85
- throw new CredentialUnavailableError("ManagedIdentityCredential: Specifying a user-assigned managed identity is not supported for CloudShell at runtime. When using Managed Identity in CloudShell, omit the clientId, resourceId, and objectId parameters.");
86
- }
87
- }
88
- }
89
- /**
90
- * Authenticates with Microsoft Entra ID and returns an access token if successful.
91
- * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
92
- * If an unexpected error occurs, an {@link AuthenticationError} will be thrown with the details of the failure.
93
- *
94
- * @param scopes - The list of scopes for which the token will have access.
95
- * @param options - The options used to configure any requests this
96
- * TokenCredential implementation might make.
97
- */
98
- getToken(scopes_1) {
99
- return __awaiter(this, arguments, void 0, function* (scopes, options = {}) {
100
- logger.getToken.info("Using the MSAL provider for Managed Identity.");
101
- const resource = mapScopesToResource(scopes);
102
- if (!resource) {
103
- throw new CredentialUnavailableError(`ManagedIdentityCredential: Multiple scopes are not supported. Scopes: ${JSON.stringify(scopes)}`);
104
- }
105
- return tracingClient.withSpan("ManagedIdentityCredential.getToken", options, () => __awaiter(this, void 0, void 0, function* () {
106
- var _a;
107
- try {
108
- const isTokenExchangeMsi = yield tokenExchangeMsi.isAvailable(this.clientId);
109
- // Most scenarios are handled by MSAL except for two:
110
- // AKS pod identity - MSAL does not implement the token exchange flow.
111
- // IMDS Endpoint probing - MSAL does not do any probing before trying to get a token.
112
- // As a DefaultAzureCredential optimization we probe the IMDS endpoint with a short timeout and no retries before actually trying to get a token
113
- // We will continue to implement these features in the Identity library.
114
- const identitySource = this.managedIdentityApp.getManagedIdentitySource();
115
- const isImdsMsi = identitySource === "DefaultToImds" || identitySource === "Imds"; // Neither actually checks that IMDS endpoint is available, just that it's the source the MSAL _would_ try to use.
116
- logger.getToken.info(`MSAL Identity source: ${identitySource}`);
117
- if (isTokenExchangeMsi) {
118
- // In the AKS scenario we will use the existing tokenExchangeMsi indefinitely.
119
- logger.getToken.info("Using the token exchange managed identity.");
120
- const result = yield tokenExchangeMsi.getToken({
121
- scopes,
122
- clientId: this.clientId,
123
- identityClient: this.identityClient,
124
- retryConfig: this.msiRetryConfig,
125
- resourceId: this.resourceId,
126
- });
127
- if (result === null) {
128
- throw new CredentialUnavailableError("Attempted to use the token exchange managed identity, but received a null response.");
129
- }
130
- return result;
131
- }
132
- else if (isImdsMsi) {
133
- // In the IMDS scenario we will probe the IMDS endpoint to ensure it's available before trying to get a token.
134
- // If the IMDS endpoint is not available and this is the source that MSAL will use, we will fail-fast with an error that tells DAC to move to the next credential.
135
- logger.getToken.info("Using the IMDS endpoint to probe for availability.");
136
- const isAvailable = yield imdsMsi.isAvailable({
137
- scopes,
138
- clientId: this.clientId,
139
- getTokenOptions: options,
140
- identityClient: this.isAvailableIdentityClient,
141
- resourceId: this.resourceId,
142
- });
143
- if (!isAvailable) {
144
- throw new CredentialUnavailableError(`Attempted to use the IMDS endpoint, but it is not available.`);
145
- }
146
- }
147
- // If we got this far, it means:
148
- // - This is not a tokenExchangeMsi,
149
- // - We already probed for IMDS endpoint availability and failed-fast if it's unreachable.
150
- // We can proceed normally by calling MSAL for a token.
151
- logger.getToken.info("Calling into MSAL for managed identity token.");
152
- const token = yield this.managedIdentityApp.acquireToken({
153
- resource,
154
- });
155
- this.ensureValidMsalToken(scopes, token, options);
156
- logger.getToken.info(formatSuccess(scopes));
157
- return {
158
- expiresOnTimestamp: token.expiresOn.getTime(),
159
- token: token.accessToken,
160
- refreshAfterTimestamp: (_a = token.refreshOn) === null || _a === void 0 ? void 0 : _a.getTime(),
161
- tokenType: "Bearer",
162
- };
163
- }
164
- catch (err) {
165
- logger.getToken.error(formatError(scopes, err));
166
- // AuthenticationRequiredError described as Error to enforce authentication after trying to retrieve a token silently.
167
- // TODO: why would this _ever_ happen considering we're not trying the silent request in this flow?
168
- if (err.name === "AuthenticationRequiredError") {
169
- throw err;
170
- }
171
- if (isNetworkError(err)) {
172
- throw new CredentialUnavailableError(`ManagedIdentityCredential: Network unreachable. Message: ${err.message}`, { cause: err });
173
- }
174
- throw new CredentialUnavailableError(`ManagedIdentityCredential: Authentication failed. Message ${err.message}`, { cause: err });
175
- }
176
- }));
177
- });
178
- }
179
- /**
180
- * Ensures the validity of the MSAL token
181
- */
182
- ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
183
- const createError = (message) => {
184
- logger.getToken.info(message);
185
- return new AuthenticationRequiredError({
186
- scopes: Array.isArray(scopes) ? scopes : [scopes],
187
- getTokenOptions,
188
- message,
189
- });
190
- };
191
- if (!msalToken) {
192
- throw createError("No response.");
193
- }
194
- if (!msalToken.expiresOn) {
195
- throw createError(`Response had no "expiresOn" property.`);
196
- }
197
- if (!msalToken.accessToken) {
198
- throw createError(`Response had no "accessToken" property.`);
199
- }
200
- }
201
- }
202
- function isNetworkError(err) {
203
- // MSAL error
204
- if (err.errorCode === "network_error") {
205
- return true;
206
- }
207
- // Probe errors
208
- if (err.code === "ENETUNREACH" || err.code === "EHOSTUNREACH") {
209
- return true;
210
- }
211
- // This is a special case for Docker Desktop which responds with a 403 with a message that contains "A socket operation was attempted to an unreachable network" or "A socket operation was attempted to an unreachable host"
212
- // rather than just timing out, as expected.
213
- if (err.statusCode === 403 || err.code === 403) {
214
- if (err.message.includes("unreachable")) {
215
- return true;
216
- }
217
- }
218
- return false;
219
- }
220
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../identity/src/credentials/managedIdentityCredential/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\n\nimport type { TokenCredentialOptions } from \"../../tokenCredentialOptions\";\nimport { getLogLevel } from \"@azure/logger\";\nimport { ManagedIdentityApplication } from \"@azure/msal-node\";\nimport { IdentityClient } from \"../../client/identityClient\";\nimport { AuthenticationRequiredError, CredentialUnavailableError } from \"../../errors\";\nimport { getMSALLogLevel, defaultLoggerCallback } from \"../../msal/utils\";\nimport { imdsRetryPolicy } from \"./imdsRetryPolicy\";\nimport { MSIConfiguration } from \"./models\";\nimport { formatSuccess, formatError, credentialLogger } from \"../../util/logging\";\nimport { tracingClient } from \"../../util/tracing\";\nimport { imdsMsi } from \"./imdsMsi\";\nimport { tokenExchangeMsi } from \"./tokenExchangeMsi\";\nimport { mapScopesToResource } from \"./utils\";\nimport { MsalToken, ValidMsalToken } from \"../../msal/types\";\n\nconst logger = credentialLogger(\"ManagedIdentityCredential\");\n\n/**\n * Options to send on the {@link ManagedIdentityCredential} constructor.\n * This variation supports `clientId` and not `resourceId`, since only one of both is supported.\n */\nexport interface ManagedIdentityCredentialClientIdOptions extends TokenCredentialOptions {\n /**\n * The client ID of the user - assigned identity, or app registration(when working with AKS pod - identity).\n */\n clientId?: string;\n}\n\n/**\n * Options to send on the {@link ManagedIdentityCredential} constructor.\n * This variation supports `resourceId` and not `clientId`, since only one of both is supported.\n */\nexport interface ManagedIdentityCredentialResourceIdOptions extends TokenCredentialOptions {\n /**\n * Allows specifying a custom resource Id.\n * In scenarios such as when user assigned identities are created using an ARM template,\n * where the resource Id of the identity is known but the client Id can't be known ahead of time,\n * this parameter allows programs to use these user assigned identities\n * without having to first determine the client Id of the created identity.\n */\n resourceId: string;\n}\n\n/**\n * Options to send on the {@link ManagedIdentityCredential} constructor.\n * This variation supports `objectId` as a constructor argument.\n */\nexport interface ManagedIdentityCredentialObjectIdOptions extends TokenCredentialOptions {\n /**\n * Allows specifying the object ID of the underlying service principal used to authenticate a user-assigned managed identity.\n * This is an alternative to providing a client ID or resource ID and is not required for system-assigned managed identities.\n */\n objectId: string;\n}\n\n/**\n * Attempts authentication using a managed identity available at the deployment environment.\n * This authentication type works in Azure VMs, App Service instances, Azure Functions applications,\n * Azure Kubernetes Services, Azure Service Fabric instances and inside of the Azure Cloud Shell.\n *\n * More information about configuring managed identities can be found here:\n * https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/overview\n */\nexport class ManagedIdentityCredential implements TokenCredential {\n private managedIdentityApp: ManagedIdentityApplication;\n private identityClient: IdentityClient;\n private clientId?: string;\n private resourceId?: string;\n private objectId?: string;\n private msiRetryConfig: MSIConfiguration[\"retryConfig\"] = {\n maxRetries: 5,\n startDelayInMs: 800,\n intervalIncrement: 2,\n };\n private isAvailableIdentityClient: IdentityClient;\n\n /**\n * Creates an instance of ManagedIdentityCredential with the client ID of a\n * user-assigned identity, or app registration (when working with AKS pod-identity).\n *\n * @param clientId - The client ID of the user-assigned identity, or app registration (when working with AKS pod-identity).\n * @param options - Options for configuring the client which makes the access token request.\n */\n constructor(clientId: string, options?: TokenCredentialOptions);\n /**\n * Creates an instance of ManagedIdentityCredential with a client ID\n *\n * @param options - Options for configuring the client which makes the access token request.\n */\n constructor(options?: ManagedIdentityCredentialClientIdOptions);\n /**\n * Creates an instance of ManagedIdentityCredential with a resource ID\n *\n * @param options - Options for configuring the resource which makes the access token request.\n */\n constructor(options?: ManagedIdentityCredentialResourceIdOptions);\n /**\n * Creates an instance of ManagedIdentityCredential with an object ID\n *\n * @param options - Options for configuring the resource which makes the access token request.\n */\n constructor(options?: ManagedIdentityCredentialObjectIdOptions);\n /**\n * @internal\n * @hidden\n */\n constructor(\n clientIdOrOptions?:\n | string\n | ManagedIdentityCredentialClientIdOptions\n | ManagedIdentityCredentialResourceIdOptions\n | ManagedIdentityCredentialObjectIdOptions,\n options?: TokenCredentialOptions,\n ) {\n let _options: TokenCredentialOptions;\n if (typeof clientIdOrOptions === \"string\") {\n this.clientId = clientIdOrOptions;\n _options = options ?? {};\n } else {\n this.clientId = (clientIdOrOptions as ManagedIdentityCredentialClientIdOptions)?.clientId;\n _options = clientIdOrOptions ?? {};\n }\n this.resourceId = (_options as ManagedIdentityCredentialResourceIdOptions)?.resourceId;\n this.objectId = (_options as ManagedIdentityCredentialObjectIdOptions)?.objectId;\n\n // For JavaScript users.\n const providedIds = [this.clientId, this.resourceId, this.objectId].filter(Boolean);\n if (providedIds.length > 1) {\n throw new Error(\n `ManagedIdentityCredential: only one of 'clientId', 'resourceId', or 'objectId' can be provided. Received values: ${JSON.stringify(\n { clientId: this.clientId, resourceId: this.resourceId, objectId: this.objectId },\n )}`,\n );\n }\n\n // ManagedIdentity uses http for local requests\n _options.allowInsecureConnection = true;\n\n if (_options.retryOptions?.maxRetries !== undefined) {\n this.msiRetryConfig.maxRetries = _options.retryOptions.maxRetries;\n }\n\n this.identityClient = new IdentityClient({\n ..._options,\n additionalPolicies: [{ policy: imdsRetryPolicy(this.msiRetryConfig), position: \"perCall\" }],\n });\n\n this.managedIdentityApp = new ManagedIdentityApplication({\n managedIdentityIdParams: {\n userAssignedClientId: this.clientId,\n userAssignedResourceId: this.resourceId,\n userAssignedObjectId: this.objectId,\n },\n system: {\n disableInternalRetries: true,\n networkClient: this.identityClient,\n loggerOptions: {\n logLevel: getMSALLogLevel(getLogLevel()),\n piiLoggingEnabled: _options.loggingOptions?.enableUnsafeSupportLogging,\n loggerCallback: defaultLoggerCallback(logger),\n },\n },\n });\n\n this.isAvailableIdentityClient = new IdentityClient({\n ..._options,\n retryOptions: {\n maxRetries: 0,\n },\n });\n\n // CloudShell MSI will ignore any user-assigned identity passed as parameters. To avoid confusion, we prevent this from happening as early as possible.\n if (this.managedIdentityApp.getManagedIdentitySource() === \"CloudShell\") {\n if (this.clientId || this.resourceId || this.objectId) {\n logger.warning(\n `CloudShell MSI detected with user-provided IDs - throwing. Received values: ${JSON.stringify(\n {\n clientId: this.clientId,\n resourceId: this.resourceId,\n objectId: this.objectId,\n },\n )}.`,\n );\n throw new CredentialUnavailableError(\n \"ManagedIdentityCredential: Specifying a user-assigned managed identity is not supported for CloudShell at runtime. When using Managed Identity in CloudShell, omit the clientId, resourceId, and objectId parameters.\",\n );\n }\n }\n }\n\n /**\n * Authenticates with Microsoft Entra ID and returns an access token if successful.\n * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n * If an unexpected error occurs, an {@link AuthenticationError} will be thrown with the details of the failure.\n *\n * @param scopes - The list of scopes for which the token will have access.\n * @param options - The options used to configure any requests this\n * TokenCredential implementation might make.\n */\n public async getToken(\n scopes: string | string[],\n options: GetTokenOptions = {},\n ): Promise<AccessToken> {\n logger.getToken.info(\"Using the MSAL provider for Managed Identity.\");\n const resource = mapScopesToResource(scopes);\n if (!resource) {\n throw new CredentialUnavailableError(\n `ManagedIdentityCredential: Multiple scopes are not supported. Scopes: ${JSON.stringify(\n scopes,\n )}`,\n );\n }\n\n return tracingClient.withSpan(\"ManagedIdentityCredential.getToken\", options, async () => {\n try {\n const isTokenExchangeMsi = await tokenExchangeMsi.isAvailable(this.clientId);\n\n // Most scenarios are handled by MSAL except for two:\n // AKS pod identity - MSAL does not implement the token exchange flow.\n // IMDS Endpoint probing - MSAL does not do any probing before trying to get a token.\n // As a DefaultAzureCredential optimization we probe the IMDS endpoint with a short timeout and no retries before actually trying to get a token\n // We will continue to implement these features in the Identity library.\n\n const identitySource = this.managedIdentityApp.getManagedIdentitySource();\n const isImdsMsi = identitySource === \"DefaultToImds\" || identitySource === \"Imds\"; // Neither actually checks that IMDS endpoint is available, just that it's the source the MSAL _would_ try to use.\n\n logger.getToken.info(`MSAL Identity source: ${identitySource}`);\n\n if (isTokenExchangeMsi) {\n // In the AKS scenario we will use the existing tokenExchangeMsi indefinitely.\n logger.getToken.info(\"Using the token exchange managed identity.\");\n const result = await tokenExchangeMsi.getToken({\n scopes,\n clientId: this.clientId,\n identityClient: this.identityClient,\n retryConfig: this.msiRetryConfig,\n resourceId: this.resourceId,\n });\n\n if (result === null) {\n throw new CredentialUnavailableError(\n \"Attempted to use the token exchange managed identity, but received a null response.\",\n );\n }\n\n return result;\n } else if (isImdsMsi) {\n // In the IMDS scenario we will probe the IMDS endpoint to ensure it's available before trying to get a token.\n // If the IMDS endpoint is not available and this is the source that MSAL will use, we will fail-fast with an error that tells DAC to move to the next credential.\n logger.getToken.info(\"Using the IMDS endpoint to probe for availability.\");\n const isAvailable = await imdsMsi.isAvailable({\n scopes,\n clientId: this.clientId,\n getTokenOptions: options,\n identityClient: this.isAvailableIdentityClient,\n resourceId: this.resourceId,\n });\n\n if (!isAvailable) {\n throw new CredentialUnavailableError(\n `Attempted to use the IMDS endpoint, but it is not available.`,\n );\n }\n }\n\n // If we got this far, it means:\n // - This is not a tokenExchangeMsi,\n // - We already probed for IMDS endpoint availability and failed-fast if it's unreachable.\n // We can proceed normally by calling MSAL for a token.\n logger.getToken.info(\"Calling into MSAL for managed identity token.\");\n const token = await this.managedIdentityApp.acquireToken({\n resource,\n });\n\n this.ensureValidMsalToken(scopes, token, options);\n logger.getToken.info(formatSuccess(scopes));\n\n return {\n expiresOnTimestamp: token.expiresOn.getTime(),\n token: token.accessToken,\n refreshAfterTimestamp: token.refreshOn?.getTime(),\n tokenType: \"Bearer\",\n } as AccessToken;\n } catch (err: any) {\n logger.getToken.error(formatError(scopes, err));\n\n // AuthenticationRequiredError described as Error to enforce authentication after trying to retrieve a token silently.\n // TODO: why would this _ever_ happen considering we're not trying the silent request in this flow?\n if (err.name === \"AuthenticationRequiredError\") {\n throw err;\n }\n\n if (isNetworkError(err)) {\n throw new CredentialUnavailableError(\n `ManagedIdentityCredential: Network unreachable. Message: ${err.message}`,\n { cause: err },\n );\n }\n\n throw new CredentialUnavailableError(\n `ManagedIdentityCredential: Authentication failed. Message ${err.message}`,\n { cause: err },\n );\n }\n });\n }\n\n /**\n * Ensures the validity of the MSAL token\n */\n private ensureValidMsalToken(\n scopes: string | string[],\n msalToken?: MsalToken,\n getTokenOptions?: GetTokenOptions,\n ): asserts msalToken is ValidMsalToken {\n const createError = (message: string): Error => {\n logger.getToken.info(message);\n return new AuthenticationRequiredError({\n scopes: Array.isArray(scopes) ? scopes : [scopes],\n getTokenOptions,\n message,\n });\n };\n if (!msalToken) {\n throw createError(\"No response.\");\n }\n if (!msalToken.expiresOn) {\n throw createError(`Response had no \"expiresOn\" property.`);\n }\n if (!msalToken.accessToken) {\n throw createError(`Response had no \"accessToken\" property.`);\n }\n }\n}\n\nfunction isNetworkError(err: any): boolean {\n // MSAL error\n if (err.errorCode === \"network_error\") {\n return true;\n }\n\n // Probe errors\n if (err.code === \"ENETUNREACH\" || err.code === \"EHOSTUNREACH\") {\n return true;\n }\n\n // This is a special case for Docker Desktop which responds with a 403 with a message that contains \"A socket operation was attempted to an unreachable network\" or \"A socket operation was attempted to an unreachable host\"\n // rather than just timing out, as expected.\n if (err.statusCode === 403 || err.code === 403) {\n if (err.message.includes(\"unreachable\")) {\n return true;\n }\n }\n\n return false;\n}\n"]}
@@ -1,4 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- export {};
4
- //# sourceMappingURL=models.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"models.js","sourceRoot":"","sources":["../../../../../../identity/src/credentials/managedIdentityCredential/models.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken } from \"@azure/core-auth\";\n\nimport type { IdentityClient } from \"../../client/identityClient\";\n\n/**\n * @internal\n */\nexport interface MSIConfiguration {\n retryConfig: {\n maxRetries: number;\n startDelayInMs: number;\n intervalIncrement: number;\n };\n identityClient: IdentityClient;\n scopes: string | string[];\n clientId?: string;\n resourceId?: string;\n}\n\n/**\n * @internal\n * Represents an access token for {@link ManagedIdentity} for internal usage,\n * with an expiration time and the time in which token should refresh.\n */\nexport declare interface MSIToken extends AccessToken {}\n"]}
@@ -1,37 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- import { __awaiter } from "tslib";
4
- import { WorkloadIdentityCredential } from "../workloadIdentityCredential";
5
- import { credentialLogger } from "../../util/logging";
6
- const msiName = "ManagedIdentityCredential - Token Exchange";
7
- const logger = credentialLogger(msiName);
8
- /**
9
- * Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
10
- *
11
- * Token exchange MSI (used by AKS) is the only MSI implementation handled entirely by Azure Identity.
12
- * The rest have been migrated to MSAL.
13
- */
14
- export const tokenExchangeMsi = {
15
- name: "tokenExchangeMsi",
16
- isAvailable(clientId) {
17
- return __awaiter(this, void 0, void 0, function* () {
18
- const env = process.env;
19
- const result = Boolean((clientId || env.AZURE_CLIENT_ID) &&
20
- env.AZURE_TENANT_ID &&
21
- process.env.AZURE_FEDERATED_TOKEN_FILE);
22
- if (!result) {
23
- logger.info(`${msiName}: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE`);
24
- }
25
- return result;
26
- });
27
- },
28
- getToken(configuration_1) {
29
- return __awaiter(this, arguments, void 0, function* (configuration, getTokenOptions = {}) {
30
- const { scopes, clientId } = configuration;
31
- const identityClientTokenCredentialOptions = {};
32
- const workloadIdentityCredential = new WorkloadIdentityCredential(Object.assign(Object.assign({ clientId, tenantId: process.env.AZURE_TENANT_ID, tokenFilePath: process.env.AZURE_FEDERATED_TOKEN_FILE }, identityClientTokenCredentialOptions), { disableInstanceDiscovery: true }));
33
- return workloadIdentityCredential.getToken(scopes, getTokenOptions);
34
- });
35
- },
36
- };
37
- //# sourceMappingURL=tokenExchangeMsi.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tokenExchangeMsi.js","sourceRoot":"","sources":["../../../../../../identity/src/credentials/managedIdentityCredential/tokenExchangeMsi.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;AAIlC,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,MAAM,OAAO,GAAG,4CAA4C,CAAC;AAC7D,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,kBAAkB;IAClB,WAAW,CAAC,QAAiB;;YACjC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;YACxB,MAAM,MAAM,GAAG,OAAO,CACpB,CAAC,QAAQ,IAAI,GAAG,CAAC,eAAe,CAAC;gBAC/B,GAAG,CAAC,eAAe;gBACnB,OAAO,CAAC,GAAG,CAAC,0BAA0B,CACzC,CAAC;YACF,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,CACT,GAAG,OAAO,qKAAqK,CAChL,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;KAAA;IACK,QAAQ;6DACZ,aAA+B,EAC/B,kBAAmC,EAAE;YAErC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC;YAC3C,MAAM,oCAAoC,GAAG,EAAE,CAAC;YAChD,MAAM,0BAA0B,GAAG,IAAI,0BAA0B,CAAC,8BAChE,QAAQ,EACR,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EACrC,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAClD,oCAAoC,KACvC,wBAAwB,EAAE,IAAI,GACM,CAAC,CAAC;YACxC,OAAO,0BAA0B,CAAC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;QACtE,CAAC;KAAA;CACF,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport type { MSIConfiguration } from \"./models\";\nimport { WorkloadIdentityCredential } from \"../workloadIdentityCredential\";\nimport { credentialLogger } from \"../../util/logging\";\nimport type { WorkloadIdentityCredentialOptions } from \"../workloadIdentityCredentialOptions\";\n\nconst msiName = \"ManagedIdentityCredential - Token Exchange\";\nconst logger = credentialLogger(msiName);\n\n/**\n * Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.\n *\n * Token exchange MSI (used by AKS) is the only MSI implementation handled entirely by Azure Identity.\n * The rest have been migrated to MSAL.\n */\nexport const tokenExchangeMsi = {\n name: \"tokenExchangeMsi\",\n async isAvailable(clientId?: string): Promise<boolean> {\n const env = process.env;\n const result = Boolean(\n (clientId || env.AZURE_CLIENT_ID) &&\n env.AZURE_TENANT_ID &&\n process.env.AZURE_FEDERATED_TOKEN_FILE,\n );\n if (!result) {\n logger.info(\n `${msiName}: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE`,\n );\n }\n return result;\n },\n async getToken(\n configuration: MSIConfiguration,\n getTokenOptions: GetTokenOptions = {},\n ): Promise<AccessToken | null> {\n const { scopes, clientId } = configuration;\n const identityClientTokenCredentialOptions = {};\n const workloadIdentityCredential = new WorkloadIdentityCredential({\n clientId,\n tenantId: process.env.AZURE_TENANT_ID,\n tokenFilePath: process.env.AZURE_FEDERATED_TOKEN_FILE,\n ...identityClientTokenCredentialOptions,\n disableInstanceDiscovery: true,\n } as WorkloadIdentityCredentialOptions);\n return workloadIdentityCredential.getToken(scopes, getTokenOptions);\n },\n};\n"]}
@@ -1,77 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- const DefaultScopeSuffix = "/.default";
4
- /**
5
- * Most MSIs send requests to the IMDS endpoint, or a similar endpoint.
6
- * These are GET requests that require sending a `resource` parameter on the query.
7
- * This resource can be derived from the scopes received through the getToken call, as long as only one scope is received.
8
- * Multiple scopes assume that the resulting token will have access to multiple resources, which won't be the case.
9
- *
10
- * For that reason, when we encounter multiple scopes, we return undefined.
11
- * It's up to the individual MSI implementations to throw the errors (which helps us provide less generic errors).
12
- */
13
- export function mapScopesToResource(scopes) {
14
- let scope = "";
15
- if (Array.isArray(scopes)) {
16
- if (scopes.length !== 1) {
17
- return;
18
- }
19
- scope = scopes[0];
20
- }
21
- else if (typeof scopes === "string") {
22
- scope = scopes;
23
- }
24
- if (!scope.endsWith(DefaultScopeSuffix)) {
25
- return scope;
26
- }
27
- return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));
28
- }
29
- /**
30
- * Given a token response, return the expiration timestamp as the number of milliseconds from the Unix epoch.
31
- * @param body - A parsed response body from the authentication endpoint.
32
- */
33
- export function parseExpirationTimestamp(body) {
34
- if (typeof body.expires_on === "number") {
35
- return body.expires_on * 1000;
36
- }
37
- if (typeof body.expires_on === "string") {
38
- const asNumber = +body.expires_on;
39
- if (!isNaN(asNumber)) {
40
- return asNumber * 1000;
41
- }
42
- const asDate = Date.parse(body.expires_on);
43
- if (!isNaN(asDate)) {
44
- return asDate;
45
- }
46
- }
47
- if (typeof body.expires_in === "number") {
48
- return Date.now() + body.expires_in * 1000;
49
- }
50
- throw new Error(`Failed to parse token expiration from body. expires_in="${body.expires_in}", expires_on="${body.expires_on}"`);
51
- }
52
- /**
53
- * Given a token response, return the expiration timestamp as the number of milliseconds from the Unix epoch.
54
- * @param body - A parsed response body from the authentication endpoint.
55
- */
56
- export function parseRefreshTimestamp(body) {
57
- if (body.refresh_on) {
58
- if (typeof body.refresh_on === "number") {
59
- return body.refresh_on * 1000;
60
- }
61
- if (typeof body.refresh_on === "string") {
62
- const asNumber = +body.refresh_on;
63
- if (!isNaN(asNumber)) {
64
- return asNumber * 1000;
65
- }
66
- const asDate = Date.parse(body.refresh_on);
67
- if (!isNaN(asDate)) {
68
- return asDate;
69
- }
70
- }
71
- throw new Error(`Failed to parse refresh_on from body. refresh_on="${body.refresh_on}"`);
72
- }
73
- else {
74
- return undefined;
75
- }
76
- }
77
- //# sourceMappingURL=utils.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../../../identity/src/credentials/managedIdentityCredential/utils.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,MAAM,kBAAkB,GAAG,WAAW,CAAC;AAEvC;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAyB;IAC3D,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QAED,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;SAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACtC,KAAK,GAAG,MAAM,CAAC;IACjB,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,CAAC;QACxC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAChE,CAAC;AAeD;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAA6B;IACpE,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IAChC,CAAC;IAED,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrB,OAAO,QAAQ,GAAG,IAAI,CAAC;QACzB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IAED,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;IAC7C,CAAC;IAED,MAAM,IAAI,KAAK,CACb,2DAA2D,IAAI,CAAC,UAAU,kBAAkB,IAAI,CAAC,UAAU,GAAG,CAC/G,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,IAA6B;IACjE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;QACpB,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YACxC,OAAO,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAChC,CAAC;QAED,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;YAClC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACrB,OAAO,QAAQ,GAAG,IAAI,CAAC;YACzB,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC3C,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;gBACnB,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,qDAAqD,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;IAC3F,CAAC;SAAM,CAAC;QACN,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nconst DefaultScopeSuffix = \"/.default\";\n\n/**\n * Most MSIs send requests to the IMDS endpoint, or a similar endpoint.\n * These are GET requests that require sending a `resource` parameter on the query.\n * This resource can be derived from the scopes received through the getToken call, as long as only one scope is received.\n * Multiple scopes assume that the resulting token will have access to multiple resources, which won't be the case.\n *\n * For that reason, when we encounter multiple scopes, we return undefined.\n * It's up to the individual MSI implementations to throw the errors (which helps us provide less generic errors).\n */\nexport function mapScopesToResource(scopes: string | string[]): string | undefined {\n let scope = \"\";\n if (Array.isArray(scopes)) {\n if (scopes.length !== 1) {\n return;\n }\n\n scope = scopes[0];\n } else if (typeof scopes === \"string\") {\n scope = scopes;\n }\n\n if (!scope.endsWith(DefaultScopeSuffix)) {\n return scope;\n }\n\n return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));\n}\n\n/**\n * Internal type roughly matching the raw responses of the authentication endpoints.\n *\n * @internal\n */\nexport interface TokenResponseParsedBody {\n access_token?: string;\n refresh_token?: string;\n expires_in: number;\n expires_on?: number | string;\n refresh_on?: number | string;\n}\n\n/**\n * Given a token response, return the expiration timestamp as the number of milliseconds from the Unix epoch.\n * @param body - A parsed response body from the authentication endpoint.\n */\nexport function parseExpirationTimestamp(body: TokenResponseParsedBody): number {\n if (typeof body.expires_on === \"number\") {\n return body.expires_on * 1000;\n }\n\n if (typeof body.expires_on === \"string\") {\n const asNumber = +body.expires_on;\n if (!isNaN(asNumber)) {\n return asNumber * 1000;\n }\n\n const asDate = Date.parse(body.expires_on);\n if (!isNaN(asDate)) {\n return asDate;\n }\n }\n\n if (typeof body.expires_in === \"number\") {\n return Date.now() + body.expires_in * 1000;\n }\n\n throw new Error(\n `Failed to parse token expiration from body. expires_in=\"${body.expires_in}\", expires_on=\"${body.expires_on}\"`,\n );\n}\n\n/**\n * Given a token response, return the expiration timestamp as the number of milliseconds from the Unix epoch.\n * @param body - A parsed response body from the authentication endpoint.\n */\nexport function parseRefreshTimestamp(body: TokenResponseParsedBody): number | undefined {\n if (body.refresh_on) {\n if (typeof body.refresh_on === \"number\") {\n return body.refresh_on * 1000;\n }\n\n if (typeof body.refresh_on === \"string\") {\n const asNumber = +body.refresh_on;\n if (!isNaN(asNumber)) {\n return asNumber * 1000;\n }\n\n const asDate = Date.parse(body.refresh_on);\n if (!isNaN(asDate)) {\n return asDate;\n }\n }\n throw new Error(`Failed to parse refresh_on from body. refresh_on=\"${body.refresh_on}\"`);\n } else {\n return undefined;\n }\n}\n"]}
@@ -1,4 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- export {};
4
- //# sourceMappingURL=multiTenantTokenCredentialOptions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"multiTenantTokenCredentialOptions.js","sourceRoot":"","sources":["../../../../../identity/src/credentials/multiTenantTokenCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { TokenCredentialOptions } from \"../tokenCredentialOptions\";\n\n/**\n * Options for multi-tenant applications which allows for additionally allowed tenants.\n */\nexport interface MultiTenantTokenCredentialOptions extends TokenCredentialOptions {\n /**\n * For multi-tenant applications, specifies additional tenants for which the credential may acquire tokens.\n * Add the wildcard value \"*\" to allow the credential to acquire tokens for any tenant the application is installed.\n */\n additionallyAllowedTenants?: string[];\n}\n"]}
@@ -1,119 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- import { __awaiter } from "tslib";
4
- import { createMsalClient } from "../msal/nodeFlows/msalClient";
5
- import { credentialLogger, formatError } from "../util/logging";
6
- import { processMultiTenantRequest, resolveAdditionallyAllowedTenantIds, } from "../util/tenantIdUtils";
7
- import { CredentialUnavailableError } from "../errors";
8
- import { createHash } from "node:crypto";
9
- import { ensureScopes } from "../util/scopeUtils";
10
- import { readFile } from "node:fs/promises";
11
- import { tracingClient } from "../util/tracing";
12
- const credentialName = "OnBehalfOfCredential";
13
- const logger = credentialLogger(credentialName);
14
- /**
15
- * Enables authentication to Microsoft Entra ID using the [On Behalf Of flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-on-behalf-of-flow).
16
- */
17
- export class OnBehalfOfCredential {
18
- constructor(options) {
19
- const { clientSecret } = options;
20
- const { certificatePath, sendCertificateChain } = options;
21
- const { getAssertion } = options;
22
- const { tenantId, clientId, userAssertionToken, additionallyAllowedTenants: additionallyAllowedTenantIds, } = options;
23
- if (!tenantId) {
24
- throw new CredentialUnavailableError(`${credentialName}: tenantId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
25
- }
26
- if (!clientId) {
27
- throw new CredentialUnavailableError(`${credentialName}: clientId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
28
- }
29
- if (!clientSecret && !certificatePath && !getAssertion) {
30
- throw new CredentialUnavailableError(`${credentialName}: You must provide one of clientSecret, certificatePath, or a getAssertion callback but none were provided. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
31
- }
32
- if (!userAssertionToken) {
33
- throw new CredentialUnavailableError(`${credentialName}: userAssertionToken is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`);
34
- }
35
- this.certificatePath = certificatePath;
36
- this.clientSecret = clientSecret;
37
- this.userAssertionToken = userAssertionToken;
38
- this.sendCertificateChain = sendCertificateChain;
39
- this.clientAssertion = getAssertion;
40
- this.tenantId = tenantId;
41
- this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(additionallyAllowedTenantIds);
42
- this.msalClient = createMsalClient(clientId, this.tenantId, Object.assign(Object.assign({}, options), { logger, tokenCredentialOptions: options }));
43
- }
44
- /**
45
- * Authenticates with Microsoft Entra ID and returns an access token if successful.
46
- * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.
47
- *
48
- * @param scopes - The list of scopes for which the token will have access.
49
- * @param options - The options used to configure the underlying network requests.
50
- */
51
- getToken(scopes_1) {
52
- return __awaiter(this, arguments, void 0, function* (scopes, options = {}) {
53
- return tracingClient.withSpan(`${credentialName}.getToken`, options, (newOptions) => __awaiter(this, void 0, void 0, function* () {
54
- newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger);
55
- const arrayScopes = ensureScopes(scopes);
56
- if (this.certificatePath) {
57
- const clientCertificate = yield this.buildClientCertificate(this.certificatePath);
58
- return this.msalClient.getTokenOnBehalfOf(arrayScopes, this.userAssertionToken, clientCertificate, newOptions);
59
- }
60
- else if (this.clientSecret) {
61
- return this.msalClient.getTokenOnBehalfOf(arrayScopes, this.userAssertionToken, this.clientSecret, options);
62
- }
63
- else if (this.clientAssertion) {
64
- return this.msalClient.getTokenOnBehalfOf(arrayScopes, this.userAssertionToken, this.clientAssertion, options);
65
- }
66
- else {
67
- // this is an invalid scenario and is a bug, as the constructor should have thrown an error if neither clientSecret nor certificatePath nor clientAssertion were provided
68
- throw new Error("Expected either clientSecret or certificatePath or clientAssertion to be defined.");
69
- }
70
- }));
71
- });
72
- }
73
- buildClientCertificate(certificatePath) {
74
- return __awaiter(this, void 0, void 0, function* () {
75
- try {
76
- const parts = yield this.parseCertificate({ certificatePath }, this.sendCertificateChain);
77
- return {
78
- thumbprint: parts.thumbprint,
79
- privateKey: parts.certificateContents,
80
- x5c: parts.x5c,
81
- };
82
- }
83
- catch (error) {
84
- logger.info(formatError("", error));
85
- throw error;
86
- }
87
- });
88
- }
89
- parseCertificate(configuration, sendCertificateChain) {
90
- return __awaiter(this, void 0, void 0, function* () {
91
- const certificatePath = configuration.certificatePath;
92
- const certificateContents = yield readFile(certificatePath, "utf8");
93
- const x5c = sendCertificateChain ? certificateContents : undefined;
94
- const certificatePattern = /(-+BEGIN CERTIFICATE-+)(\n\r?|\r\n?)([A-Za-z0-9+/\n\r]+=*)(\n\r?|\r\n?)(-+END CERTIFICATE-+)/g;
95
- const publicKeys = [];
96
- // Match all possible certificates, in the order they are in the file. These will form the chain that is used for x5c
97
- let match;
98
- do {
99
- match = certificatePattern.exec(certificateContents);
100
- if (match) {
101
- publicKeys.push(match[3]);
102
- }
103
- } while (match);
104
- if (publicKeys.length === 0) {
105
- throw new Error("The file at the specified path does not contain a PEM-encoded certificate.");
106
- }
107
- const thumbprint = createHash("sha1")
108
- .update(Buffer.from(publicKeys[0], "base64"))
109
- .digest("hex")
110
- .toUpperCase();
111
- return {
112
- certificateContents,
113
- thumbprint,
114
- x5c,
115
- };
116
- });
117
- }
118
- }
119
- //# sourceMappingURL=onBehalfOfCredential.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"onBehalfOfCredential.js","sourceRoot":"","sources":["../../../../../identity/src/credentials/onBehalfOfCredential.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\nimport type { MsalClient } from \"../msal/nodeFlows/msalClient\";\nimport { createMsalClient } from \"../msal/nodeFlows/msalClient\";\nimport type {\n OnBehalfOfCredentialAssertionOptions,\n OnBehalfOfCredentialCertificateOptions,\n OnBehalfOfCredentialOptions,\n OnBehalfOfCredentialSecretOptions,\n} from \"./onBehalfOfCredentialOptions\";\nimport { credentialLogger, formatError } from \"../util/logging\";\nimport {\n processMultiTenantRequest,\n resolveAdditionallyAllowedTenantIds,\n} from \"../util/tenantIdUtils\";\n\nimport type { CertificateParts } from \"../msal/types\";\nimport type { ClientCertificatePEMCertificatePath } from \"./clientCertificateCredential\";\nimport type { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\nimport { CredentialUnavailableError } from \"../errors\";\nimport type { MultiTenantTokenCredentialOptions } from \"./multiTenantTokenCredentialOptions\";\nimport { createHash } from \"node:crypto\";\nimport { ensureScopes } from \"../util/scopeUtils\";\nimport { readFile } from \"node:fs/promises\";\nimport { tracingClient } from \"../util/tracing\";\n\nconst credentialName = \"OnBehalfOfCredential\";\nconst logger = credentialLogger(credentialName);\n\n/**\n * Enables authentication to Microsoft Entra ID using the [On Behalf Of flow](https://learn.microsoft.com/entra/identity-platform/v2-oauth2-on-behalf-of-flow).\n */\nexport class OnBehalfOfCredential implements TokenCredential {\n private tenantId: string;\n private additionallyAllowedTenantIds: string[];\n private msalClient: MsalClient;\n private sendCertificateChain?: boolean;\n private certificatePath?: string;\n private clientSecret?: string;\n private userAssertionToken: string;\n private clientAssertion?: () => Promise<string>;\n\n /**\n * Creates an instance of the {@link OnBehalfOfCredential} with the details\n * needed to authenticate against Microsoft Entra ID with path to a PEM certificate,\n * and an user assertion.\n *\n * Example using the `KeyClient` from [\\@azure/keyvault-keys](https://www.npmjs.com/package/\\@azure/keyvault-keys):\n *\n * ```ts snippet:on_behalf_of_credential_pem_example\n * import { OnBehalfOfCredential } from \"@azure/identity\";\n * import { KeyClient } from \"@azure/keyvault-keys\";\n *\n * const tokenCredential = new OnBehalfOfCredential({\n * tenantId: \"tenant-id\",\n * clientId: \"client-id\",\n * certificatePath: \"/path/to/certificate.pem\",\n * userAssertionToken: \"access-token\",\n * });\n * const client = new KeyClient(\"vault-url\", tokenCredential);\n * await client.getKey(\"key-name\");\n * ```\n *\n * @param options - Optional parameters, generally common across credentials.\n */\n constructor(\n options: OnBehalfOfCredentialCertificateOptions &\n MultiTenantTokenCredentialOptions &\n CredentialPersistenceOptions,\n );\n /**\n * Creates an instance of the {@link OnBehalfOfCredential} with the details\n * needed to authenticate against Microsoft Entra ID with a client\n * secret and an user assertion.\n *\n * Example using the `KeyClient` from [\\@azure/keyvault-keys](https://www.npmjs.com/package/\\@azure/keyvault-keys):\n *\n * ```ts snippet:on_behalf_of_credential_secret_example\n * import { OnBehalfOfCredential } from \"@azure/identity\";\n * import { KeyClient } from \"@azure/keyvault-keys\";\n *\n * const tokenCredential = new OnBehalfOfCredential({\n * tenantId: \"tenant-id\",\n * clientId: \"client-id\",\n * clientSecret: \"client-secret\",\n * userAssertionToken: \"access-token\",\n * });\n * const client = new KeyClient(\"vault-url\", tokenCredential);\n * await client.getKey(\"key-name\");\n * ```\n *\n * @param options - Optional parameters, generally common across credentials.\n */\n constructor(\n options: OnBehalfOfCredentialSecretOptions &\n MultiTenantTokenCredentialOptions &\n CredentialPersistenceOptions,\n );\n\n /**\n * Creates an instance of the {@link OnBehalfOfCredential} with the details\n * needed to authenticate against Microsoft Entra ID with a client `getAssertion`\n * and an user assertion.\n *\n * Example using the `KeyClient` from [\\@azure/keyvault-keys](https://www.npmjs.com/package/\\@azure/keyvault-keys):\n *\n * ```ts snippet:on_behalf_of_credential_assertion_example\n * import { OnBehalfOfCredential } from \"@azure/identity\";\n * import { KeyClient } from \"@azure/keyvault-keys\";\n *\n * const tokenCredential = new OnBehalfOfCredential({\n * tenantId: \"tenant-id\",\n * clientId: \"client-id\",\n * getAssertion: () => {\n * return Promise.resolve(\"my-jwt\");\n * },\n * userAssertionToken: \"access-token\",\n * });\n * const client = new KeyClient(\"vault-url\", tokenCredential);\n * await client.getKey(\"key-name\");\n * ```\n *\n * @param options - Optional parameters, generally common across credentials.\n */\n constructor(\n options: OnBehalfOfCredentialAssertionOptions &\n MultiTenantTokenCredentialOptions &\n CredentialPersistenceOptions,\n );\n\n constructor(options: OnBehalfOfCredentialOptions) {\n const { clientSecret } = options as OnBehalfOfCredentialSecretOptions;\n const { certificatePath, sendCertificateChain } =\n options as OnBehalfOfCredentialCertificateOptions;\n const { getAssertion } = options as OnBehalfOfCredentialAssertionOptions;\n const {\n tenantId,\n clientId,\n userAssertionToken,\n additionallyAllowedTenants: additionallyAllowedTenantIds,\n } = options;\n if (!tenantId) {\n throw new CredentialUnavailableError(\n `${credentialName}: tenantId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`,\n );\n }\n\n if (!clientId) {\n throw new CredentialUnavailableError(\n `${credentialName}: clientId is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`,\n );\n }\n\n if (!clientSecret && !certificatePath && !getAssertion) {\n throw new CredentialUnavailableError(\n `${credentialName}: You must provide one of clientSecret, certificatePath, or a getAssertion callback but none were provided. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`,\n );\n }\n\n if (!userAssertionToken) {\n throw new CredentialUnavailableError(\n `${credentialName}: userAssertionToken is a required parameter. To troubleshoot, visit https://aka.ms/azsdk/js/identity/serviceprincipalauthentication/troubleshoot.`,\n );\n }\n this.certificatePath = certificatePath;\n this.clientSecret = clientSecret;\n this.userAssertionToken = userAssertionToken;\n this.sendCertificateChain = sendCertificateChain;\n this.clientAssertion = getAssertion;\n\n this.tenantId = tenantId;\n this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(\n additionallyAllowedTenantIds,\n );\n\n this.msalClient = createMsalClient(clientId, this.tenantId, {\n ...options,\n logger,\n tokenCredentialOptions: options,\n });\n }\n\n /**\n * Authenticates with Microsoft Entra ID and returns an access token if successful.\n * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n *\n * @param scopes - The list of scopes for which the token will have access.\n * @param options - The options used to configure the underlying network requests.\n */\n async getToken(scopes: string | string[], options: GetTokenOptions = {}): Promise<AccessToken> {\n return tracingClient.withSpan(`${credentialName}.getToken`, options, async (newOptions) => {\n newOptions.tenantId = processMultiTenantRequest(\n this.tenantId,\n newOptions,\n this.additionallyAllowedTenantIds,\n logger,\n );\n\n const arrayScopes = ensureScopes(scopes);\n if (this.certificatePath) {\n const clientCertificate = await this.buildClientCertificate(this.certificatePath);\n\n return this.msalClient.getTokenOnBehalfOf(\n arrayScopes,\n this.userAssertionToken,\n clientCertificate,\n newOptions,\n );\n } else if (this.clientSecret) {\n return this.msalClient.getTokenOnBehalfOf(\n arrayScopes,\n this.userAssertionToken,\n this.clientSecret,\n options,\n );\n } else if (this.clientAssertion) {\n return this.msalClient.getTokenOnBehalfOf(\n arrayScopes,\n this.userAssertionToken,\n this.clientAssertion,\n options,\n );\n } else {\n // this is an invalid scenario and is a bug, as the constructor should have thrown an error if neither clientSecret nor certificatePath nor clientAssertion were provided\n throw new Error(\n \"Expected either clientSecret or certificatePath or clientAssertion to be defined.\",\n );\n }\n });\n }\n\n private async buildClientCertificate(certificatePath: string): Promise<CertificateParts> {\n try {\n const parts = await this.parseCertificate({ certificatePath }, this.sendCertificateChain);\n return {\n thumbprint: parts.thumbprint,\n privateKey: parts.certificateContents,\n x5c: parts.x5c,\n };\n } catch (error: any) {\n logger.info(formatError(\"\", error));\n throw error;\n }\n }\n\n private async parseCertificate(\n configuration: ClientCertificatePEMCertificatePath,\n sendCertificateChain?: boolean,\n ): Promise<Omit<CertificateParts, \"privateKey\"> & { certificateContents: string }> {\n const certificatePath = configuration.certificatePath;\n const certificateContents = await readFile(certificatePath, \"utf8\");\n const x5c = sendCertificateChain ? certificateContents : undefined;\n\n const certificatePattern =\n /(-+BEGIN CERTIFICATE-+)(\\n\\r?|\\r\\n?)([A-Za-z0-9+/\\n\\r]+=*)(\\n\\r?|\\r\\n?)(-+END CERTIFICATE-+)/g;\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(certificateContents);\n if (match) {\n publicKeys.push(match[3]);\n }\n } while (match);\n\n if (publicKeys.length === 0) {\n throw new Error(\"The file at the specified path does not contain a PEM-encoded certificate.\");\n }\n\n const thumbprint = createHash(\"sha1\")\n .update(Buffer.from(publicKeys[0], \"base64\"))\n .digest(\"hex\")\n .toUpperCase();\n\n return {\n certificateContents,\n thumbprint,\n x5c,\n };\n }\n}\n"]}
@@ -1,4 +0,0 @@
1
- // Copyright (c) Microsoft Corporation.
2
- // Licensed under the MIT License.
3
- export {};
4
- //# sourceMappingURL=onBehalfOfCredentialOptions.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"onBehalfOfCredentialOptions.js","sourceRoot":"","sources":["../../../../../identity/src/credentials/onBehalfOfCredentialOptions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AuthorityValidationOptions } from \"./authorityValidationOptions\";\nimport type { CredentialPersistenceOptions } from \"./credentialPersistenceOptions\";\nimport type { MultiTenantTokenCredentialOptions } from \"./multiTenantTokenCredentialOptions\";\n\n/**\n * Defines the parameters to authenticate the {@link OnBehalfOfCredential} with a secret.\n */\nexport interface OnBehalfOfCredentialSecretOptions {\n /**\n * The Microsoft Entra tenant (directory) ID.\n */\n tenantId: string;\n /**\n * The client (application) ID of an App Registration in the tenant.\n */\n clientId: string;\n /**\n * A client secret that was generated for the App Registration.\n */\n clientSecret: string;\n /**\n * The user assertion for the On-Behalf-Of flow.\n */\n userAssertionToken: string;\n}\n\n/**\n * Defines the parameters to authenticate the {@link OnBehalfOfCredential} with a certificate.\n */\nexport interface OnBehalfOfCredentialCertificateOptions {\n /**\n * The Microsoft Entra tenant (directory) ID.\n */\n tenantId: string;\n /**\n * The client (application) ID of an App Registration in the tenant.\n */\n clientId: string;\n /**\n * The path to a PEM-encoded public/private key certificate on the filesystem.\n */\n certificatePath: string;\n /**\n * The user assertion for the On-Behalf-Of flow.\n */\n userAssertionToken: string;\n /**\n * Option to include x5c header for SubjectName and Issuer name authorization.\n * Set this option to send base64 encoded public certificate in the client assertion header as an x5c claim\n */\n sendCertificateChain?: boolean;\n}\n\n/**\n * Defines the parameters to authenticate the {@link OnBehalfOfCredential} with an assertion.\n */\nexport interface OnBehalfOfCredentialAssertionOptions {\n /**\n * The Microsoft Entra tenant (directory) ID.\n */\n tenantId: string;\n /**\n * The client (application) ID of an App Registration in the tenant.\n */\n clientId: string;\n /**\n * A function that retrieves the client assertion for the credential to use\n */\n getAssertion: () => Promise<string>;\n /**\n * The user assertion for the On-Behalf-Of flow.\n */\n userAssertionToken: string;\n}\n/**\n * Optional parameters for the {@link OnBehalfOfCredential} class.\n */\nexport type OnBehalfOfCredentialOptions = (\n | OnBehalfOfCredentialSecretOptions\n | OnBehalfOfCredentialCertificateOptions\n | OnBehalfOfCredentialAssertionOptions\n) &\n MultiTenantTokenCredentialOptions &\n CredentialPersistenceOptions &\n AuthorityValidationOptions;\n"]}