Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
92 changes: 92 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,98 @@ 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 () {
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');

await collection.insertOne({ name: 'test' });
expect(callbackSpy).to.not.have.been.called;
expect(saslStarts).to.be.empty;

utilClient = new MongoClient(uriSingle, {
authMechanismProperties: {
OIDC_CALLBACK: createCallback()
},
retryReads: false
});

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

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.have.been.calledOnce;
expect(saslStarts.length).to.equal(1);
});
});
});
});

Expand Down
Loading