Skip to content

Commit ad3292e

Browse files
authored
PYTHON-4922 Remove Support for MONGODB-CR Authentication (mongodb#1978)
1 parent 9a11b78 commit ad3292e

File tree

9 files changed

+13
-127
lines changed

9 files changed

+13
-127
lines changed

doc/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ PyMongo 4.11 brings a number of changes including:
1212

1313
- Dropped support for Python 3.8.
1414
- Dropped support for MongoDB 3.6.
15+
- Dropped support for the MONGODB-CR authenticate mechanism, which is no longer supported by MongoDB 4.0+.
1516
- Added support for free-threaded Python with the GIL disabled. For more information see:
1617
`Free-threaded CPython <https://docs.python.org/3.13/whatsnew/3.13.html#whatsnew313-free-threaded-cpython>`_.
1718
- :attr:`~pymongo.asynchronous.mongo_client.AsyncMongoClient.address` and

doc/examples/authentication.rst

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -76,24 +76,6 @@ For best performance on Python versions older than 2.7.8 install `backports.pbkd
7676

7777
.. _backports.pbkdf2: https://pypi.python.org/pypi/backports.pbkdf2/
7878

79-
MONGODB-CR
80-
----------
81-
82-
.. warning:: MONGODB-CR was deprecated with the release of MongoDB 3.6 and
83-
is no longer supported by MongoDB 4.0.
84-
85-
Before MongoDB 3.0 the default authentication mechanism was MONGODB-CR,
86-
the "MongoDB Challenge-Response" protocol::
87-
88-
>>> from pymongo import MongoClient
89-
>>> client = MongoClient('example.com',
90-
... username='user',
91-
... password='password',
92-
... authMechanism='MONGODB-CR')
93-
>>>
94-
>>> uri = "mongodb://user:[email protected]/?authSource=the_database&authMechanism=MONGODB-CR"
95-
>>> client = MongoClient(uri)
96-
9779
Default Authentication Mechanism
9880
--------------------------------
9981

@@ -221,8 +203,7 @@ SASL PLAIN (RFC 4616)
221203

222204
MongoDB Enterprise Edition version 2.6 and newer support the SASL PLAIN
223205
authentication mechanism, initially intended for delegating authentication
224-
to an LDAP server. Using the PLAIN mechanism is very similar to MONGODB-CR.
225-
These examples use the $external virtual database for LDAP support::
206+
to an LDAP server. These examples use the $external virtual database for LDAP support::
226207

227208
>>> from pymongo import MongoClient
228209
>>> uri = "mongodb://user:[email protected]/?authMechanism=PLAIN"

pymongo/asynchronous/auth.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -329,21 +329,6 @@ async def _authenticate_x509(credentials: MongoCredential, conn: AsyncConnection
329329
await conn.command("$external", cmd)
330330

331331

332-
async def _authenticate_mongo_cr(credentials: MongoCredential, conn: AsyncConnection) -> None:
333-
"""Authenticate using MONGODB-CR."""
334-
source = credentials.source
335-
username = credentials.username
336-
password = credentials.password
337-
# Get a nonce
338-
response = await conn.command(source, {"getnonce": 1})
339-
nonce = response["nonce"]
340-
key = _auth_key(nonce, username, password)
341-
342-
# Actually authenticate
343-
query = {"authenticate": 1, "user": username, "nonce": nonce, "key": key}
344-
await conn.command(source, query)
345-
346-
347332
async def _authenticate_default(credentials: MongoCredential, conn: AsyncConnection) -> None:
348333
if conn.max_wire_version >= 7:
349334
if conn.negotiated_mechs:
@@ -365,7 +350,6 @@ async def _authenticate_default(credentials: MongoCredential, conn: AsyncConnect
365350

366351
_AUTH_MAP: Mapping[str, Callable[..., Coroutine[Any, Any, None]]] = {
367352
"GSSAPI": _authenticate_gssapi,
368-
"MONGODB-CR": _authenticate_mongo_cr,
369353
"MONGODB-X509": _authenticate_x509,
370354
"MONGODB-AWS": _authenticate_aws,
371355
"MONGODB-OIDC": _authenticate_oidc, # type:ignore[dict-item]

pymongo/auth_shared.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
MECHANISMS = frozenset(
3535
[
3636
"GSSAPI",
37-
"MONGODB-CR",
3837
"MONGODB-OIDC",
3938
"MONGODB-X509",
4039
"MONGODB-AWS",

pymongo/synchronous/auth.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -326,21 +326,6 @@ def _authenticate_x509(credentials: MongoCredential, conn: Connection) -> None:
326326
conn.command("$external", cmd)
327327

328328

329-
def _authenticate_mongo_cr(credentials: MongoCredential, conn: Connection) -> None:
330-
"""Authenticate using MONGODB-CR."""
331-
source = credentials.source
332-
username = credentials.username
333-
password = credentials.password
334-
# Get a nonce
335-
response = conn.command(source, {"getnonce": 1})
336-
nonce = response["nonce"]
337-
key = _auth_key(nonce, username, password)
338-
339-
# Actually authenticate
340-
query = {"authenticate": 1, "user": username, "nonce": nonce, "key": key}
341-
conn.command(source, query)
342-
343-
344329
def _authenticate_default(credentials: MongoCredential, conn: Connection) -> None:
345330
if conn.max_wire_version >= 7:
346331
if conn.negotiated_mechs:
@@ -360,7 +345,6 @@ def _authenticate_default(credentials: MongoCredential, conn: Connection) -> Non
360345

361346
_AUTH_MAP: Mapping[str, Callable[..., None]] = {
362347
"GSSAPI": _authenticate_gssapi,
363-
"MONGODB-CR": _authenticate_mongo_cr,
364348
"MONGODB-X509": _authenticate_x509,
365349
"MONGODB-AWS": _authenticate_aws,
366350
"MONGODB-OIDC": _authenticate_oidc, # type:ignore[dict-item]

test/auth/legacy/connection-string.json

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -127,47 +127,6 @@
127127
"uri": "mongodb://localhost/?authMechanism=GSSAPI",
128128
"valid": false
129129
},
130-
{
131-
"description": "should recognize the mechanism (MONGODB-CR)",
132-
"uri": "mongodb://user:password@localhost/?authMechanism=MONGODB-CR",
133-
"valid": true,
134-
"credential": {
135-
"username": "user",
136-
"password": "password",
137-
"source": "admin",
138-
"mechanism": "MONGODB-CR",
139-
"mechanism_properties": null
140-
}
141-
},
142-
{
143-
"description": "should use the database when no authSource is specified (MONGODB-CR)",
144-
"uri": "mongodb://user:password@localhost/foo?authMechanism=MONGODB-CR",
145-
"valid": true,
146-
"credential": {
147-
"username": "user",
148-
"password": "password",
149-
"source": "foo",
150-
"mechanism": "MONGODB-CR",
151-
"mechanism_properties": null
152-
}
153-
},
154-
{
155-
"description": "should use the authSource when specified (MONGODB-CR)",
156-
"uri": "mongodb://user:password@localhost/foo?authMechanism=MONGODB-CR&authSource=bar",
157-
"valid": true,
158-
"credential": {
159-
"username": "user",
160-
"password": "password",
161-
"source": "bar",
162-
"mechanism": "MONGODB-CR",
163-
"mechanism_properties": null
164-
}
165-
},
166-
{
167-
"description": "should throw an exception if no username is supplied (MONGODB-CR)",
168-
"uri": "mongodb://localhost/?authMechanism=MONGODB-CR",
169-
"valid": false
170-
},
171130
{
172131
"description": "should recognize the mechanism (MONGODB-X509)",
173132
"uri": "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality%2CST%3DmyState%2CC%3DmyCountry@localhost/?authMechanism=MONGODB-X509",

test/connection_string/test/valid-auth.json

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -220,29 +220,8 @@
220220
"options": null
221221
},
222222
{
223-
"description": "Escaped user info and database (MONGODB-CR)",
224-
"uri": "mongodb://%24am:f%3Azzb%40z%2Fz%[email protected]/admin%3F?authMechanism=MONGODB-CR",
225-
"valid": true,
226-
"warning": false,
227-
"hosts": [
228-
{
229-
"type": "ipv4",
230-
"host": "127.0.0.1",
231-
"port": null
232-
}
233-
],
234-
"auth": {
235-
"username": "$am",
236-
"password": "f:zzb@z/z=",
237-
"db": "admin?"
238-
},
239-
"options": {
240-
"authmechanism": "MONGODB-CR"
241-
}
242-
},
243-
{
244-
"description": "Subdelimiters in user/pass don't need escaping (MONGODB-CR)",
245-
"uri": "mongodb://!$&'()*+,;=:!$&'()*+,;[email protected]/admin?authMechanism=MONGODB-CR",
223+
"description": "Subdelimiters in user/pass don't need escaping (PLAIN)",
224+
"uri": "mongodb://!$&'()*+,;=:!$&'()*+,;[email protected]/admin?authMechanism=PLAIN",
246225
"valid": true,
247226
"warning": false,
248227
"hosts": [
@@ -258,7 +237,7 @@
258237
"db": "admin"
259238
},
260239
"options": {
261-
"authmechanism": "MONGODB-CR"
240+
"authmechanism": "PLAIN"
262241
}
263242
},
264243
{

test/connection_string/test/valid-options.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"tests": [
33
{
44
"description": "Option names are normalized to lowercase",
5-
"uri": "mongodb://alice:[email protected]/admin?AUTHMechanism=MONGODB-CR",
5+
"uri": "mongodb://alice:[email protected]/admin?AUTHMechanism=PLAIN",
66
"valid": true,
77
"warning": false,
88
"hosts": [
@@ -18,7 +18,7 @@
1818
"db": "admin"
1919
},
2020
"options": {
21-
"authmechanism": "MONGODB-CR"
21+
"authmechanism": "PLAIN"
2222
}
2323
},
2424
{

test/test_uri_parser.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,6 @@ def test_split_options(self):
142142
self.assertEqual({"fsync": True}, split_options("fsync=true"))
143143
self.assertEqual({"fsync": False}, split_options("fsync=false"))
144144
self.assertEqual({"authmechanism": "GSSAPI"}, split_options("authMechanism=GSSAPI"))
145-
self.assertEqual({"authmechanism": "MONGODB-CR"}, split_options("authMechanism=MONGODB-CR"))
146145
self.assertEqual(
147146
{"authmechanism": "SCRAM-SHA-1"}, split_options("authMechanism=SCRAM-SHA-1")
148147
)
@@ -295,30 +294,30 @@ def test_parse_uri(self):
295294

296295
# Various authentication tests
297296
res = copy.deepcopy(orig)
298-
res["options"] = {"authmechanism": "MONGODB-CR"}
297+
res["options"] = {"authmechanism": "SCRAM-SHA-256"}
299298
res["username"] = "user"
300299
res["password"] = "password"
301300
self.assertEqual(
302-
res, parse_uri("mongodb://user:password@localhost/?authMechanism=MONGODB-CR")
301+
res, parse_uri("mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-256")
303302
)
304303

305304
res = copy.deepcopy(orig)
306-
res["options"] = {"authmechanism": "MONGODB-CR", "authsource": "bar"}
305+
res["options"] = {"authmechanism": "SCRAM-SHA-256", "authsource": "bar"}
307306
res["username"] = "user"
308307
res["password"] = "password"
309308
res["database"] = "foo"
310309
self.assertEqual(
311310
res,
312311
parse_uri(
313-
"mongodb://user:password@localhost/foo?authSource=bar;authMechanism=MONGODB-CR"
312+
"mongodb://user:password@localhost/foo?authSource=bar;authMechanism=SCRAM-SHA-256"
314313
),
315314
)
316315

317316
res = copy.deepcopy(orig)
318-
res["options"] = {"authmechanism": "MONGODB-CR"}
317+
res["options"] = {"authmechanism": "SCRAM-SHA-256"}
319318
res["username"] = "user"
320319
res["password"] = ""
321-
self.assertEqual(res, parse_uri("mongodb://user:@localhost/?authMechanism=MONGODB-CR"))
320+
self.assertEqual(res, parse_uri("mongodb://user:@localhost/?authMechanism=SCRAM-SHA-256"))
322321

323322
res = copy.deepcopy(orig)
324323
res["username"] = "[email protected]"

0 commit comments

Comments
 (0)