Skip to content

Commit efd48c9

Browse files
authored
DOCSP-39405: kotlin v5.1 content (#161)
* DOCSP-39405: kotlin v5.1 content * NR small fixes * RL tech review comments
1 parent f78b102 commit efd48c9

12 files changed

+292
-7
lines changed

examples/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
kotlin.code.style=official
2-
kotlin_mongodb_version=4.11.0
2+
kotlin_mongodb_version=5.1.0

examples/src/test/kotlin/EnterpriseAuthTest.kt

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ import com.mongodb.ConnectionString
33
import com.mongodb.KerberosSubjectProvider
44
import com.mongodb.MongoClientSettings
55
import com.mongodb.MongoCredential
6+
import com.mongodb.MongoCredential.OidcCallbackResult
67
import com.mongodb.ServerAddress
78
import com.mongodb.kotlin.client.coroutine.MongoClient
89
import kotlinx.coroutines.runBlocking
10+
import java.nio.file.Files
11+
import java.nio.file.Paths
12+
import javax.naming.Context
913
import javax.security.auth.Subject
1014
import javax.security.auth.login.LoginContext
1115
import kotlin.test.Ignore
@@ -113,6 +117,87 @@ internal class EnterpriseAuthTest {
113117
val mongoClient = MongoClient.create(connectionString)
114118
// :snippet-end:
115119
}
120+
121+
fun oidcAzureConnectionString() = runBlocking {
122+
// :snippet-start: oidc-azure-connection-string
123+
val connectionString = ConnectionString(
124+
"mongodb://<username>@<hostname>:<port>/?" +
125+
"?authMechanism=MONGODB-OIDC" +
126+
"&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:<percent-encoded audience>")
127+
val mongoClient = MongoClient.create(connectionString)
128+
// :snippet-end:
129+
}
130+
131+
fun oidcAzureCredential() = runBlocking {
132+
// :snippet-start: oidc-azure-credential
133+
val credential = MongoCredential.createOidcCredential("<username>")
134+
.withMechanismProperty("ENVIRONMENT", "azure")
135+
.withMechanismProperty("TOKEN_RESOURCE", "<audience>")
136+
137+
val mongoClient = MongoClient.create(
138+
MongoClientSettings.builder()
139+
.applyToClusterSettings { builder ->
140+
builder.hosts(listOf(ServerAddress("<hostname>", PORT)))
141+
}
142+
.credential(credential)
143+
.build())
144+
// :snippet-end:
145+
}
146+
147+
fun oidcGCPConnectionString() = runBlocking {
148+
// :snippet-start: oidc-gcp-connection-string
149+
val connectionString = ConnectionString(
150+
"mongodb://<hostname>:<port>/?" +
151+
"authMechanism=MONGODB-OIDC" +
152+
"&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:<percent-encoded audience>")
153+
val mongoClient = MongoClient.create(connectionString)
154+
// :snippet-end:
155+
}
156+
157+
fun oidcGCPCredential() = runBlocking {
158+
// :snippet-start: oidc-gcp-credential
159+
val credential = MongoCredential.createOidcCredential("<username>")
160+
.withMechanismProperty("ENVIRONMENT", "gcp")
161+
.withMechanismProperty("TOKEN_RESOURCE", "<audience>")
162+
163+
val mongoClient = MongoClient.create(
164+
MongoClientSettings.builder()
165+
.applyToClusterSettings { builder ->
166+
builder.hosts(listOf(ServerAddress("<hostname>", PORT)))
167+
}
168+
.credential(credential)
169+
.build())
170+
// :snippet-end:
171+
}
172+
173+
fun oidcCallback() = runBlocking {
174+
// :snippet-start: oidc-callback
175+
val credential = MongoCredential.createOidcCredential(null)
176+
.withMechanismProperty("OIDC_CALLBACK") { context: Context ->
177+
val accessToken = "..."
178+
OidcCallbackResult(accessToken)
179+
}
180+
// :snippet-end:
181+
}
182+
183+
fun oidcCallbackFile() = runBlocking {
184+
// :snippet-start: oidc-callback-file
185+
val credential = MongoCredential.createOidcCredential(null)
186+
.withMechanismProperty("OIDC_CALLBACK") { context: Context ->
187+
val accessToken = String(Files.readAllBytes(Paths.get("access-token.dat")))
188+
OidcCallbackResult(accessToken)
189+
}
190+
191+
val mongoClient = MongoClient.create(
192+
MongoClientSettings.builder()
193+
.applyToClusterSettings { builder ->
194+
builder.hosts(listOf(ServerAddress("<hostname>", PORT)))
195+
}
196+
.credential(credential)
197+
.build()
198+
)
199+
// :snippet-end:
200+
}
116201
}
117202
// :replace-end:
118203

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
val connectionString = ConnectionString(
2+
"mongodb://<username>@<hostname>:<port>/?" +
3+
"?authMechanism=MONGODB-OIDC" +
4+
"&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:<percent-encoded audience>")
5+
val mongoClient = MongoClient.create(connectionString)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
val credential = MongoCredential.createOidcCredential("<username>")
2+
.withMechanismProperty("ENVIRONMENT", "azure")
3+
.withMechanismProperty("TOKEN_RESOURCE", "<audience>")
4+
5+
val mongoClient = MongoClient.create(
6+
MongoClientSettings.builder()
7+
.applyToClusterSettings { builder ->
8+
builder.hosts(listOf(ServerAddress("<hostname>", <port>)))
9+
}
10+
.credential(credential)
11+
.build())
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
val credential = MongoCredential.createOidcCredential(null)
2+
.withMechanismProperty("OIDC_CALLBACK") { context: Context ->
3+
val accessToken = String(Files.readAllBytes(Paths.get("access-token.dat")))
4+
OidcCallbackResult(accessToken)
5+
}
6+
7+
val mongoClient = MongoClient.create(
8+
MongoClientSettings.builder()
9+
.applyToClusterSettings { builder ->
10+
builder.hosts(listOf(ServerAddress("<hostname>", <port>)))
11+
}
12+
.credential(credential)
13+
.build()
14+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
val credential = MongoCredential.createOidcCredential(null)
2+
.withMechanismProperty("OIDC_CALLBACK") { context: Context ->
3+
val accessToken = "..."
4+
OidcCallbackResult(accessToken)
5+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
val connectionString = ConnectionString(
2+
"mongodb://<hostname>:<port>/?" +
3+
"authMechanism=MONGODB-OIDC" +
4+
"&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:<percent-encoded audience>")
5+
val mongoClient = MongoClient.create(connectionString)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
val credential = MongoCredential.createOidcCredential("<username>")
2+
.withMechanismProperty("ENVIRONMENT", "gcp")
3+
.withMechanismProperty("TOKEN_RESOURCE", "<audience>")
4+
5+
val mongoClient = MongoClient.create(
6+
MongoClientSettings.builder()
7+
.applyToClusterSettings { builder ->
8+
builder.hosts(listOf(ServerAddress("<hostname>", <port>)))
9+
}
10+
.credential(credential)
11+
.build())

source/fundamentals/connection/connection-options.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,15 @@ parameters of the connection URI to specify the behavior of the client.
261261

262262
| **Default**: ``true``
263263

264+
* - **serverMonitoringMode**
265+
- string
266+
- Specifies which server monitoring protocol the driver uses. When set to
267+
``auto``, the monitoring mode is determined by the environment in which
268+
the driver is running. The driver uses ``poll`` mode in function-as-a-service
269+
(FaaS) environments and ``stream`` mode in other environments.
270+
271+
| **Default**: ``auto``
272+
264273
* - **uuidRepresentation**
265274
- string
266275
- Specifies the UUID representation to use for read and write

source/fundamentals/connection/mongoclientsettings.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,9 @@ settings to modify the driver's behavior:
433433
* - ``minHeartbeatFrequency()``
434434
- Sets the minimum interval for server monitoring checks.
435435

436+
* - ``serverMonitoringMode()``
437+
- Specifies which server monitoring protocol the driver uses.
438+
436439
Example
437440
~~~~~~~
438441

source/fundamentals/enterprise-auth.txt

Lines changed: 139 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@
44
Enterprise Authentication Mechanisms
55
====================================
66

7+
.. facet::
8+
:name: genre
9+
:values: reference
10+
11+
.. meta::
12+
:keywords: ldap, encryption, principal, tls
13+
14+
715
.. contents:: On this page
816
:local:
917
:backlinks: none
@@ -22,6 +30,7 @@ Enterprise Edition:
2230

2331
- :ref:`Kerberos (GSSAPI) <gssapi-auth-mechanism>`
2432
- :ref:`LDAP (PLAIN) <plain-auth-mechanism>`
33+
- :ref:`MONGODB-OIDC <kotlin-oidc>`
2534

2635
:doc:`Authentication Mechanisms guide </fundamentals/auth>`.
2736

@@ -278,4 +287,133 @@ mechanism:
278287

279288
.. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.ldap-mongo-credential.kt
280289
:language: kotlin
281-
290+
291+
.. _kotlin-oidc:
292+
293+
MONGODB-OIDC
294+
~~~~~~~~~~~~
295+
296+
.. important::
297+
298+
The MONGODB-OIDC authentication mechanism requires {+mdb-server+} v7.0 or later running
299+
on a Linux platform.
300+
301+
The following sections describe how to use the MONGODB-OIDC
302+
authentication mechanism to authenticate to various platforms.
303+
304+
For more information about the MONGODB-OIDC authentication mechanism, see
305+
:manual:`OpenID Connect Authentication </core/security-oidc/>` and
306+
:manual:`MongoDB Server Parameters </reference/parameters/#mongodb-parameter-param.oidcIdentityProviders>`
307+
in the MongoDB Server manual.
308+
309+
.. _kotlin-mongodb-oidc-azure-imds:
310+
311+
Azure IMDS
312+
++++++++++
313+
314+
If your application runs on an Azure VM, or otherwise uses the
315+
`Azure Instance Metadata Service <https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service>`__
316+
(IMDS), you can authenticate to MongoDB by using the {+driver-short+}'s built-in Azure
317+
support.
318+
319+
You can specify Azure IMDS OIDC authentication either by
320+
using a ``MongoCredential`` instance or by specifying your credentials
321+
in the connection string.
322+
323+
Select from the :guilabel:`Connection String` or :guilabel:`MongoCredential` tabs to
324+
see the corresponding syntax.
325+
326+
.. tabs::
327+
328+
.. tab:: Connection String
329+
:tabid: mongodb-azure-imds-connection-string
330+
331+
Replace the ``<percent-encoded audience>`` placeholder in the
332+
following code with the percent-encoded value of the audience server
333+
parameter configured on your MongoDB deployment.
334+
335+
The comma (``,``) character and its encoding (``%2C``) are
336+
reserved, and using these characters in a value causes the
337+
driver to interpret commas as delimiters of key-value pairs.
338+
You must specify values that contain commas in a ``MongoCredential`` instance, as
339+
demonstrated in the :guilabel:`MongoCredential` tab.
340+
341+
.. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.oidc-azure-connection-string.kt
342+
:language: kotlin
343+
344+
.. tab:: MongoCredential
345+
:tabid: mongodb-azure-mongo-credential
346+
347+
Replace the ``<username>`` placeholder with the client ID or application ID of the
348+
Azure managed identity or enterprise application. Replace the ``<audience>``
349+
placeholder with the value of the
350+
``audience`` server parameter configured on your MongoDB deployment.
351+
352+
.. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.oidc-azure-credential.kt
353+
:language: kotlin
354+
355+
.. _kotlin-mongodb-oidc-gcp-imds:
356+
357+
GCP IMDS
358+
++++++++
359+
360+
If your application runs on a Google Compute Engine VM, or otherwise uses the
361+
`GCP Instance Metadata Service <https://cloud.google.com/compute/docs/metadata/querying-metadata>`__,
362+
you can authenticate to MongoDB by using the {+driver-short+}'s built-in GCP
363+
support.
364+
365+
You can specify GCP IMDS OIDC authentication either by
366+
using a ``MongoCredential`` instance or by specifying your credentials
367+
in the connection string.
368+
369+
Select from the :guilabel:`Connection String` or :guilabel:`MongoCredential` tabs to
370+
see the corresponding syntax.
371+
372+
.. tabs::
373+
374+
.. tab:: Connection String
375+
:tabid: mongodb-gcp-imds-connection-string
376+
377+
Replace the ``<percent-encoded audience>`` placeholder in the
378+
following code with the percent-encoded value of the audience server
379+
parameter configured on your MongoDB deployment.
380+
381+
The comma (``,``) character and its encoding (``%2C``) are
382+
reserved, and using these characters in a value causes the
383+
driver to interpret commas as delimiters of key-value pairs.
384+
You must specify values that contain commas in a ``MongoCredential`` instance, as
385+
demonstrated in the :guilabel:`MongoCredential` tab.
386+
387+
.. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.oidc-gcp-connection-string.kt
388+
:language: kotlin
389+
390+
.. tab:: MongoCredential
391+
:tabid: mongodb-gcp-mongo-credential
392+
393+
Replace the ``<audience>`` placeholder with the value of the
394+
``audience`` server parameter configured on your MongoDB deployment.
395+
396+
.. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.oidc-gcp-credential.kt
397+
:language: kotlin
398+
399+
Custom Callback
400+
+++++++++++++++
401+
402+
The {+driver-short+} doesn't offer built-in support for all platforms, including
403+
Azure Functions and Azure Kubernetes Service (AKS). Instead, you
404+
must define a custom callback to use OIDC to authenticate from these platforms.
405+
To do so, use the ``"OIDC_CALLBACK"`` authentication property, as shown in the following
406+
code example:
407+
408+
.. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.oidc-callback.kt
409+
:language: kotlin
410+
411+
The value of the ``"OIDC_CALLBACK"`` property must be a lambda or other implementation
412+
of the ``OidcCallback`` functional interface that accepts an ``OidcCallbackContext``
413+
as a parameter and returns an ``OidcCallbackResult``.
414+
415+
The following example uses an example callback to retrieve an OIDC token from a file
416+
named ``"access-token.dat"`` in the local file system:
417+
418+
.. literalinclude:: /examples/generated/EnterpriseAuthTest.snippet.oidc-callback-file.kt
419+
:language: kotlin

source/whats-new.txt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ Improvements in 5.1
5252
native applications by using the GraalVM native-image tool.
5353

5454
- Enhanced support for the ``MONGODB-OIDC`` authentication mechanism.
55-
56-
.. TODO add OIDC content and link
55+
To learn more about OIDC, see the :ref:`kotlin-oidc` section of the
56+
Enterprise Authentication Mechanisms guide.
5757

5858
- Fixes an issue in which operations used the incorrect codec when using
5959
a polymorphic ``MongoCollection`` instance. This ensures that
@@ -72,9 +72,8 @@ New Features in 5.1
7272

7373
.. TODO add polymorphic serialization content
7474

75-
- Introduces the ``serverMonitoringMode`` connection URI option.
76-
77-
.. TODO add serverMonitoringMode content and link
75+
- Introduces the ``serverMonitoringMode`` connection URI option. To
76+
learn more, see the :ref:`connection-options` guide.
7877

7978
.. _version-5.0:
8079

0 commit comments

Comments
 (0)