From 85adf6943b8c756fe44a34fa2577d8109ad81077 Mon Sep 17 00:00:00 2001 From: Jamie Klassen Date: Fri, 17 Mar 2023 17:33:35 -0400 Subject: [PATCH] fail multi-resource access token requests The emphasis on the word 'erroneously' in [this doc](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/ef0a1ae38249ba2cf6ec5d75731e711a6ae62cba/lib/msal-browser/docs/resources-and-scopes.md?plain=1#L36) makes this behaviour pretty compelling. Signed-off-by: Jamie Klassen --- .../auth/microsoft/MicrosoftAuth.test.ts | 10 ++++++++++ .../auth/microsoft/MicrosoftAuth.ts | 19 ++++++++++++++----- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts b/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts index 0d2e016b41..c71799ed98 100644 --- a/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts +++ b/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.test.ts @@ -69,6 +69,16 @@ describe('MicrosoftAuth', () => { expect(accessToken).toEqual('tokenForOtherResource'); }); + + it('fails when requesting scopes for multiple resources at once', async () => { + const accessTokenPromise = microsoftAuth.getAccessToken( + 'one-resource/scope other-resource/scope', + ); + + await expect(accessTokenPromise).rejects.toThrow( + 'Requested access token with scopes from multiple Azure resources: one-resource, other-resource. Access tokens can only have a single audience.', + ); + }); }); describe('without a refresh token', () => { diff --git a/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.ts b/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.ts index fa74979c6b..fdffb3fc45 100644 --- a/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.ts +++ b/packages/core-app-api/src/apis/implementations/auth/microsoft/MicrosoftAuth.ts @@ -91,11 +91,20 @@ export default class MicrosoftAuth { } private static resourceForScopes(scope: string): Promise { - const audience = - scope - .split(' ') - .map(MicrosoftAuth.resourceForScope) - .find(aud => aud !== 'openid') ?? MicrosoftAuth.MicrosoftGraphID; + const audiences = scope + .split(' ') + .map(MicrosoftAuth.resourceForScope) + .filter(aud => aud !== 'openid'); + if (audiences.length > 1) { + return Promise.reject( + new Error( + `Requested access token with scopes from multiple Azure resources: ${audiences.join( + ', ', + )}. Access tokens can only have a single audience.`, + ), + ); + } + const audience = audiences[0] ?? MicrosoftAuth.MicrosoftGraphID; return Promise.resolve(audience); }