Skip to content

Commit f0cb970

Browse files
authored
DOCSP-38206: authentication (#23)
* DOCSP-38206: authentication * CC fix
1 parent 7ee5fd9 commit f0cb970

File tree

2 files changed

+333
-2
lines changed

2 files changed

+333
-2
lines changed

source/tutorials/connect.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ Connect to MongoDB
1414
.. toctree::
1515

1616
/tutorials/connect/tls/
17+
/tutorials/connect/authentication/
1718

18-
.. /tutorials/connect/auth/
1919
.. /tutorials/connect/compression/
2020

2121
.. contents:: On this page
@@ -246,7 +246,11 @@ with programmatic configuration:
246246
.applyConnectionString(connectionString)
247247
.build())
248248

249+
Connection Tutorials
250+
--------------------
251+
249252
To learn how to implement other connection features, see the following
250253
tutorials:
251254

252-
- :ref:`scala-tls`
255+
- :ref:`scala-tls`
256+
- :ref:`scala-auth`
Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
.. _scala-auth:
2+
3+
==============
4+
Authentication
5+
==============
6+
7+
.. facet::
8+
:name: genre
9+
:values: reference
10+
11+
.. meta::
12+
:keywords: code example, verify, AWS, Kerberos
13+
14+
.. contents:: On this page
15+
:local:
16+
:backlinks: none
17+
:depth: 2
18+
:class: singlecol
19+
20+
The driver supports all MongoDB authentication mechanisms,
21+
including those available only in the MongoDB Enterprise Edition.
22+
23+
MongoCredential
24+
---------------
25+
26+
Include the following import statements:
27+
28+
.. code-block:: scala
29+
30+
import org.mongodb.scala._
31+
import scala.collection.JavaConverters._
32+
33+
An authentication credential is represented as an instance of the
34+
``MongoCredential`` class. The ``MongoCredential`` class includes
35+
helper methods for each of the supported authentication
36+
mechanisms.
37+
38+
Default Authentication Mechanism
39+
--------------------------------
40+
41+
In MongoDB 3.0, MongoDB changed the default authentication mechanism
42+
from ``MONGODB-CR`` to ``SCRAM-SHA-1``. In MongoDB 4.0, support for
43+
the deprecated ``MONGODB-CR`` mechanism was removed and
44+
``SCRAM-SHA-256`` support was added.
45+
46+
To create a credential that authenticates by using the default
47+
authentication mechanism, regardless of server version, create a
48+
credential by using the ``createCredential()`` helper method:
49+
50+
.. code-block:: scala
51+
52+
val user: String = ... // the user name
53+
val source: String = ... // the source where the user is defined
54+
val password: Array[Char] = ... // the password as a character array
55+
// ...
56+
val credential = MongoCredential.createCredential(user, source, password)
57+
58+
val mongoClient: MongoClient = MongoClient(
59+
MongoClientSettings.builder()
60+
.applyToClusterSettings((builder: ClusterSettings.Builder) => builder.hosts(List(new ServerAddress("host1", 27017)).asJava))
61+
.credential(credential)
62+
.build())
63+
64+
Or, you can use a connection string without explicitly specifying the
65+
authentication mechanism:
66+
67+
.. code-block:: scala
68+
69+
val mongoClient: MongoClient = MongoClient("mongodb://user1:pwd1@host1/?authSource=db1")
70+
71+
For challenge and response mechanisms, using the default
72+
authentication mechanism is the recommended approach, as it makes
73+
upgrading from MongoDB 2.6 to MongoDB 3.0 more simple, even after
74+
upgrading the authentication schema. For MongoDB 4.0 users, using the
75+
default authentication mechanism is also recommended as the mechanisms are
76+
checked and the correct hashing algorithm is used.
77+
78+
SCRAM-Based Mechanisms
79+
----------------------
80+
81+
Salted Challenge-Response Authentication Mechanism (``SCRAM``) has been
82+
the default authentication mechanism for MongoDB since 3.0. ``SCRAM`` is
83+
based on the `IETF RFC 5802
84+
<https://datatracker.ietf.org/doc/html/rfc5802>`__ standard that defines
85+
best practices for implementation of challenge-response mechanisms for authenticating
86+
users with passwords.
87+
88+
MongoDB 3.0 introduced support for ``SCRAM-SHA-1``, which uses the
89+
``SHA-1`` hashing function. MongoDB 4.0 introduced support for
90+
``SCRAM-SHA-256`` which uses the ``SHA-256`` hashing function.
91+
92+
SCRAM-SHA-256
93+
~~~~~~~~~~~~~
94+
95+
Using this mechanism requires MongoDB 4.0 and
96+
``featureCompatibilityVersion`` to be set to 4.0.
97+
98+
To explicitly create a credential of type ``SCRAM-SHA-256``, use
99+
the ``createScramSha256Credential()`` method:
100+
101+
.. code-block:: scala
102+
103+
val user: String = ... // the user name
104+
val source: String = ... // the source where the user is defined
105+
val password: Array[Char] = ... // the password as a character array
106+
// ...
107+
val credential = MongoCredential.createScramSha256Credential(user, source, password)
108+
109+
val mongoClient: MongoClient = MongoClient(
110+
MongoClientSettings.builder()
111+
.applyToClusterSettings((builder: ClusterSettings.Builder) => builder.hosts(List(new ServerAddress("host1", 27017)).asJava))
112+
.credential(credential)
113+
.build())
114+
115+
Or, you can use a connection string that explicitly specifies
116+
``authMechanism=SCRAM-SHA-256``:
117+
118+
.. code-block:: scala
119+
120+
val mongoClient: MongoClient = MongoClient("mongodb://user1:pwd1@host1/?authSource=db1&authMechanism=SCRAM-SHA-256")
121+
122+
SCRAM-SHA-1
123+
~~~~~~~~~~~
124+
125+
To explicitly create a credential of type ``SCRAM-SHA-1``, use the
126+
``createScramSha1Credential()`` method:
127+
128+
.. code-block:: scala
129+
130+
val user: String = ... // the user name
131+
val source: String = ... // the source where the user is defined
132+
val password: Array[Char] = ... // the password as a character array
133+
// ...
134+
val credential = MongoCredential.createScramSha1Credential(user, source, password)
135+
136+
val mongoClient: MongoClient = MongoClient(
137+
MongoClientSettings.builder()
138+
.applyToClusterSettings((builder: ClusterSettings.Builder) => builder.hosts(List(new ServerAddress("host1", 27017)).asJava))
139+
.credential(credential)
140+
.build())
141+
142+
Or, you can use a connection string that explicitly specifies
143+
``authMechanism=SCRAM-SHA-1``:
144+
145+
.. code-block:: scala
146+
147+
val mongoClient: MongoClient = MongoClient("mongodb://user1:pwd1@host1/?authSource=db1&authMechanism=SCRAM-SHA-1")
148+
149+
MONGODB-CR
150+
----------
151+
152+
.. important::
153+
154+
Starting in version 4.0, MongoDB removes support for the deprecated
155+
MongoDB Challenge-Response (``MONGODB-CR``) authentication mechanism.
156+
157+
If your deployment has user credentials stored in a ``MONGODB-CR`` schema,
158+
you must upgrade to use a ``SCRAM``-based mechanism before you
159+
upgrade to version 4.0.
160+
161+
To explicitly create a credential of type ``MONGODB-CR`` use the
162+
``createMongCRCredential()`` helper method:
163+
164+
.. code-block:: scala
165+
166+
val user: String = ... // the user name
167+
val source: String = ... // the source where the user is defined
168+
val password: Array[Char] = ... // the password as a character array
169+
// ...
170+
val credential = MongoCredential.createMongoCRCredential(user, database, password)
171+
172+
val mongoClient: MongoClient = MongoClient(
173+
MongoClientSettings.builder()
174+
.applyToClusterSettings((builder: ClusterSettings.Builder) => builder.hosts(List(new ServerAddress("host1", 27017)).asJava))
175+
.credential(credential)
176+
.build())
177+
178+
Or, you can use a connection string that explicitly specifies
179+
``authMechanism=MONGODB-CR``:
180+
181+
.. code-block:: scala
182+
183+
val mongoClient: MongoClient = MongoClient("mongodb://user1:pwd1@host1/?authSource=db1&authMechanism=MONGODB-CR")
184+
185+
.. note::
186+
187+
After you upgrade the authentication schema from ``MONGODB-CR`` to ``SCRAM``,
188+
``MONGODB-CR`` credentials will fail to authenticate.
189+
190+
X.509
191+
-----
192+
193+
With the ``X.509`` mechanism, MongoDB uses the X.509 certificate presented
194+
during SSL negotiation to authenticate a user whose name is derived
195+
from the distinguished name of the X.509 certificate.
196+
197+
X.509 authentication requires the use of SSL connections with
198+
certificate validation. To create a credential of this type use the
199+
``createMongoX509Credential()`` helper method:
200+
201+
.. code-block:: scala
202+
203+
val user: String = ... // The X.509 certificate derived user name, e.g. "CN=user,OU=OrgUnit,O=myOrg,..."
204+
// ...
205+
val credential = MongoCredential.createMongoX509Credential(user)
206+
207+
val mongoClient: MongoClient = MongoClient(
208+
MongoClientSettings.builder()
209+
.applyToClusterSettings((builder: ClusterSettings.Builder) => builder.hosts(List(new ServerAddress("host1", 27017)).asJava))
210+
.credential(credential)
211+
.build())
212+
213+
Or, you can use a connection string that explicitly specifies
214+
``authMechanism=MONGODB-X509``:
215+
216+
.. code-block:: scala
217+
218+
val mongoClient: MongoClient = MongoClient("mongodb://subjectName@host1/?authMechanism=MONGODB-X509&ssl=true")
219+
220+
See the :manual:`Use x.509 Certificates to Authenticate Clients </tutorial/configure-x509-client-authentication/>`
221+
tutorial in the Server manual to learn more about
222+
determining the subject name from the certificate.
223+
224+
Kerberos (GSSAPI)
225+
-----------------
226+
227+
MongoDB Enterprise supports proxy authentication through the Kerberos
228+
service. To create a credential of type Kerberos (GSSAPI), use the
229+
``createGSSAPICredential()`` helper method:
230+
231+
.. code-block:: scala
232+
233+
val user: String = ... // The Kerberos user name, including the realm, e.g. "[email protected]"
234+
// ...
235+
val credential = MongoCredential.createGSSAPICredential(user)
236+
237+
val mongoClient: MongoClient = MongoClient(
238+
MongoClientSettings.builder()
239+
.applyToClusterSettings((builder: ClusterSettings.Builder) => builder.hosts(List(new ServerAddress("host1", 27017)).asJava))
240+
.credential(credential)
241+
.build())
242+
243+
Or, you can use a connection string that explicitly specifies
244+
``authMechanism=GSSAPI``:
245+
246+
.. code-block:: scala
247+
248+
val mongoClient: MongoClient = MongoClient("mongodb://username%40REALM.ME@host1/?authMechanism=GSSAPI")
249+
250+
.. note::
251+
252+
The method refers to the ``GSSAPI`` authentication mechanism instead of
253+
``Kerberos`` because the driver authenticates by using the ``GSSAPI`` SASL mechanism.
254+
255+
To successfully authenticate by using Kerberos, the application typically
256+
must specify several system properties so that the underlying GSSAPI
257+
Java libraries can acquire a Kerberos ticket:
258+
259+
.. code-block:: none
260+
261+
java.security.krb5.realm=MYREALM.ME
262+
java.security.krb5.kdc=mykdc.myrealm.me
263+
264+
Depending on the Kerberos setup, additional property specifications
265+
might be required, either within the application code or, in some cases,
266+
by using the ``withMechanismProperty()`` method of the ``MongoCredential``
267+
instance:
268+
269+
- ``SERVICE_NAME``
270+
- ``CANONICALIZE_HOST_NAME``
271+
- ``JAVA_SUBJECT``
272+
- ``JAVA_SASL_CLIENT_PROPERTIES``
273+
274+
The following code shows how to specify the ``SERVICE_NAME`` property within the
275+
``MongoCredential`` object:
276+
277+
.. code-block:: scala
278+
279+
val credentialWithProperty = credential.withMechanismProperty(MongoCredential.SERVICE_NAME_KEY, "othername")
280+
281+
Or, you can specify the ``SERVICE_NAME`` property within the ``ConnectionString``:
282+
283+
.. code-block:: scala
284+
285+
val uri = "mongodb://username%40MYREALM.com@myserver/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:othername"
286+
287+
.. note::
288+
289+
On Windows, Oracles JRE uses `LSA
290+
<https://msdn.microsoft.com/en-us/library/windows/desktop/aa378326.aspx>`__
291+
rather than `SSPI
292+
<https://msdn.microsoft.com/en-us/library/windows/desktop/aa380493.aspx>`__
293+
in its implementation of GSSAPI, which limits interoperability with Windows
294+
Active Directory and in particular the ability to implement single
295+
sign-on.
296+
297+
LDAP (PLAIN)
298+
------------
299+
300+
MongoDB Enterprise supports proxy authentication through a
301+
Lightweight Directory Access Protocol (LDAP) service. To create a
302+
credential of type ``LDAP`` use the ``createPlainCredential()`` helper method:
303+
304+
.. code-block:: scala
305+
306+
val user: String = ... // The LDAP user name
307+
val password: Array[Char] = ... // The LDAP password
308+
// ...
309+
val credential = MongoCredential.createPlainCredential(user, "$external", password)
310+
val mongoClient: MongoClient = MongoClient(
311+
MongoClientSettings.builder()
312+
.applyToClusterSettings((builder: ClusterSettings.Builder) => builder.hosts(List(new ServerAddress("host1", 27017)).asJava))
313+
.credential(credential)
314+
.build())
315+
316+
Or, you can use a connection string that explicitly specifies
317+
``authMechanism=PLAIN``:
318+
319+
.. code-block:: scala
320+
321+
val mongoClient: MongoClient = MongoClient("mongodb://user1@host1/?authSource=$external&authMechanism=PLAIN")
322+
323+
.. note::
324+
325+
The method refers to the ``PLAIN`` authentication mechanism instead of
326+
``LDAP`` because the driver authenticates by using the ``PLAIN``
327+
SASL mechanism.

0 commit comments

Comments
 (0)