Skip to content

Commit

Permalink
fix(NODE-6340): OIDC reauth uses caches speculative auth result (#4379)
Browse files Browse the repository at this point in the history
Co-authored-by: Warren James <[email protected]>
Co-authored-by: Bailey Pearson <[email protected]>
  • Loading branch information
3 people authored Jan 29, 2025
1 parent 907aac1 commit 8b2b7fd
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/cmap/auth/mongodb_oidc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export class MongoDBOIDC extends AuthProvider {
*/
override async auth(authContext: AuthContext): Promise<void> {
const { connection, reauthenticating, response } = authContext;
if (response?.speculativeAuthenticate?.done) {
if (response?.speculativeAuthenticate?.done && !reauthenticating) {
return;
}
const credentials = getCredentials(authContext);
Expand Down
93 changes: 93 additions & 0 deletions test/integration/auth/mongodb_oidc.prose.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,99 @@ describe('OIDC Auth Spec Tests', function () {
expect(callbackSpy).to.have.been.calledTwice;
});
});

describe('4.4 Speculative Authentication should be ignored on Reauthentication', function () {
let utilClient: MongoClient;
const callbackSpy = sinon.spy(createCallback());
const saslStarts = [];
// - Create an OIDC configured client.
// - Populate the *Client Cache* with a valid access token to enforce Speculative Authentication.
// - Perform an `insert` operation that succeeds.
// - Assert that the callback was not called.
// - Assert there were no `SaslStart` commands executed.
// - Set a fail point for `insert` commands of the form:
// ```javascript
// {
// configureFailPoint: "failCommand",
// mode: {
// times: 1
// },
// data: {
// failCommands: [
// "insert"
// ],
// errorCode: 391 // ReauthenticationRequired
// }
// }
// ```
// - Perform an `insert` operation that succeeds.
// - Assert that the callback was called once.
// - Assert there were `SaslStart` commands executed.
// - Close the client.
beforeEach(async function () {
utilClient = new MongoClient(uriSingle, {
authMechanismProperties: {
OIDC_CALLBACK: createCallback()
},
retryReads: false
});

client = new MongoClient(uriSingle, {
authMechanismProperties: {
OIDC_CALLBACK: callbackSpy
},
retryReads: false,
monitorCommands: true
});
client.on('commandStarted', event => {
if (event.commandName === 'saslStart') {
saslStarts.push(event);
}
});

const provider = client.s.authProviders.getOrCreateProvider('MONGODB-OIDC', {
OIDC_CALLBACK: callbackSpy
}) as MongoDBOIDC;
const token = await readFile(path.join(process.env.OIDC_TOKEN_DIR, 'test_user1'), {
encoding: 'utf8'
});

provider.workflow.cache.put({ accessToken: token });
collection = client.db('test').collection('test');
});

afterEach(async function () {
await utilClient.db().admin().command({
configureFailPoint: 'failCommand',
mode: 'off'
});
await utilClient.close();
});

it('successfully authenticates', async function () {
await collection.insertOne({ name: 'test' });
expect(callbackSpy).to.not.have.been.called;
expect(saslStarts).to.be.empty;

await utilClient
.db()
.admin()
.command({
configureFailPoint: 'failCommand',
mode: {
times: 1
},
data: {
failCommands: ['insert'],
errorCode: 391
}
});

await collection.insertOne({ name: 'test' });
expect(callbackSpy).to.have.been.calledOnce;
expect(saslStarts.length).to.equal(1);
});
});
});
});

Expand Down

0 comments on commit 8b2b7fd

Please sign in to comment.