From 4891b5b078dade80099ef22e19b1f8b1c3179f0f Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Fri, 12 Jul 2019 09:17:20 +0200 Subject: [PATCH] fix: give AAD v2 organizations and consumers same treatment as common Closes #175 --- lib/helpers/consts.js | 6 ++++- lib/issuer.js | 4 ++-- test/aad/aad.test.js | 56 ++++++++++++++++++++++++++----------------- 3 files changed, 41 insertions(+), 25 deletions(-) diff --git a/lib/helpers/consts.js b/lib/helpers/consts.js index 2d69ea8d..ba4f0264 100644 --- a/lib/helpers/consts.js +++ b/lib/helpers/consts.js @@ -2,7 +2,11 @@ const OIDC_DISCOVERY = '/.well-known/openid-configuration'; const OAUTH2_DISCOVERY = '/.well-known/oauth-authorization-server'; const WEBFINGER = '/.well-known/webfinger'; const REL = 'http://openid.net/specs/connect/1.0/issuer'; -const AAD_MULTITENANT_DISCOVERY = `https://login.microsoftonline.com/common/v2.0${OIDC_DISCOVERY}`; +const AAD_MULTITENANT_DISCOVERY = new Set([ + `https://login.microsoftonline.com/common/v2.0${OIDC_DISCOVERY}`, + `https://login.microsoftonline.com/organizations/v2.0${OIDC_DISCOVERY}`, + `https://login.microsoftonline.com/consumers/v2.0${OIDC_DISCOVERY}`, +]); const CLIENT_DEFAULTS = { grant_types: ['authorization_code'], diff --git a/lib/issuer.js b/lib/issuer.js index 61f8a982..3f97fb8a 100644 --- a/lib/issuer.js +++ b/lib/issuer.js @@ -215,7 +215,7 @@ class Issuer { {}, ISSUER_DEFAULTS, body, - { [AAD_MULTITENANT]: uri === AAD_MULTITENANT_DISCOVERY }, + { [AAD_MULTITENANT]: AAD_MULTITENANT_DISCOVERY.has(uri) }, )); } @@ -243,7 +243,7 @@ class Issuer { {}, ISSUER_DEFAULTS, body, - { [AAD_MULTITENANT]: wellKnownUri === AAD_MULTITENANT_DISCOVERY }, + { [AAD_MULTITENANT]: AAD_MULTITENANT_DISCOVERY.has(wellKnownUri) }, )); })); } diff --git a/test/aad/aad.test.js b/test/aad/aad.test.js index 3b5c80f8..20a19284 100644 --- a/test/aad/aad.test.js +++ b/test/aad/aad.test.js @@ -3,38 +3,50 @@ const nock = require('nock'); const { Issuer } = require('../../lib'); -const INPUTS = [ - 'https://login.microsoftonline.com/common/v2.0', - 'https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration', -]; +const INPUTS = { + common: [ + 'https://login.microsoftonline.com/common/v2.0', + 'https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration', + ], + consumers: [ + 'https://login.microsoftonline.com/consumers/v2.0', + 'https://login.microsoftonline.com/consumers/v2.0/.well-known/openid-configuration', + ], + organizations: [ + 'https://login.microsoftonline.com/organizations/v2.0', + 'https://login.microsoftonline.com/organizations/v2.0/.well-known/openid-configuration', + ], +}; const idToken = 'eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJmb28iLCJhdWQiOiJmb28iLCJpYXQiOjEyMzQ1LCJleHAiOjEyMzQ1LCJpc3MiOiJodHRwczovL2xvZ2luLm1pY3Jvc29mdG9ubGluZS5jb20vZm9vL3YyLjAiLCJ0aWQiOiJmb28ifQ'; const fail = () => { throw new Error('expected promise to be rejected'); }; describe('Azure AD multi-tenant applications', () => { - INPUTS.forEach((input, i) => { - it(`changes the "iss" validation when Issuer is discovered ${i + 1}/${INPUTS.length}`, async () => { - nock('https://login.microsoftonline.com') - .get('/common/v2.0/.well-known/openid-configuration') - .reply(200, { - issuer: 'https://login.microsoftonline.com/{tenantid}/v2.0', + Object.entries(INPUTS).forEach(([bucket, inputs]) => { + inputs.forEach((input) => { + it(`changes the "iss" validation when Issuer is discovered (${input})`, async () => { + nock('https://login.microsoftonline.com') + .get(`/${bucket}/v2.0/.well-known/openid-configuration`) + .reply(200, { + issuer: 'https://login.microsoftonline.com/{tenantid}/v2.0', + }); + + const aad = await Issuer.discover(input); + const client = new aad.Client({ client_id: 'foo' }); + return client.validateIdToken(idToken).then(fail).catch((err) => { + expect(err.message).to.match(/^id_token expired, now \d+, exp 12345$/); }); + }); + }); - const aad = await Issuer.discover(input); + it('no changes to "iss" validation when Issuer is constructed', async () => { + const aad = new Issuer({ + issuer: 'https://login.microsoftonline.com/{tenantid}/v2.0', + }); const client = new aad.Client({ client_id: 'foo' }); return client.validateIdToken(idToken).then(fail).catch((err) => { - expect(err.message).to.match(/^id_token expired, now \d+, exp 12345$/); + expect(err.message).to.eql('unexpected iss value, expected https://login.microsoftonline.com/{tenantid}/v2.0, got: https://login.microsoftonline.com/foo/v2.0'); }); }); }); - - it('no changes to "iss" validation when Issuer is constructed', async () => { - const aad = new Issuer({ - issuer: 'https://login.microsoftonline.com/{tenantid}/v2.0', - }); - const client = new aad.Client({ client_id: 'foo' }); - return client.validateIdToken(idToken).then(fail).catch((err) => { - expect(err.message).to.eql('unexpected iss value, expected https://login.microsoftonline.com/{tenantid}/v2.0, got: https://login.microsoftonline.com/foo/v2.0'); - }); - }); });