Skip to content

Commit bee9db7

Browse files
authored
feat: add --oidcIdTokenAsAccessToken MONGOSH-1843 (#2109)
1 parent adc530e commit bee9db7

File tree

8 files changed

+109
-19
lines changed

8 files changed

+109
-19
lines changed

package-lock.json

Lines changed: 18 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/arg-parser/src/arg-mapper.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,22 @@ describe('arg-mapper.mapCliToDriver', function () {
374374
});
375375
});
376376

377+
context('when cli args have oidcIdTokenAsAccessToken', function () {
378+
const cliOptions: CliOptions = {
379+
oidcIdTokenAsAccessToken: true,
380+
};
381+
382+
it('maps to oidc passIdTokenAsAccessToken', function () {
383+
expect(optionsTest(cliOptions)).to.deep.equal({
384+
driver: {
385+
oidc: {
386+
passIdTokenAsAccessToken: true,
387+
},
388+
},
389+
});
390+
});
391+
});
392+
377393
context('when cli args have oidcTrustedEndpoint', function () {
378394
function actual(cs: string) {
379395
return mapCliToDriver(

packages/arg-parser/src/arg-mapper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,7 @@ const MAPPINGS: {
237237
'allowedFlows',
238238
v.split(',').filter(Boolean) as OIDCOptions['allowedFlows']
239239
),
240+
oidcIdTokenAsAccessToken: (i, v) => setOIDC(i, 'passIdTokenAsAccessToken', v),
240241
browser: (i, v) =>
241242
setOIDC(i, 'openBrowser', typeof v === 'string' ? { command: v } : v),
242243
};

packages/arg-parser/src/cli-options.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,5 +55,6 @@ export interface CliOptions {
5555
oidcFlows?: string;
5656
oidcRedirectUri?: string;
5757
oidcTrustedEndpoint?: boolean;
58+
oidcIdTokenAsAccessToken?: boolean;
5859
browser?: string | false;
5960
}

packages/cli-repl/src/arg-parser.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ const OPTIONS = {
6464
'nodb',
6565
'norc',
6666
'oidcTrustedEndpoint',
67+
'oidcIdTokenAsAccessToken',
6768
'perfTests',
6869
'quiet',
6970
'retryWrites',
@@ -91,6 +92,7 @@ const OPTIONS = {
9192
json: 'json', // List explicitly here since it can be a boolean or a string
9293
browser: 'browser', // ditto
9394
oidcRedirectUrl: 'oidcRedirectUri', // I'd get this wrong about 50% of the time
95+
oidcIDTokenAsAccessToken: 'oidcIdTokenAsAccessToken', // ditto
9496
},
9597
configuration: {
9698
'camel-case-expansion': false,

packages/e2e-tests/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
},
3434
"devDependencies": {
3535
"@mongodb-js/eslint-config-mongosh": "^1.0.0",
36-
"@mongodb-js/oidc-mock-provider": "^0.9.0",
36+
"@mongodb-js/oidc-mock-provider": "^0.10.0",
3737
"@mongodb-js/prettier-config-devtools": "^1.0.1",
3838
"@mongodb-js/tsconfig-mongosh": "^1.0.0",
3939
"@types/chai-as-promised": "^7.1.3",

packages/e2e-tests/test/e2e-oidc.spec.ts

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ describe('OIDC auth e2e', function () {
3131
let tokenFetches: number;
3232
let testServer: MongoRunnerSetup;
3333
let testServer2: MongoRunnerSetup;
34+
let testServer3: MongoRunnerSetup;
3435
let oidcMockProviderConfig: OIDCMockProviderConfig;
3536
let oidcMockProvider: OIDCMockProvider;
3637
let oidcMockProviderHttps: OIDCMockProvider;
@@ -127,7 +128,26 @@ describe('OIDC auth e2e', function () {
127128
...commonOidcServerArgs,
128129
],
129130
});
130-
await Promise.all([testServer.start(), testServer2.start()]);
131+
testServer3 = new MongoRunnerSetup('e2e-oidc-test-idtoken', {
132+
args: [
133+
'--setParameter',
134+
`oidcIdentityProviders=${JSON.stringify([
135+
{
136+
...serverOidcConfig,
137+
// When using ID tokens as access tokens, clientId and audience need to match
138+
// (otherwise they usually should not)
139+
clientId: 'testServer3',
140+
audience: 'testServer3',
141+
},
142+
])}`,
143+
...commonOidcServerArgs,
144+
],
145+
});
146+
await Promise.all([
147+
testServer.start(),
148+
testServer2.start(),
149+
testServer3.start(),
150+
]);
131151
});
132152

133153
beforeEach(function () {
@@ -151,6 +171,7 @@ describe('OIDC auth e2e', function () {
151171
await Promise.all([
152172
testServer?.stop(),
153173
testServer2?.stop(),
174+
testServer3?.stop(),
154175
oidcMockProvider?.close(),
155176
oidcMockProviderHttps?.close(),
156177
]);
@@ -410,4 +431,51 @@ describe('OIDC auth e2e', function () {
410431
/Unable to fetch issuer metadata for "https:\/\/localhost:\d+"/
411432
);
412433
});
434+
435+
it('can successfully authenticate using the ID token rather than access token if requested', async function () {
436+
const originalGetTokenPayload = getTokenPayload;
437+
getTokenPayload = (metadata) => {
438+
return {
439+
...originalGetTokenPayload(metadata),
440+
payload: {
441+
sub: 'testuser-at',
442+
groups: ['testuser-at-group'],
443+
aud: 'testServer3',
444+
},
445+
customIdTokenPayload: {
446+
sub: 'testuser-id',
447+
groups: ['testuser-id-group'],
448+
aud: 'testServer3',
449+
},
450+
};
451+
};
452+
453+
// Consistency check: ID token is *not* used by default
454+
shell = TestShell.start({
455+
args: [
456+
await testServer3.connectionString(),
457+
'--authenticationMechanism=MONGODB-OIDC',
458+
'--oidcRedirectUri=http://localhost:0/',
459+
`--browser=${fetchBrowserFixture}`,
460+
],
461+
});
462+
await shell.waitForPrompt();
463+
464+
await verifyUser(shell, 'testuser-at', 'testuser-at-group');
465+
466+
// Actual test: ID token data is used when --oidcIdTokenAsAccessToken is set
467+
shell = TestShell.start({
468+
args: [
469+
await testServer3.connectionString(),
470+
'--authenticationMechanism=MONGODB-OIDC',
471+
'--oidcIdTokenAsAccessToken',
472+
'--oidcRedirectUri=http://localhost:0/',
473+
`--browser=${fetchBrowserFixture}`,
474+
],
475+
});
476+
await shell.waitForPrompt();
477+
478+
await verifyUser(shell, 'testuser-id', 'testuser-id-group');
479+
shell.assertNoErrors();
480+
});
413481
});

packages/service-provider-server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
},
4949
"dependencies": {
5050
"@mongodb-js/devtools-connect": "^3.0.5",
51-
"@mongodb-js/oidc-plugin": "^1.0.2",
51+
"@mongodb-js/oidc-plugin": "^1.1.0",
5252
"@mongosh/errors": "0.0.0-dev.0",
5353
"@mongosh/service-provider-core": "0.0.0-dev.0",
5454
"@mongosh/types": "0.0.0-dev.0",

0 commit comments

Comments
 (0)