PYTHON-4922 Remove Support for MONGODB-CR Authentication (#1978)
This commit is contained in:
parent
9a11b78fdf
commit
ad3292e39b
@ -12,6 +12,7 @@ PyMongo 4.11 brings a number of changes including:
|
||||
|
||||
- Dropped support for Python 3.8.
|
||||
- Dropped support for MongoDB 3.6.
|
||||
- Dropped support for the MONGODB-CR authenticate mechanism, which is no longer supported by MongoDB 4.0+.
|
||||
- Added support for free-threaded Python with the GIL disabled. For more information see:
|
||||
`Free-threaded CPython <https://docs.python.org/3.13/whatsnew/3.13.html#whatsnew313-free-threaded-cpython>`_.
|
||||
- :attr:`~pymongo.asynchronous.mongo_client.AsyncMongoClient.address` and
|
||||
|
||||
@ -76,24 +76,6 @@ For best performance on Python versions older than 2.7.8 install `backports.pbkd
|
||||
|
||||
.. _backports.pbkdf2: https://pypi.python.org/pypi/backports.pbkdf2/
|
||||
|
||||
MONGODB-CR
|
||||
----------
|
||||
|
||||
.. warning:: MONGODB-CR was deprecated with the release of MongoDB 3.6 and
|
||||
is no longer supported by MongoDB 4.0.
|
||||
|
||||
Before MongoDB 3.0 the default authentication mechanism was MONGODB-CR,
|
||||
the "MongoDB Challenge-Response" protocol::
|
||||
|
||||
>>> from pymongo import MongoClient
|
||||
>>> client = MongoClient('example.com',
|
||||
... username='user',
|
||||
... password='password',
|
||||
... authMechanism='MONGODB-CR')
|
||||
>>>
|
||||
>>> uri = "mongodb://user:password@example.com/?authSource=the_database&authMechanism=MONGODB-CR"
|
||||
>>> client = MongoClient(uri)
|
||||
|
||||
Default Authentication Mechanism
|
||||
--------------------------------
|
||||
|
||||
@ -221,8 +203,7 @@ SASL PLAIN (RFC 4616)
|
||||
|
||||
MongoDB Enterprise Edition version 2.6 and newer support the SASL PLAIN
|
||||
authentication mechanism, initially intended for delegating authentication
|
||||
to an LDAP server. Using the PLAIN mechanism is very similar to MONGODB-CR.
|
||||
These examples use the $external virtual database for LDAP support::
|
||||
to an LDAP server. These examples use the $external virtual database for LDAP support::
|
||||
|
||||
>>> from pymongo import MongoClient
|
||||
>>> uri = "mongodb://user:password@example.com/?authMechanism=PLAIN"
|
||||
|
||||
@ -329,21 +329,6 @@ async def _authenticate_x509(credentials: MongoCredential, conn: AsyncConnection
|
||||
await conn.command("$external", cmd)
|
||||
|
||||
|
||||
async def _authenticate_mongo_cr(credentials: MongoCredential, conn: AsyncConnection) -> None:
|
||||
"""Authenticate using MONGODB-CR."""
|
||||
source = credentials.source
|
||||
username = credentials.username
|
||||
password = credentials.password
|
||||
# Get a nonce
|
||||
response = await conn.command(source, {"getnonce": 1})
|
||||
nonce = response["nonce"]
|
||||
key = _auth_key(nonce, username, password)
|
||||
|
||||
# Actually authenticate
|
||||
query = {"authenticate": 1, "user": username, "nonce": nonce, "key": key}
|
||||
await conn.command(source, query)
|
||||
|
||||
|
||||
async def _authenticate_default(credentials: MongoCredential, conn: AsyncConnection) -> None:
|
||||
if conn.max_wire_version >= 7:
|
||||
if conn.negotiated_mechs:
|
||||
@ -365,7 +350,6 @@ async def _authenticate_default(credentials: MongoCredential, conn: AsyncConnect
|
||||
|
||||
_AUTH_MAP: Mapping[str, Callable[..., Coroutine[Any, Any, None]]] = {
|
||||
"GSSAPI": _authenticate_gssapi,
|
||||
"MONGODB-CR": _authenticate_mongo_cr,
|
||||
"MONGODB-X509": _authenticate_x509,
|
||||
"MONGODB-AWS": _authenticate_aws,
|
||||
"MONGODB-OIDC": _authenticate_oidc, # type:ignore[dict-item]
|
||||
|
||||
@ -34,7 +34,6 @@ from pymongo.errors import ConfigurationError
|
||||
MECHANISMS = frozenset(
|
||||
[
|
||||
"GSSAPI",
|
||||
"MONGODB-CR",
|
||||
"MONGODB-OIDC",
|
||||
"MONGODB-X509",
|
||||
"MONGODB-AWS",
|
||||
|
||||
@ -326,21 +326,6 @@ def _authenticate_x509(credentials: MongoCredential, conn: Connection) -> None:
|
||||
conn.command("$external", cmd)
|
||||
|
||||
|
||||
def _authenticate_mongo_cr(credentials: MongoCredential, conn: Connection) -> None:
|
||||
"""Authenticate using MONGODB-CR."""
|
||||
source = credentials.source
|
||||
username = credentials.username
|
||||
password = credentials.password
|
||||
# Get a nonce
|
||||
response = conn.command(source, {"getnonce": 1})
|
||||
nonce = response["nonce"]
|
||||
key = _auth_key(nonce, username, password)
|
||||
|
||||
# Actually authenticate
|
||||
query = {"authenticate": 1, "user": username, "nonce": nonce, "key": key}
|
||||
conn.command(source, query)
|
||||
|
||||
|
||||
def _authenticate_default(credentials: MongoCredential, conn: Connection) -> None:
|
||||
if conn.max_wire_version >= 7:
|
||||
if conn.negotiated_mechs:
|
||||
@ -360,7 +345,6 @@ def _authenticate_default(credentials: MongoCredential, conn: Connection) -> Non
|
||||
|
||||
_AUTH_MAP: Mapping[str, Callable[..., None]] = {
|
||||
"GSSAPI": _authenticate_gssapi,
|
||||
"MONGODB-CR": _authenticate_mongo_cr,
|
||||
"MONGODB-X509": _authenticate_x509,
|
||||
"MONGODB-AWS": _authenticate_aws,
|
||||
"MONGODB-OIDC": _authenticate_oidc, # type:ignore[dict-item]
|
||||
|
||||
@ -127,47 +127,6 @@
|
||||
"uri": "mongodb://localhost/?authMechanism=GSSAPI",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "should recognize the mechanism (MONGODB-CR)",
|
||||
"uri": "mongodb://user:password@localhost/?authMechanism=MONGODB-CR",
|
||||
"valid": true,
|
||||
"credential": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"source": "admin",
|
||||
"mechanism": "MONGODB-CR",
|
||||
"mechanism_properties": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should use the database when no authSource is specified (MONGODB-CR)",
|
||||
"uri": "mongodb://user:password@localhost/foo?authMechanism=MONGODB-CR",
|
||||
"valid": true,
|
||||
"credential": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"source": "foo",
|
||||
"mechanism": "MONGODB-CR",
|
||||
"mechanism_properties": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should use the authSource when specified (MONGODB-CR)",
|
||||
"uri": "mongodb://user:password@localhost/foo?authMechanism=MONGODB-CR&authSource=bar",
|
||||
"valid": true,
|
||||
"credential": {
|
||||
"username": "user",
|
||||
"password": "password",
|
||||
"source": "bar",
|
||||
"mechanism": "MONGODB-CR",
|
||||
"mechanism_properties": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "should throw an exception if no username is supplied (MONGODB-CR)",
|
||||
"uri": "mongodb://localhost/?authMechanism=MONGODB-CR",
|
||||
"valid": false
|
||||
},
|
||||
{
|
||||
"description": "should recognize the mechanism (MONGODB-X509)",
|
||||
"uri": "mongodb://CN%3DmyName%2COU%3DmyOrgUnit%2CO%3DmyOrg%2CL%3DmyLocality%2CST%3DmyState%2CC%3DmyCountry@localhost/?authMechanism=MONGODB-X509",
|
||||
|
||||
@ -220,29 +220,8 @@
|
||||
"options": null
|
||||
},
|
||||
{
|
||||
"description": "Escaped user info and database (MONGODB-CR)",
|
||||
"uri": "mongodb://%24am:f%3Azzb%40z%2Fz%3D@127.0.0.1/admin%3F?authMechanism=MONGODB-CR",
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"hosts": [
|
||||
{
|
||||
"type": "ipv4",
|
||||
"host": "127.0.0.1",
|
||||
"port": null
|
||||
}
|
||||
],
|
||||
"auth": {
|
||||
"username": "$am",
|
||||
"password": "f:zzb@z/z=",
|
||||
"db": "admin?"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "MONGODB-CR"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "Subdelimiters in user/pass don't need escaping (MONGODB-CR)",
|
||||
"uri": "mongodb://!$&'()*+,;=:!$&'()*+,;=@127.0.0.1/admin?authMechanism=MONGODB-CR",
|
||||
"description": "Subdelimiters in user/pass don't need escaping (PLAIN)",
|
||||
"uri": "mongodb://!$&'()*+,;=:!$&'()*+,;=@127.0.0.1/admin?authMechanism=PLAIN",
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"hosts": [
|
||||
@ -258,7 +237,7 @@
|
||||
"db": "admin"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "MONGODB-CR"
|
||||
"authmechanism": "PLAIN"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"tests": [
|
||||
{
|
||||
"description": "Option names are normalized to lowercase",
|
||||
"uri": "mongodb://alice:secret@example.com/admin?AUTHMechanism=MONGODB-CR",
|
||||
"uri": "mongodb://alice:secret@example.com/admin?AUTHMechanism=PLAIN",
|
||||
"valid": true,
|
||||
"warning": false,
|
||||
"hosts": [
|
||||
@ -18,7 +18,7 @@
|
||||
"db": "admin"
|
||||
},
|
||||
"options": {
|
||||
"authmechanism": "MONGODB-CR"
|
||||
"authmechanism": "PLAIN"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@ -142,7 +142,6 @@ class TestURI(unittest.TestCase):
|
||||
self.assertEqual({"fsync": True}, split_options("fsync=true"))
|
||||
self.assertEqual({"fsync": False}, split_options("fsync=false"))
|
||||
self.assertEqual({"authmechanism": "GSSAPI"}, split_options("authMechanism=GSSAPI"))
|
||||
self.assertEqual({"authmechanism": "MONGODB-CR"}, split_options("authMechanism=MONGODB-CR"))
|
||||
self.assertEqual(
|
||||
{"authmechanism": "SCRAM-SHA-1"}, split_options("authMechanism=SCRAM-SHA-1")
|
||||
)
|
||||
@ -295,30 +294,30 @@ class TestURI(unittest.TestCase):
|
||||
|
||||
# Various authentication tests
|
||||
res = copy.deepcopy(orig)
|
||||
res["options"] = {"authmechanism": "MONGODB-CR"}
|
||||
res["options"] = {"authmechanism": "SCRAM-SHA-256"}
|
||||
res["username"] = "user"
|
||||
res["password"] = "password"
|
||||
self.assertEqual(
|
||||
res, parse_uri("mongodb://user:password@localhost/?authMechanism=MONGODB-CR")
|
||||
res, parse_uri("mongodb://user:password@localhost/?authMechanism=SCRAM-SHA-256")
|
||||
)
|
||||
|
||||
res = copy.deepcopy(orig)
|
||||
res["options"] = {"authmechanism": "MONGODB-CR", "authsource": "bar"}
|
||||
res["options"] = {"authmechanism": "SCRAM-SHA-256", "authsource": "bar"}
|
||||
res["username"] = "user"
|
||||
res["password"] = "password"
|
||||
res["database"] = "foo"
|
||||
self.assertEqual(
|
||||
res,
|
||||
parse_uri(
|
||||
"mongodb://user:password@localhost/foo?authSource=bar;authMechanism=MONGODB-CR"
|
||||
"mongodb://user:password@localhost/foo?authSource=bar;authMechanism=SCRAM-SHA-256"
|
||||
),
|
||||
)
|
||||
|
||||
res = copy.deepcopy(orig)
|
||||
res["options"] = {"authmechanism": "MONGODB-CR"}
|
||||
res["options"] = {"authmechanism": "SCRAM-SHA-256"}
|
||||
res["username"] = "user"
|
||||
res["password"] = ""
|
||||
self.assertEqual(res, parse_uri("mongodb://user:@localhost/?authMechanism=MONGODB-CR"))
|
||||
self.assertEqual(res, parse_uri("mongodb://user:@localhost/?authMechanism=SCRAM-SHA-256"))
|
||||
|
||||
res = copy.deepcopy(orig)
|
||||
res["username"] = "user@domain.com"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user