From 7f3b03ed1f7a93831445c668378606549f09a4a0 Mon Sep 17 00:00:00 2001 From: Rea Rustagi <85902999+rustagir@users.noreply.github.com> Date: Fri, 28 Jun 2024 12:00:05 -0400 Subject: [PATCH] DOCSP-39405: kotlin v5.1 content (#161) * DOCSP-39405: kotlin v5.1 content * NR small fixes * RL tech review comments (cherry picked from commit efd48c978e784705fe55c72a32ae654ce5edf0fd) --- examples/gradle.properties | 2 +- .../src/test/kotlin/EnterpriseAuthTest.kt | 85 +++++++++++ ...st.snippet.oidc-azure-connection-string.kt | 5 + ...eAuthTest.snippet.oidc-azure-credential.kt | 11 ++ ...riseAuthTest.snippet.oidc-callback-file.kt | 14 ++ ...nterpriseAuthTest.snippet.oidc-callback.kt | 5 + ...Test.snippet.oidc-gcp-connection-string.kt | 5 + ...iseAuthTest.snippet.oidc-gcp-credential.kt | 11 ++ .../connection/connection-options.txt | 9 ++ .../connection/mongoclientsettings.txt | 3 + source/fundamentals/enterprise-auth.txt | 140 +++++++++++++++++- source/whats-new.txt | 9 +- 12 files changed, 292 insertions(+), 7 deletions(-) create mode 100644 source/examples/generated/EnterpriseAuthTest.snippet.oidc-azure-connection-string.kt create mode 100644 source/examples/generated/EnterpriseAuthTest.snippet.oidc-azure-credential.kt create mode 100644 source/examples/generated/EnterpriseAuthTest.snippet.oidc-callback-file.kt create mode 100644 source/examples/generated/EnterpriseAuthTest.snippet.oidc-callback.kt create mode 100644 source/examples/generated/EnterpriseAuthTest.snippet.oidc-gcp-connection-string.kt create mode 100644 source/examples/generated/EnterpriseAuthTest.snippet.oidc-gcp-credential.kt diff --git a/examples/gradle.properties b/examples/gradle.properties index 83ff08dc..4c1be229 100644 --- a/examples/gradle.properties +++ b/examples/gradle.properties @@ -1,2 +1,2 @@ kotlin.code.style=official -kotlin_mongodb_version=4.11.0 +kotlin_mongodb_version=5.1.0 diff --git a/examples/src/test/kotlin/EnterpriseAuthTest.kt b/examples/src/test/kotlin/EnterpriseAuthTest.kt index 39dee4af..c30ee505 100644 --- a/examples/src/test/kotlin/EnterpriseAuthTest.kt +++ b/examples/src/test/kotlin/EnterpriseAuthTest.kt @@ -3,9 +3,13 @@ import com.mongodb.ConnectionString import com.mongodb.KerberosSubjectProvider import com.mongodb.MongoClientSettings import com.mongodb.MongoCredential +import com.mongodb.MongoCredential.OidcCallbackResult import com.mongodb.ServerAddress import com.mongodb.kotlin.client.coroutine.MongoClient import kotlinx.coroutines.runBlocking +import java.nio.file.Files +import java.nio.file.Paths +import javax.naming.Context import javax.security.auth.Subject import javax.security.auth.login.LoginContext import kotlin.test.Ignore @@ -113,6 +117,87 @@ internal class EnterpriseAuthTest { val mongoClient = MongoClient.create(connectionString) // :snippet-end: } + + fun oidcAzureConnectionString() = runBlocking { + // :snippet-start: oidc-azure-connection-string + val connectionString = ConnectionString( + "mongodb://@:/?" + + "?authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:") + val mongoClient = MongoClient.create(connectionString) + // :snippet-end: + } + + fun oidcAzureCredential() = runBlocking { + // :snippet-start: oidc-azure-credential + val credential = MongoCredential.createOidcCredential("") + .withMechanismProperty("ENVIRONMENT", "azure") + .withMechanismProperty("TOKEN_RESOURCE", "") + + val mongoClient = MongoClient.create( + MongoClientSettings.builder() + .applyToClusterSettings { builder -> + builder.hosts(listOf(ServerAddress("", PORT))) + } + .credential(credential) + .build()) + // :snippet-end: + } + + fun oidcGCPConnectionString() = runBlocking { + // :snippet-start: oidc-gcp-connection-string + val connectionString = ConnectionString( + "mongodb://:/?" + + "authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:") + val mongoClient = MongoClient.create(connectionString) + // :snippet-end: + } + + fun oidcGCPCredential() = runBlocking { + // :snippet-start: oidc-gcp-credential + val credential = MongoCredential.createOidcCredential("") + .withMechanismProperty("ENVIRONMENT", "gcp") + .withMechanismProperty("TOKEN_RESOURCE", "") + + val mongoClient = MongoClient.create( + MongoClientSettings.builder() + .applyToClusterSettings { builder -> + builder.hosts(listOf(ServerAddress("", PORT))) + } + .credential(credential) + .build()) + // :snippet-end: + } + + fun oidcCallback() = runBlocking { + // :snippet-start: oidc-callback + val credential = MongoCredential.createOidcCredential(null) + .withMechanismProperty("OIDC_CALLBACK") { context: Context -> + val accessToken = "..." + OidcCallbackResult(accessToken) + } + // :snippet-end: + } + + fun oidcCallbackFile() = runBlocking { + // :snippet-start: oidc-callback-file + val credential = MongoCredential.createOidcCredential(null) + .withMechanismProperty("OIDC_CALLBACK") { context: Context -> + val accessToken = String(Files.readAllBytes(Paths.get("access-token.dat"))) + OidcCallbackResult(accessToken) + } + + val mongoClient = MongoClient.create( + MongoClientSettings.builder() + .applyToClusterSettings { builder -> + builder.hosts(listOf(ServerAddress("", PORT))) + } + .credential(credential) + .build() + ) + // :snippet-end: + } } // :replace-end: diff --git a/source/examples/generated/EnterpriseAuthTest.snippet.oidc-azure-connection-string.kt b/source/examples/generated/EnterpriseAuthTest.snippet.oidc-azure-connection-string.kt new file mode 100644 index 00000000..d73b0f59 --- /dev/null +++ b/source/examples/generated/EnterpriseAuthTest.snippet.oidc-azure-connection-string.kt @@ -0,0 +1,5 @@ +val connectionString = ConnectionString( + "mongodb://@:/?" + + "?authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:") +val mongoClient = MongoClient.create(connectionString) diff --git a/source/examples/generated/EnterpriseAuthTest.snippet.oidc-azure-credential.kt b/source/examples/generated/EnterpriseAuthTest.snippet.oidc-azure-credential.kt new file mode 100644 index 00000000..cad36ee2 --- /dev/null +++ b/source/examples/generated/EnterpriseAuthTest.snippet.oidc-azure-credential.kt @@ -0,0 +1,11 @@ +val credential = MongoCredential.createOidcCredential("") + .withMechanismProperty("ENVIRONMENT", "azure") + .withMechanismProperty("TOKEN_RESOURCE", "") + +val mongoClient = MongoClient.create( + MongoClientSettings.builder() + .applyToClusterSettings { builder -> + builder.hosts(listOf(ServerAddress("", ))) + } + .credential(credential) + .build()) diff --git a/source/examples/generated/EnterpriseAuthTest.snippet.oidc-callback-file.kt b/source/examples/generated/EnterpriseAuthTest.snippet.oidc-callback-file.kt new file mode 100644 index 00000000..fc6e8b7b --- /dev/null +++ b/source/examples/generated/EnterpriseAuthTest.snippet.oidc-callback-file.kt @@ -0,0 +1,14 @@ +val credential = MongoCredential.createOidcCredential(null) + .withMechanismProperty("OIDC_CALLBACK") { context: Context -> + val accessToken = String(Files.readAllBytes(Paths.get("access-token.dat"))) + OidcCallbackResult(accessToken) + } + +val mongoClient = MongoClient.create( + MongoClientSettings.builder() + .applyToClusterSettings { builder -> + builder.hosts(listOf(ServerAddress("", ))) + } + .credential(credential) + .build() +) diff --git a/source/examples/generated/EnterpriseAuthTest.snippet.oidc-callback.kt b/source/examples/generated/EnterpriseAuthTest.snippet.oidc-callback.kt new file mode 100644 index 00000000..6e3bd252 --- /dev/null +++ b/source/examples/generated/EnterpriseAuthTest.snippet.oidc-callback.kt @@ -0,0 +1,5 @@ +val credential = MongoCredential.createOidcCredential(null) + .withMechanismProperty("OIDC_CALLBACK") { context: Context -> + val accessToken = "..." + OidcCallbackResult(accessToken) + } diff --git a/source/examples/generated/EnterpriseAuthTest.snippet.oidc-gcp-connection-string.kt b/source/examples/generated/EnterpriseAuthTest.snippet.oidc-gcp-connection-string.kt new file mode 100644 index 00000000..874c7bfe --- /dev/null +++ b/source/examples/generated/EnterpriseAuthTest.snippet.oidc-gcp-connection-string.kt @@ -0,0 +1,5 @@ +val connectionString = ConnectionString( + "mongodb://:/?" + + "authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:") +val mongoClient = MongoClient.create(connectionString) diff --git a/source/examples/generated/EnterpriseAuthTest.snippet.oidc-gcp-credential.kt b/source/examples/generated/EnterpriseAuthTest.snippet.oidc-gcp-credential.kt new file mode 100644 index 00000000..3a2d0782 --- /dev/null +++ b/source/examples/generated/EnterpriseAuthTest.snippet.oidc-gcp-credential.kt @@ -0,0 +1,11 @@ +val credential = MongoCredential.createOidcCredential("") + .withMechanismProperty("ENVIRONMENT", "gcp") + .withMechanismProperty("TOKEN_RESOURCE", "") + +val mongoClient = MongoClient.create( + MongoClientSettings.builder() + .applyToClusterSettings { builder -> + builder.hosts(listOf(ServerAddress("", ))) + } + .credential(credential) + .build()) diff --git a/source/fundamentals/connection/connection-options.txt b/source/fundamentals/connection/connection-options.txt index e972ecc1..d43dc7a9 100644 --- a/source/fundamentals/connection/connection-options.txt +++ b/source/fundamentals/connection/connection-options.txt @@ -261,6 +261,15 @@ parameters of the connection URI to specify the behavior of the client. | **Default**: ``true`` + * - **serverMonitoringMode** + - string + - Specifies which server monitoring protocol the driver uses. When set to + ``auto``, the monitoring mode is determined by the environment in which + the driver is running. The driver uses ``poll`` mode in function-as-a-service + (FaaS) environments and ``stream`` mode in other environments. + + | **Default**: ``auto`` + * - **uuidRepresentation** - string - Specifies the UUID representation to use for read and write diff --git a/source/fundamentals/connection/mongoclientsettings.txt b/source/fundamentals/connection/mongoclientsettings.txt index 84943672..f3dd9e60 100644 --- a/source/fundamentals/connection/mongoclientsettings.txt +++ b/source/fundamentals/connection/mongoclientsettings.txt @@ -433,6 +433,9 @@ settings to modify the driver's behavior: * - ``minHeartbeatFrequency()`` - Sets the minimum interval for server monitoring checks. + * - ``serverMonitoringMode()`` + - Specifies which server monitoring protocol the driver uses. + Example ~~~~~~~ diff --git a/source/fundamentals/enterprise-auth.txt b/source/fundamentals/enterprise-auth.txt index c1946caf..1daa1997 100644 --- a/source/fundamentals/enterprise-auth.txt +++ b/source/fundamentals/enterprise-auth.txt @@ -4,6 +4,14 @@ Enterprise Authentication Mechanisms ==================================== +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: ldap, encryption, principal, tls + + .. contents:: On this page :local: :backlinks: none @@ -22,6 +30,7 @@ Enterprise Edition: - :ref:`Kerberos (GSSAPI) ` - :ref:`LDAP (PLAIN) ` +- :ref:`MONGODB-OIDC ` :doc:`Authentication Mechanisms guide `. @@ -278,4 +287,133 @@ mechanism: .. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.ldap-mongo-credential.kt :language: kotlin - \ No newline at end of file + +.. _kotlin-oidc: + +MONGODB-OIDC +~~~~~~~~~~~~ + +.. important:: + + The MONGODB-OIDC authentication mechanism requires {+mdb-server+} v7.0 or later running + on a Linux platform. + +The following sections describe how to use the MONGODB-OIDC +authentication mechanism to authenticate to various platforms. + +For more information about the MONGODB-OIDC authentication mechanism, see +:manual:`OpenID Connect Authentication ` and +:manual:`MongoDB Server Parameters ` +in the MongoDB Server manual. + +.. _kotlin-mongodb-oidc-azure-imds: + +Azure IMDS +++++++++++ + +If your application runs on an Azure VM, or otherwise uses the +`Azure Instance Metadata Service `__ +(IMDS), you can authenticate to MongoDB by using the {+driver-short+}'s built-in Azure +support. + +You can specify Azure IMDS OIDC authentication either by +using a ``MongoCredential`` instance or by specifying your credentials +in the connection string. + +Select from the :guilabel:`Connection String` or :guilabel:`MongoCredential` tabs to +see the corresponding syntax. + +.. tabs:: + + .. tab:: Connection String + :tabid: mongodb-azure-imds-connection-string + + Replace the ```` placeholder in the + following code with the percent-encoded value of the audience server + parameter configured on your MongoDB deployment. + + The comma (``,``) character and its encoding (``%2C``) are + reserved, and using these characters in a value causes the + driver to interpret commas as delimiters of key-value pairs. + You must specify values that contain commas in a ``MongoCredential`` instance, as + demonstrated in the :guilabel:`MongoCredential` tab. + + .. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.oidc-azure-connection-string.kt + :language: kotlin + + .. tab:: MongoCredential + :tabid: mongodb-azure-mongo-credential + + Replace the ```` placeholder with the client ID or application ID of the + Azure managed identity or enterprise application. Replace the ```` + placeholder with the value of the + ``audience`` server parameter configured on your MongoDB deployment. + + .. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.oidc-azure-credential.kt + :language: kotlin + +.. _kotlin-mongodb-oidc-gcp-imds: + +GCP IMDS +++++++++ + +If your application runs on a Google Compute Engine VM, or otherwise uses the +`GCP Instance Metadata Service `__, +you can authenticate to MongoDB by using the {+driver-short+}'s built-in GCP +support. + +You can specify GCP IMDS OIDC authentication either by +using a ``MongoCredential`` instance or by specifying your credentials +in the connection string. + +Select from the :guilabel:`Connection String` or :guilabel:`MongoCredential` tabs to +see the corresponding syntax. + +.. tabs:: + + .. tab:: Connection String + :tabid: mongodb-gcp-imds-connection-string + + Replace the ```` placeholder in the + following code with the percent-encoded value of the audience server + parameter configured on your MongoDB deployment. + + The comma (``,``) character and its encoding (``%2C``) are + reserved, and using these characters in a value causes the + driver to interpret commas as delimiters of key-value pairs. + You must specify values that contain commas in a ``MongoCredential`` instance, as + demonstrated in the :guilabel:`MongoCredential` tab. + + .. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.oidc-gcp-connection-string.kt + :language: kotlin + + .. tab:: MongoCredential + :tabid: mongodb-gcp-mongo-credential + + Replace the ```` placeholder with the value of the + ``audience`` server parameter configured on your MongoDB deployment. + + .. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.oidc-gcp-credential.kt + :language: kotlin + +Custom Callback ++++++++++++++++ + +The {+driver-short+} doesn't offer built-in support for all platforms, including +Azure Functions and Azure Kubernetes Service (AKS). Instead, you +must define a custom callback to use OIDC to authenticate from these platforms. +To do so, use the ``"OIDC_CALLBACK"`` authentication property, as shown in the following +code example: + +.. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.oidc-callback.kt + :language: kotlin + +The value of the ``"OIDC_CALLBACK"`` property must be a lambda or other implementation +of the ``OidcCallback`` functional interface that accepts an ``OidcCallbackContext`` +as a parameter and returns an ``OidcCallbackResult``. + +The following example uses an example callback to retrieve an OIDC token from a file +named ``"access-token.dat"`` in the local file system: + +.. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.oidc-callback-file.kt + :language: kotlin diff --git a/source/whats-new.txt b/source/whats-new.txt index 4c0acfd4..2b2c91ee 100644 --- a/source/whats-new.txt +++ b/source/whats-new.txt @@ -52,8 +52,8 @@ Improvements in 5.1 native applications by using the GraalVM native-image tool. - Enhanced support for the ``MONGODB-OIDC`` authentication mechanism. - -.. TODO add OIDC content and link + To learn more about OIDC, see the :ref:`kotlin-oidc` section of the + Enterprise Authentication Mechanisms guide. - Fixes an issue in which operations used the incorrect codec when using a polymorphic ``MongoCollection`` instance. This ensures that @@ -72,9 +72,8 @@ New Features in 5.1 .. TODO add polymorphic serialization content -- Introduces the ``serverMonitoringMode`` connection URI option. - -.. TODO add serverMonitoringMode content and link +- Introduces the ``serverMonitoringMode`` connection URI option. To + learn more, see the :ref:`connection-options` guide. .. _version-5.0: