diff --git a/.changeset/hungry-countries-enjoy.md b/.changeset/hungry-countries-enjoy.md new file mode 100644 index 0000000000..dca874462b --- /dev/null +++ b/.changeset/hungry-countries-enjoy.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-app-api': patch +--- + +Fixed bug in microsoftAuth preventing access tokens with multiple scopes for one resource 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 c71799ed98..1c51dd0698 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 @@ -79,6 +79,16 @@ describe('MicrosoftAuth', () => { 'Requested access token with scopes from multiple Azure resources: one-resource, other-resource. Access tokens can only have a single audience.', ); }); + + it('succeeds when requesting multiple scopes for the same resource', async () => { + const accessTokenPromise = microsoftAuth.getAccessToken( + 'same-resource/one-scope same-resource/other-scope', + ); + + await expect(accessTokenPromise).resolves.toEqual( + 'tokenForOtherResource', + ); + }); }); 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 fdffb3fc45..c57c65d830 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,10 +91,15 @@ export default class MicrosoftAuth { } private static resourceForScopes(scope: string): Promise { - const audiences = scope - .split(' ') - .map(MicrosoftAuth.resourceForScope) - .filter(aud => aud !== 'openid'); + const audiences = [ + ...new Set( + scope + .split(' ') + .map(MicrosoftAuth.resourceForScope) + .filter(aud => aud !== 'openid'), + ), + ]; + if (audiences.length > 1) { return Promise.reject( new Error(