From 68d29bbe660d6c637aad035ef2b321f793997480 Mon Sep 17 00:00:00 2001 From: Robbie-Microsoft <87724641+Robbie-Microsoft@users.noreply.github.com> Date: Mon, 30 Sep 2024 17:15:04 -0400 Subject: [PATCH] Implemented functionality to skip the cache for MI when claims are provided (#7207) Re-used functionality from ClientCredential flow. This PR originally contained code to deprecate client assertion strings. That will now be a separate PR. --- ...-61f7f536-1cf8-4eef-ac92-89902d8e6963.json | 7 ++++ lib/msal-node/apiReview/msal-node.api.md | 1 + .../src/client/ManagedIdentityApplication.ts | 5 ++- .../request/ManagedIdentityRequestParams.ts | 4 ++- .../ManagedIdentitySources/Imds.spec.ts | 32 +++++++++++++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 change/@azure-msal-node-61f7f536-1cf8-4eef-ac92-89902d8e6963.json diff --git a/change/@azure-msal-node-61f7f536-1cf8-4eef-ac92-89902d8e6963.json b/change/@azure-msal-node-61f7f536-1cf8-4eef-ac92-89902d8e6963.json new file mode 100644 index 0000000000..88e793cdce --- /dev/null +++ b/change/@azure-msal-node-61f7f536-1cf8-4eef-ac92-89902d8e6963.json @@ -0,0 +1,7 @@ +{ + "type": "minor", + "comment": "Implemented functionality to skip the cache for MI when claims are provided #7207", + "packageName": "@azure/msal-node", + "email": "rginsburg@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/lib/msal-node/apiReview/msal-node.api.md b/lib/msal-node/apiReview/msal-node.api.md index 9d34e1a099..4f8f586923 100644 --- a/lib/msal-node/apiReview/msal-node.api.md +++ b/lib/msal-node/apiReview/msal-node.api.md @@ -449,6 +449,7 @@ export type ManagedIdentityIdParams = { // // @public export type ManagedIdentityRequestParams = { + claims?: string; forceRefresh?: boolean; resource: string; }; diff --git a/lib/msal-node/src/client/ManagedIdentityApplication.ts b/lib/msal-node/src/client/ManagedIdentityApplication.ts index cc3e8dbcad..9b2353a427 100644 --- a/lib/msal-node/src/client/ManagedIdentityApplication.ts +++ b/lib/msal-node/src/client/ManagedIdentityApplication.ts @@ -142,7 +142,10 @@ export class ManagedIdentityApplication { correlationId: this.cryptoProvider.createNewGuid(), }; - if (managedIdentityRequest.forceRefresh) { + if ( + managedIdentityRequestParams.claims || + managedIdentityRequest.forceRefresh + ) { // make a network call to the managed identity source return this.managedIdentityClient.sendManagedIdentityTokenRequest( managedIdentityRequest, diff --git a/lib/msal-node/src/request/ManagedIdentityRequestParams.ts b/lib/msal-node/src/request/ManagedIdentityRequestParams.ts index 66865adbac..88cc1207a1 100644 --- a/lib/msal-node/src/request/ManagedIdentityRequestParams.ts +++ b/lib/msal-node/src/request/ManagedIdentityRequestParams.ts @@ -5,10 +5,12 @@ /** * ManagedIdentityRequest + * - claims - a stringified claims request which will be used to determine whether or not the cache should be skipped * - forceRefresh - forces managed identity requests to skip the cache and make network calls if true - * - resource - resource requested to access the protected API. It should be of the form "{ResourceIdUri}" or {ResourceIdUri/.default}. For instance https://management.azure.net or, for Microsoft Graph, https://graph.microsoft.com/.default + * - resource - resource requested to access the protected API. It should be of the form "{ResourceIdUri}" or {ResourceIdUri/.default}. For instance https://management.azure.net or, for Microsoft Graph, https://graph.microsoft.com/.default */ export type ManagedIdentityRequestParams = { + claims?: string; forceRefresh?: boolean; resource: string; }; diff --git a/lib/msal-node/test/client/ManagedIdentitySources/Imds.spec.ts b/lib/msal-node/test/client/ManagedIdentitySources/Imds.spec.ts index b3b1e3d315..2e4318e3eb 100644 --- a/lib/msal-node/test/client/ManagedIdentitySources/Imds.spec.ts +++ b/lib/msal-node/test/client/ManagedIdentitySources/Imds.spec.ts @@ -14,6 +14,7 @@ import { MANAGED_IDENTITY_RESOURCE_ID, MANAGED_IDENTITY_RESOURCE_ID_2, MANAGED_IDENTITY_TOKEN_RETRIEVAL_ERROR_MESSAGE, + TEST_CONFIG, THREE_SECONDS_IN_MILLI, getCacheKey, } from "../../test_kit/StringConstants"; @@ -548,6 +549,37 @@ describe("Acquires a token successfully via an IMDS Managed Identity", () => { ); }); + test("ignores a cached token when claims are provided", async () => { + let networkManagedIdentityResult: AuthenticationResult = + await systemAssignedManagedIdentityApplication.acquireToken({ + resource: MANAGED_IDENTITY_RESOURCE, + }); + expect(networkManagedIdentityResult.fromCache).toBe(false); + + expect(networkManagedIdentityResult.accessToken).toEqual( + DEFAULT_SYSTEM_ASSIGNED_MANAGED_IDENTITY_AUTHENTICATION_RESULT.accessToken + ); + + const cachedManagedIdentityResult: AuthenticationResult = + await systemAssignedManagedIdentityApplication.acquireToken({ + resource: MANAGED_IDENTITY_RESOURCE, + }); + expect(cachedManagedIdentityResult.fromCache).toBe(true); + expect(cachedManagedIdentityResult.accessToken).toEqual( + DEFAULT_SYSTEM_ASSIGNED_MANAGED_IDENTITY_AUTHENTICATION_RESULT.accessToken + ); + + networkManagedIdentityResult = + await systemAssignedManagedIdentityApplication.acquireToken({ + claims: TEST_CONFIG.CLAIMS, + resource: MANAGED_IDENTITY_RESOURCE, + }); + expect(networkManagedIdentityResult.fromCache).toBe(false); + expect(networkManagedIdentityResult.accessToken).toEqual( + DEFAULT_SYSTEM_ASSIGNED_MANAGED_IDENTITY_AUTHENTICATION_RESULT.accessToken + ); + }); + test("ignores a cached token when forceRefresh is set to true", async () => { let networkManagedIdentityResult: AuthenticationResult = await systemAssignedManagedIdentityApplication.acquireToken({