From 32a8b98f360cdd9f7bd3626c2d1a43b6e4c670a6 Mon Sep 17 00:00:00 2001 From: Matt Dale <9760375+matthewdale@users.noreply.github.com> Date: Mon, 12 Feb 2024 23:30:13 -0800 Subject: [PATCH 1/7] DRIVERS-2416 Add Azure built-in integration for OIDC. --- source/auth/auth.md | 68 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/source/auth/auth.md b/source/auth/auth.md index 717b9f5175..942b209227 100644 --- a/source/auth/auth.md +++ b/source/auth/auth.md @@ -1217,10 +1217,15 @@ in the MONGODB-OIDC specification, including sections or blocks that specificall - PROVIDER_NAME\ Drivers MUST allow the user to specify the name of a built-in OIDC provider integration to use to - obtain credentials. If provided, the value MUST be one of `["aws"]`. If both `PROVIDER_NAME` and an + obtain credentials. If provided, the value MUST be one of `["aws", "azure"]`. If both `PROVIDER_NAME` and an [OIDC Callback](#oidc-callback) or [OIDC Human Callback](#oidc-human-callback) are provided for the same `MongoClient`, the driver MUST raise an error. + - TOKEN_AUDIENCE\ + The URI of the target resource. This property is currently only used and required by the Azure + built-in OIDC provider integration. If `TOKEN_AUDIENCE` is provided and `PROVIDER_NAME` is not `azure` or + `TOKEN_AUDIENCE` is not provided and `PROVIDER_NAME` is `azure`, the driver MUST raise an error. + - OIDC_CALLBACK\ An [OIDC Callback](#oidc-callback) that returns OIDC credentials. Drivers MAY allow the user to specify an [OIDC Callback](#oidc-callback) using a `MongoClient` configuration instead of a mechanism property, @@ -1250,9 +1255,9 @@ in the MONGODB-OIDC specification, including sections or blocks that specificall Drivers MUST support all of the following built-in OIDC providers. -####### AWS +**AWS** -The AWS provider is enabled by setting auth mechanism property `PROVIDER_NAME:aws`. +The AWS provider integration is enabled by setting auth mechanism property `PROVIDER_NAME:aws`. If enabled, drivers MUST read the file path from 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 @@ -1261,6 +1266,59 @@ OIDC access token from that file. The driver MUST use the contents of that file Drivers MAY implement the AWS provider so that it conforms to the function signature of the [OIDC Callback](#oidc-callback) to prevent having to re-implement the AWS provider logic in the OIDC prose tests. +**Azure** + +The Azure provider integration is enabled by setting auth mechanism property `PROVIDER_NAME:azure`. + +If enabled, drivers MUST call the +[Azure Instance Metadata Service](https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service) +and parse the JSON response body. + +Make an HTTP GET request to + +``` +http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=&object_id= +``` + +with headers + +``` +Accept: application/json +Metadata: true +``` + +where `` is the value of the `TOKEN_AUDIENCE` mechanism property and `` is the `username` from the +connection string. If a `username` is not provided, the `object_id` query parameter should be omitted. + +The curl recipe below demonstrates the above, where `$TOKEN_AUDIENCE` is the value of the `TOKEN_AUDIENCE` mechanism +property. + +```bash +curl -X GET \ + -H "Accept: application/json" \ + -H "Metadata: true" \ + "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=$TOKEN_AUDIENCE" +``` + +The JSON response will be in this format: + +```json +{ + "access_token": "eyJ0eXAi...", + "refresh_token": "", + "expires_in": "3599", + "expires_on": "1506484173", + "not_before": "1506480273", + "resource": "https://management.azure.com/", + "token_type": "Bearer" +} +``` + +The driver MUST use the returned `"access_token"` value as the access token in a `JwtStepRequest`. + +For more details, see +[How to use managed identities for Azure resources on an Azure VM to acquire an access token](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token). + #### OIDC Callback Drivers MUST allow users to provide a callback that returns an OIDC access token. The purpose of the callback is to @@ -1572,7 +1630,7 @@ def invalidate(access_token): Drivers that support the [Human Authentication Flow](#human-authentication-flow) MUST also cache the `IdPInfo` and refresh token in the *Client Cache* when a [OIDC Human Callback](#oidc-human-callback) is configured. -####### Authentication +**Authentication** Use the following algorithm to authenticate a new connection: @@ -1919,6 +1977,8 @@ to EC2 instance metadata in ECS, for security reasons, Amazon states it's best p ## Changelog +- 2024-02-21: Added Azure built-in OIDC provider integration. + - 2024-01-31: Migrated from reStructuredText to Markdown. - 2024-01-17: Added MONGODB-OIDC machine auth flow spec and combine with human\ From 66af2ebfc2a585e0472877f667763b0cc274a21f Mon Sep 17 00:00:00 2001 From: Matt Dale <9760375+matthewdale@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:47:08 -0800 Subject: [PATCH 2/7] Apply suggestions from code review Co-authored-by: Maxim Katcharov --- source/auth/auth.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/auth/auth.md b/source/auth/auth.md index 942b209227..4096574324 100644 --- a/source/auth/auth.md +++ b/source/auth/auth.md @@ -1272,7 +1272,7 @@ The Azure provider integration is enabled by setting auth mechanism property `PR If enabled, drivers MUST call the [Azure Instance Metadata Service](https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service) -and parse the JSON response body. +and parse the JSON response body, as follows: Make an HTTP GET request to @@ -1290,7 +1290,7 @@ Metadata: true where `` is the value of the `TOKEN_AUDIENCE` mechanism property and `` is the `username` from the connection string. If a `username` is not provided, the `object_id` query parameter should be omitted. -The curl recipe below demonstrates the above, where `$TOKEN_AUDIENCE` is the value of the `TOKEN_AUDIENCE` mechanism +Example code for the above using curl, where `$TOKEN_AUDIENCE` is the value of the `TOKEN_AUDIENCE` mechanism property. ```bash From 390e2ee5d3a3401e00b3eaf901a2554fb8fa2b5b Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 11 Mar 2024 21:14:47 -0500 Subject: [PATCH 3/7] Address review --- source/auth/auth.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/source/auth/auth.md b/source/auth/auth.md index 4096574324..3a1a423c59 100644 --- a/source/auth/auth.md +++ b/source/auth/auth.md @@ -1221,10 +1221,10 @@ in the MONGODB-OIDC specification, including sections or blocks that specificall [OIDC Callback](#oidc-callback) or [OIDC Human Callback](#oidc-human-callback) are provided for the same `MongoClient`, the driver MUST raise an error. - - TOKEN_AUDIENCE\ + - TOKEN_RESOURCE\ The URI of the target resource. This property is currently only used and required by the Azure - built-in OIDC provider integration. If `TOKEN_AUDIENCE` is provided and `PROVIDER_NAME` is not `azure` or - `TOKEN_AUDIENCE` is not provided and `PROVIDER_NAME` is `azure`, the driver MUST raise an error. + built-in OIDC provider integration. If `TOKEN_RESOURCE` is provided and `PROVIDER_NAME` is not `azure` or + `TOKEN_RESOURCE` is not provided and `PROVIDER_NAME` is `azure`, the driver MUST raise an error. - OIDC_CALLBACK\ An [OIDC Callback](#oidc-callback) that returns OIDC credentials. Drivers MAY allow the user to @@ -1268,9 +1268,9 @@ Drivers MAY implement the AWS provider so that it conforms to the function signa **Azure** -The Azure provider integration is enabled by setting auth mechanism property `PROVIDER_NAME:azure`. +The Azure provider integration is enabled by setting auth mechanism property `ENVIRONMENT:azure`. -If enabled, drivers MUST call the +If enabled, drivers MUST provide a machine callback that calls the [Azure Instance Metadata Service](https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service) and parse the JSON response body, as follows: @@ -1287,17 +1287,16 @@ Accept: application/json Metadata: true ``` -where `` is the value of the `TOKEN_AUDIENCE` mechanism property and `` is the `username` from the +where `` is the value of the `TOKEN_RESOURCE` mechanism property and `` is the `username` from the connection string. If a `username` is not provided, the `object_id` query parameter should be omitted. -Example code for the above using curl, where `$TOKEN_AUDIENCE` is the value of the `TOKEN_AUDIENCE` mechanism -property. +Example code for the above using curl, where `$TOKEN_RESOURCE` is the value of the `TOKEN_RESOURCE` mechanism property. ```bash curl -X GET \ -H "Accept: application/json" \ -H "Metadata: true" \ - "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=$TOKEN_AUDIENCE" + "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=$TOKEN_RESOURCE" ``` The JSON response will be in this format: @@ -1319,6 +1318,9 @@ The driver MUST use the returned `"access_token"` value as the access token in a For more details, see [How to use managed identities for Azure resources on an Azure VM to acquire an access token](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token). +The callback itself MUST not perform any caching, and the driver MUST cache its tokens in the same way as if a custom +callback had been provided by the user. + #### OIDC Callback Drivers MUST allow users to provide a callback that returns an OIDC access token. The purpose of the callback is to @@ -1336,6 +1338,8 @@ The driver MUST pass the following information to the callback: - `timeout`: A timeout, in milliseconds, a deadline, or a `timeoutContext`. +- `username`: The username given as part of the connection string or `MongoClient` parameter. + - `version`: The callback API version number. The version number is used to communicate callback API changes that are not breaking but that users may want to know about and review their implementation. Drivers MUST pass `1` for the initial callback API version number and increment the version number anytime the API changes. Note that this may @@ -1366,6 +1370,7 @@ An example callback API might look like: ```typescript interface OIDCCallbackParams { callbackTimeoutMS: int; + username: str; version: int; } @@ -1413,6 +1418,7 @@ interface IdpInfo { } interface OIDCCallbackParams { + username: str; callbackTimeoutMS: int; version: int; idpInfo: Optional; From aa3bad6de3b52d2fb1bb3a57870ad358bd77ca1e Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Mon, 11 Mar 2024 21:27:07 -0500 Subject: [PATCH 4/7] Address review --- source/auth/tests/mongodb-oidc.md | 28 ++ source/auth/tests/mongodb-oidc.rst | 436 ----------------------------- 2 files changed, 28 insertions(+), 436 deletions(-) delete mode 100644 source/auth/tests/mongodb-oidc.rst diff --git a/source/auth/tests/mongodb-oidc.md b/source/auth/tests/mongodb-oidc.md index e61cdfd464..91b0949f77 100644 --- a/source/auth/tests/mongodb-oidc.md +++ b/source/auth/tests/mongodb-oidc.md @@ -19,11 +19,19 @@ AWS_WEB_IDENTITY_TOKEN_FILE="$OIDC_TOKEN_DIR/test_user1" /my/test/command ______________________________________________________________________ +## Unified Spec Tests + +Drivers MUST run the unified spec tests in all supported OIDC environments. + +______________________________________________________________________ + ## Prose Tests Drivers MUST implement all prose tests in this section. Unless otherwise noted, all `MongoClient` instances MUST be configured with `retryReads=false`. +Drivers MUST run the prose tests in all supported OIDC environments. + > \[!NOTE\] > > For test cases that create fail points, drivers MUST either use a unique `appName` or explicitly remove the fail point @@ -120,6 +128,24 @@ method, use `mongodb://localhost/?authMechanism=MONGODB-OIDC` for `MONGODB_URI`. - Assert that the callback was called 2 times (once during the connection handshake, and again during reauthentication). - Close the client. +## (5) Azure Tests + +Drivers MUST only run the Azure tests when testing on an Azure VM. See instructions in +[Drivers Evergreen Tools](https://github.com/mongodb-labs/drivers-evergreen-tools/tree/master/.evergreen/auth_oidc/azure#azure-oidc-testing) +for test setup. + +# 5.1 Azure With No Username + +- Create a `MongoClient` configured with `ENVIRONMENT:Azure` and a valid `TOKEN_RESOURCE` and no username. +- Perform a `find` operation that succeeds. +- Close the client. + +# 5.2 Azure with Bad Usernam + +- Create a `MongoClient` configured with `ENVIRONMENT:Azure` and a valid `TOKEN_RESOURCE` and a username of `"bad"`. +- Perform a `find` operation that fails. +- Close the client. + ______________________________________________________________________ ## Human Authentication Flow Prose Tests @@ -127,6 +153,8 @@ ______________________________________________________________________ Drivers that support the [Human Authentication Flow](../auth.md#human-authentication-flow) MUST implement all prose tests in this section. Unless otherwise noted, all `MongoClient` instances MUST be configured with `retryReads=false`. +The human workflow tests MUST only be run when testing in the default environment described beflow. + > \[!NOTE\] > > For test cases that create fail points, drivers MUST either use a unique `appName` or explicitly remove the fail point diff --git a/source/auth/tests/mongodb-oidc.rst b/source/auth/tests/mongodb-oidc.rst deleted file mode 100644 index 682f9c82aa..0000000000 --- a/source/auth/tests/mongodb-oidc.rst +++ /dev/null @@ -1,436 +0,0 @@ -============ -MongoDB OIDC -============ - -Local Testing -============= - -To test locally, use the `oidc_get_tokens.sh`_ script from -`drivers-evergreen-tools`_ to download a set of OIDC tokens, including -`test_user1` and `test_user1_expires`. You first have to install the AWS CLI and -login using the SSO flow. - -For example, if the selected AWS profile ID is "drivers-test", run: - -.. code:: shell - - aws configure sso - export OIDC_TOKEN_DIR=/tmp/tokens - AWS_PROFILE="drivers-test" oidc_get_tokens.sh - AWS_WEB_IDENTITY_TOKEN_FILE="$OIDC_TOKEN_DIR/test_user1" /my/test/command - -.. _oidc_get_tokens.sh: https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/auth_oidc/oidc_get_tokens.sh -.. _drivers-evergreen-tools: https://github.com/mongodb-labs/drivers-evergreen-tools/ - ----------- - -Prose Tests -=========== - -Drivers MUST implement all prose tests in this section. Unless otherwise noted, -all ``MongoClient`` instances MUST be configured with ``retryReads=false``. - -.. note:: - - For test cases that create fail points, drivers MUST either use a unique - ``appName`` or explicitly remove the fail point after the test to prevent - interaction between test cases. - -Note that typically the preconfigured Atlas Dev clusters are used for testing, -in Evergreen and locally. The URIs can be fetched from the ``drivers/oidc`` -Secrets vault, see `vault instructions`_. Use ``OIDC_ATLAS_URI_SINGLE`` for the -``MONGODB_URI``. If using local servers is preferred, using the `Local Testing`_ -method, use ``mongodb://localhost/?authMechanism=MONGODB-OIDC`` for -``MONGODB_URI``. - -(1) OIDC Callback Authentication -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**1.1 Callback is called during authentication** - -- Create a ``MongoClient`` configured with an OIDC callback that implements the - AWS provider logic. -- Perform a ``find`` operation that succeeds. -- Assert that the callback was called 1 time. -- Close the client. - -**1.2 Callback is called once for multiple connections** - -- Create a ``MongoClient`` configured with an OIDC callback that implements the - AWS provider logic. -- Start 10 threads and run 100 ``find`` operations in each thread that all - succeed. -- Assert that the callback was called 1 time. -- Close the client. - -(2) OIDC Callback Validation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**2.1 Valid Callback Inputs** - -- Create a ``MongoClient`` configured with an OIDC callback that validates its - inputs and returns a valid access token. -- Perform a ``find`` operation that succeeds. -- Assert that the OIDC callback was called with the appropriate inputs, - including the timeout parameter if possible. -- Close the client. - -**2.2 OIDC Callback Returns Null** - -- Create a ``MongoClient`` configured with an OIDC callback that returns - ``null``. -- Perform a ``find`` operation that fails. -- Close the client. - -**2.3 OIDC Callback Returns Missing Data** - -- Create a ``MongoClient`` configured with an OIDC callback that returns data - not conforming to the ``OIDCCredential`` with missing fields. -- Perform a ``find`` operation that fails. -- Close the client. - -**2.4 Invalid Client Configuration with Callback** - -- Create a ``MongoClient`` configured with an OIDC callback and auth mechanism - property ``PROVIDER_NAME:aws``. -- Assert it returns a client configuration error. - -(3) Authentication Failure -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**3.1 Authentication failure with cached tokens fetch a new token and retry auth** - -- Create a ``MongoClient`` configured with an OIDC callback that implements the - AWS provider logic. -- Poison the *Client Cache* with an invalid access token. -- Perform a ``find`` operation that succeeds. -- Assert that the callback was called 1 time. -- Close the client. - -**3.2 Authentication failures without cached tokens return an error** - -- Create a ``MongoClient`` configured with an OIDC callback that always returns - invalid access tokens. -- Perform a ``find`` operation that fails. -- Assert that the callback was called 1 time. -- Close the client. - -(4) Reauthentication -~~~~~~~~~~~~~~~~~~~~ - -- Create a ``MongoClient`` configured with an 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 - }, - data: { - failCommands: [ - "find" - ], - errorCode: 391 // ReauthenticationRequired - } - } - -- Perform a ``find`` operation that succeeds. -- Assert that the callback was called 2 times (once during the connection - handshake, and again during reauthentication). -- Close the client. - ----------- - -Human Authentication Flow Prose Tests -===================================== - -Drivers that support the `Human Authentication Flow -<../auth.md#human-authentication-flow>`_ MUST implement all prose tests in -this section. Unless otherwise noted, all ``MongoClient`` instances MUST be -configured with ``retryReads=false``. - -.. note:: - - For test cases that create fail points, drivers MUST either use a unique - ``appName`` or explicitly remove the fail point after the test to prevent - interaction between test cases. - -Drivers MUST be able to authenticate against a server configured with either one -or two configured identity providers. - -Note that typically the preconfigured Atlas Dev clusters are used for testing, -in Evergreen and locally. The URIs can be fetched from the ``drivers/oidc`` -Secrets vault, see `vault instructions`_. Use ``OIDC_ATLAS_URI_SINGLE`` for -``MONGODB_URI_SINGLE`` and ``OIDC_ATLAS_URI_MULTI`` for ``MONGODB_URI_MULTI``. -Currently the ``OIDC_ATLAS_URI_MULTI`` cluster does not work correctly with fail -points, so all prose tests that use fail points SHOULD use -``OIDC_ATLAS_URI_SINGLE``. - -If using local servers is preferred, using the `Local Testing`_ method, use -``mongodb://localhost/?authMechanism=MONGODB-OIDC`` for ``MONGODB_URI_SINGLE`` -and -``mongodb://localhost:27018/?authMechanism=MONGODB-OIDC&directConnection=true&readPreference=secondaryPreferred`` -for ``MONGODB_URI_MULTI`` because the other server is a secondary on a replica -set, on port ``27018``. - -The default OIDC client used in the tests is configured with -``MONGODB_URI_SINGLE`` and a valid human callback handler that returns the -``test_user1`` local token in ``OIDC_TOKEN_DIR`` as the "access_token", and a -dummy "refresh_token". - -.. _Local Testing: https://github.com/mongodb-labs/drivers-evergreen-tools/blob/master/.evergreen/auth_oidc/README.md#local-testing -.. _vault instructions: https://wiki.corp.mongodb.com/display/DRIVERS/Using+AWS+Secrets+Manager+to+Store+Testing+Secrets - -(1) OIDC Human Callback Authentication -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Drivers MUST be able to authenticate using OIDC callback(s) when there -is one principal configured. - -**1.1 Single Principal Implicit Username** - -- Create default OIDC client with ``authMechanism=MONGODB-OIDC``. -- Perform a ``find`` operation that succeeds. -- Close the client. - -**1.2 Single Principal Explicit Username** - -- Create a client with ``MONGODB_URI_SINGLE``, a username of ``test_user1``, - ``authMechanism=MONGODB-OIDC``, and the OIDC human callback. -- Perform a ``find`` operation that succeeds. -- Close the client. - -**1.3 Multiple Principal User 1** - -- Create a client with ``MONGODB_URI_MULTI``, a username of ``test_user1``, - ``authMechanism=MONGODB-OIDC``, and the OIDC human callback. -- Perform a ``find`` operation that succeeds. -- Close the client. - -**1.4 Multiple Principal User 2** - -- Create a human callback that reads in the generated ``test_user2`` token file. -- Create a client with ``MONGODB_URI_MULTI``, a username of ``test_user2``, - ``authMechanism=MONGODB-OIDC``, and the OIDC human callback. -- Perform a ``find`` operation that succeeds. -- Close the client. - -**1.5 Multiple Principal No User** - -- Create a client with ``MONGODB_URI_MULTI``, no username, - ``authMechanism=MONGODB-OIDC``, and the OIDC human callback. -- Assert that a ``find`` operation fails. -- Close the client. - -**1.6 Allowed Hosts Blocked** - -- Create a default OIDC client, with an ``ALLOWED_HOSTS`` that is an empty list. -- Assert that a ``find`` operation fails with a client-side error. -- Close the client. -- Create a client that uses the URL - ``mongodb://localhost/?authMechanism=MONGODB-OIDC&ignored=example.com``, a - human callback, and an ``ALLOWED_HOSTS`` that contains ``["example.com"]``. -- Assert that a ``find`` operation fails with a client-side error. -- Close the client. - -(2) OIDC Human Callback Validation -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**2.1 Valid Callback Inputs** - -- Create a ``MongoClient`` with a human callback that validates its inputs and - returns a valid access token. -- Perform a ``find`` operation that succeeds. Verify that the human - callback was called with the appropriate inputs, including the timeout - parameter if possible. -- Close the client. - -**2.3 Human Callback Returns Missing Data** - -- Create a ``MongoClient`` with a human callback that returns data not - conforming to the ``OIDCCredential`` with missing fields. -- Perform a ``find`` operation that fails. -- Close the client. - -(3) Speculative Authentication -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**3.1 Uses speculative authentication if there is a cached token** - -- Create a ``MongoClient`` with a human callback that returns a valid token. -- Set a fail point for ``find`` commands of the form: - -.. code:: javascript - - { - configureFailPoint: "failCommand", - mode: { - times: 1 - }, - data: { - failCommands: [ - "find" - ], - closeConnection: true - } - } - -- Perform a ``find`` operation that fails. -- Set a fail point for ``saslStart`` commands of the form: - -.. code:: javascript - - { - configureFailPoint: "failCommand", - mode: "alwaysOn", - data: { - failCommands: [ - "saslStart" - ], - errorCode: 20 - } - } - -- Perform a ``find`` operation that succeeds. -- Close the client. - -**3.2 Does not use speculative authentication if there is no cached token** - -- Create a ``MongoClient`` with a human callback that returns a valid token. -- Set a fail point for ``saslStart`` commands of the form: - -.. code:: javascript - - { - configureFailPoint: "failCommand", - mode: "alwaysOn", - data: { - failCommands: [ - "saslStart" - ], - errorCode: 20 // IllegalOperation - } - } - -- Perform a ``find`` operation that fails. -- Close the client. - -(4) Reauthentication -~~~~~~~~~~~~~~~~~~~~ - -**4.1 Succeeds** - -- Create a default OIDC client and add an event listener. The following - assumes that the driver does not emit ``saslStart`` or ``saslContinue`` - events. If the driver does emit those events, ignore/filter them for the - purposes of this test. -- Perform a ``find`` operation that succeeds. -- Assert that the human callback has been called once. -- Clear the listener state if possible. -- Force a reauthenication using a fail point of the form: - -.. code:: javascript - - { - configureFailPoint: "failCommand", - mode: { - times: 1 - }, - data: { - failCommands: [ - "find" - ], - errorCode: 391 // ReauthenticationRequired - } - } - -- Perform another find operation that succeeds. -- Assert that the human callback has been called twice. -- Assert that the ordering of list started events is [``find``], - , ``find``. Note that if the listener stat could not be cleared then there - will and be extra ``find`` command. -- Assert that the list of command succeeded events is [``find``]. -- Assert that a ``find`` operation failed once during the command execution. -- Close the client. - -**4.2 Succeeds no refresh** - -- Create a default OIDC client with a human callback that does not return - a refresh token. -- Perform a ``find`` operation that succeeds. -- Assert that the human callback has been called once. -- Force a reauthenication using a fail point of the form: - -.. code:: javascript - - { - configureFailPoint: "failCommand", - mode: { - times: 1 - }, - data: { - failCommands: [ - "find" - ], - errorCode: 391 // ReauthenticationRequired - } - } - -- Perform a ``find`` operation that succeeds. -- Assert that the human callback has been called twice. -- Close the client. - -**4.3 Succeeds after refresh fails** - -- Create a default OIDC client. -- Perform a ``find`` operation that succeeds. -- Assert that the human callback has been called once. -- Force a reauthenication using a fail point of the form: - -.. code:: javascript - - { - configureFailPoint: "failCommand", - mode: { - times: 2 - }, - data: { - failCommands: [ - "find", "saslStart" - ], - errorCode: 391 // ReauthenticationRequired - } - } - -- Perform a ``find`` operation that succeeds. -- Assert that the human callback has been called 3 times. -- Close the client. - -**4.4 Fails** - -- Create a default OIDC client. -- Perform a find operation that succeeds (to force a speculative auth). -- Assert that the human callback has been called once. -- Force a reauthenication using a failCommand of the form: - -.. code:: javascript - - { - configureFailPoint: "failCommand", - mode: { - times: 3 - }, - data: { - failCommands: [ - "find", "saslStart" - ], - errorCode: 391 // ReauthenticationRequired - } - } - -- Perform a find operation that fails. -- Assert that the human callback has been called twice. -- Close the client. From ddbc70efa1c776f948090fc9922800c9b1968789 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 13 Mar 2024 06:51:45 -0500 Subject: [PATCH 5/7] Update source/auth/auth.md Co-authored-by: Maxim Katcharov --- source/auth/auth.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/auth/auth.md b/source/auth/auth.md index 3a1a423c59..55999a160b 100644 --- a/source/auth/auth.md +++ b/source/auth/auth.md @@ -1270,7 +1270,7 @@ Drivers MAY implement the AWS provider so that it conforms to the function signa The Azure provider integration is enabled by setting auth mechanism property `ENVIRONMENT:azure`. -If enabled, drivers MUST provide a machine callback that calls the +If enabled, drivers MUST use an internal machine callback that calls the [Azure Instance Metadata Service](https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service) and parse the JSON response body, as follows: From ad5cdacd0c31db300edc56ccd6e677527a9a46e0 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Wed, 13 Mar 2024 09:18:12 -0500 Subject: [PATCH 6/7] address review --- source/auth/auth.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/auth/auth.md b/source/auth/auth.md index b21ce98660..6ddd3f6da4 100644 --- a/source/auth/auth.md +++ b/source/auth/auth.md @@ -1285,7 +1285,8 @@ Metadata: true ``` where `` is the value of the `TOKEN_RESOURCE` mechanism property and `` is the `username` from the -connection string. If a `username` is not provided, the `object_id` query parameter should be omitted. +connection string. If a `username` is not provided, the `object_id` query parameter should be omitted. The timeout +should equal the `callbackTimeoutMS` parameter given to the callback. Example code for the above using curl, where `$TOKEN_RESOURCE` is the value of the `TOKEN_RESOURCE` mechanism property. @@ -1293,6 +1294,7 @@ Example code for the above using curl, where `$TOKEN_RESOURCE` is the value of t curl -X GET \ -H "Accept: application/json" \ -H "Metadata: true" \ + --max-time $CALLBACK_TIMEOUT_MS \ "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=$TOKEN_RESOURCE" ``` @@ -1310,7 +1312,8 @@ The JSON response will be in this format: } ``` -The driver MUST use the returned `"access_token"` value as the access token in a `JwtStepRequest`. +The driver MUST use the returned `"access_token"` value as the access token in a `JwtStepRequest`. If the response does +not return a status code of 200, the driver MUST raise an error including the HTTP response body. For more details, see [How to use managed identities for Azure resources on an Azure VM to acquire an access token](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token). From 5eaea530763e1bb0106a4d3dfa8ff48966c9e3c1 Mon Sep 17 00:00:00 2001 From: Steven Silvester Date: Fri, 15 Mar 2024 07:15:40 -0500 Subject: [PATCH 7/7] Use client_id instead of object_id --- source/auth/auth.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/auth/auth.md b/source/auth/auth.md index 6ddd3f6da4..b522d60a4b 100644 --- a/source/auth/auth.md +++ b/source/auth/auth.md @@ -1274,7 +1274,7 @@ and parse the JSON response body, as follows: Make an HTTP GET request to ``` -http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=&object_id= +http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=&client_id= ``` with headers @@ -1284,8 +1284,8 @@ Accept: application/json Metadata: true ``` -where `` is the value of the `TOKEN_RESOURCE` mechanism property and `` is the `username` from the -connection string. If a `username` is not provided, the `object_id` query parameter should be omitted. The timeout +where `` is the value of the `TOKEN_RESOURCE` mechanism property and `` is the `username` from the +connection string. If a `username` is not provided, the `client_id` query parameter should be omitted. The timeout should equal the `callbackTimeoutMS` parameter given to the callback. Example code for the above using curl, where `$TOKEN_RESOURCE` is the value of the `TOKEN_RESOURCE` mechanism property.