From 419e1eed58823de1cf9fe6abbb1a5d5bf60d21ff Mon Sep 17 00:00:00 2001 From: Matt Dale <9760375+matthewdale@users.noreply.github.com> Date: Thu, 7 Dec 2023 03:05:03 -0800 Subject: [PATCH] Wrap up spec and prose tests. --- source/auth/auth.rst | 34 ++++++---- source/auth/tests/mongodb-oidc.rst | 105 +++++++++++++++++++++-------- 2 files changed, 100 insertions(+), 39 deletions(-) diff --git a/source/auth/auth.rst b/source/auth/auth.rst index c2803206b6..bc59b146b1 100644 --- a/source/auth/auth.rst +++ b/source/auth/auth.rst @@ -1211,15 +1211,15 @@ mechanism mechanism_properties PROVIDER_NAME Drivers MUST allow the user to specify the name of the OIDC service to - use to obtain credentials. MUST be one of ["aws"]. If PROVIDER_NAME is - given and a custom callback is configured (either via , the driver MUST - raise an error. + use to obtain credentials. The value MUST be one of ["aws"]. If both + ``PROVIDER_NAME`` and a `custom callback`_ are configured for the same + ``MongoClient``, the driver MUST raise an error. OIDC_TOKEN_CALLBACK Drivers MAY allow the user to specify a custom OIDC callback using a - mechanism property. Drivers MUST support either the ``MongoClient`` - configuration method or the mechanism property, but MUST NOT support - both. + mechanism property. Drivers MUST support specifying a callback either as + a ``MongoClient`` configuration or a mechanism property, but MUST NOT + support both. Supported Providers ``````````````````` @@ -1233,6 +1233,12 @@ environment variable ``AWS_WEB_IDENTITY_TOKEN_FILE`` and then read the OIDC Access Token from that file. The driver MUST use the contents of that file as value in the ``jwt`` field of the ``saslStart`` payload. +Drivers MAY implement the AWS provider so that it conforms to the function +signature of the `custom callback`_ to prevent having to re-implement the AWS +provider logic in the OIDC prose tests. + +.. _`custom callback`: + Custom Callback _______________ Drivers MUST allow the user to integrate with OIDC providers not supported by @@ -1278,7 +1284,7 @@ added to the callback signature in the future. An example might look like: .. code:: typescript - interface OIDCTokenParams { + interface OIDCCallbackParams { callbackTimeoutMS: int; version: int; } @@ -1290,7 +1296,7 @@ added to the callback signature in the future. An example might look like: .. code:: typescript - function oidcToken(params: OIDCTokenParams): OIDCToken + function oidcCallback(params: OIDCCallbackParams): OIDCToken Conversation ```````````` @@ -1308,8 +1314,8 @@ Speculative Authentication Drivers MUST implement speculative authentication for MONGODB-OIDC during the ``hello`` handshake. If there is a cached access token on the ``MongoClient``, use it for authentication. Otherwise, call the configured workload callback to -retrieve a new access token for the new connection and send that access token -with the ``saslStart`` SASL command. +retrieve a new access token and send that access token with the speculative +authentication document. .. _reauthentication: @@ -1367,7 +1373,8 @@ authentication: - Check if the the *Client Cache* has an access token. - If it does, cache the returned access token in *Connection Cache* and optimisitically try to authenticate using the access token. If the server - returns ``AuthenticationFailed`` (error code 18), continue. + returns ``AuthenticationFailed`` (error code 18), slep 100ms then + continue. - Call the access token function for the configured provider or the custom provider callback. - Cache the returned access token in the *Client Cache* and *Connection Cache*. @@ -1391,6 +1398,7 @@ described above: sasl_conversation(conn, {"jwt": token}) return except AuthenticationFailed: + sleep(0.1) invalid_token = token token = client_cache(invalid_token) @@ -1407,7 +1415,8 @@ the following algorithm to manage the caches during `reauthentication`_: token in the *Connection Cache*. - If they are different, cache the returned access token in *Connection Cache* and optimisitically try to authenticate using the access token. If - the server returns ``AuthenticationFailed`` (error code 18), continue. + the server returns ``AuthenticationFailed`` (error code 18), sleep 100ms + then continue. - Call the access token function for the configured provider or the custom provider callback. - Cache the returned access token in the *Client Cache* and *Connection Cache*. @@ -1432,6 +1441,7 @@ above: sasl_conversation(conn, {"jwt": token}) return except AuthenticationFailed: + sleep(0.1) invalid_token = token token = client_cache(invalid_token) diff --git a/source/auth/tests/mongodb-oidc.rst b/source/auth/tests/mongodb-oidc.rst index e49142b9b2..32ce89d960 100644 --- a/source/auth/tests/mongodb-oidc.rst +++ b/source/auth/tests/mongodb-oidc.rst @@ -2,8 +2,6 @@ MongoDB OIDC ============ -TODO - Local Testing ~~~~~~~~~~~~~ @@ -25,34 +23,33 @@ For example, if the selected AWS profile ID is "drivers-test", run: Prose Tests =========== - 1. Custom Callback ~~~~~~~~~~~~~~~~~~ -- Create a ``MongoClient`` configured with an ``OIDCCallback`` set to the - built-in AWS provider callback. +- Create a ``MongoClient`` configured with a custom OIDC callback that + implements the AWS provider logic. - Perform a ``find`` operation that succeeds. - Close the client. 2. Callback is called during reauthentication ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- Create a ``MongoClient`` configured with an ``OIDCCallback`` set to the - built-in AWS provider callback. +- Create a ``MongoClient`` configured with a custom OIDC callback that + implements the AWS provider logic. - Set a fail point for ``find`` commands of the form: .. code:: javascript { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 + configureFailPoint: "failCommand", + mode: { + times: 1 }, - "data": { - "failCommands": [ + data: { + failCommands: [ "find" ], - "errorCode": 391 + errorCode: 391 } } @@ -61,37 +58,91 @@ Prose Tests handshake, and again during reauthentication). - Close the client. -3. Callback is called twice on handshake authentication failure -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +3. Authentication failures with cached tokens retry with a new token +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Create a ``MongoClient`` configured with ``retryReads=false`` and a custom + OIDC callback that implements the AWS provider logic. +- Set a fail point for ``find`` commands of the form: + +.. code:: javascript -- Create a ``MongoClient`` configured with an ``OIDCCallback`` set to the - built-in AWS provider callback. + { + configureFailPoint: "failCommand", + mode: { + times: 1 + }, + data: { + failCommands: [ + "find" + ], + closeConnection: true + } + } + +- Perform a ``find`` operation that fails. This is to force the ``MongoClient`` + to cache an access token. - Set a fail point for ``saslStart`` commands of the form: .. code:: javascript { - "configureFailPoint": "failCommand", - "mode": { - "times": 1 + configureFailPoint: "failCommand", + mode: { + times: 2 }, - "data": { - "failCommands": [ + data: { + failCommands: [ "saslStart" ], - "errorCode": 18 + errorCode: 18 } } -- Perform a ``find`` operation that succeeds. +- Perform a ``find`` operation that fails. - Verify that the callback was called 2 times during connection handshake (once to get the initial token, and once to refresh the token after the authentication failure). - Close the client. -4. Reauthentication messages are sent. -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -TODO +4. Reauthentication messages are sent +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Create a ``MongoClient`` configured with a custom OIDC callback that + implements the AWS provider logic. +- Perform a ``find`` operation that succeeds. +- Set fail points for ``find`` and ``saslStart`` of the form: + +.. code:: javascript + + { + configureFailPoint: "failCommand", + mode: { + times: 1 + }, + data: { + failCommands: [ + "find" + ], + errorCode: 391 + } + } + + { + configureFailPoint: "failCommand", + mode: { + times: 2 + }, + data: { + failCommands: [ + "saslStart" + ], + errorCode: 18 + } + } + +- Perform a ``find`` operation that fails. +- Close the client. ========================= Human Authentication Flow