Repository: MongoEngine/mongoengine

Issue:
Support MONGODB-AWS authentication mechanism
As of 3.11 (and MongoDB 4.4+), `pymongo` supports AWS IAM user/role based authentication:
https://pymongo.readthedocs.io/en/stable/examples/authentication.html#mongodb-aws

Support for this would be great to have in `mongoengine` as well.

This requires two things: setting the auth mechanism to `MONGODB-AWS` and passing `authmechanismproperties` into the `authenticate` method with the session token. The former is already possible, but support for `authmechanismproperties` is missing.

It would need to be populated in the connection settings and propagated to `auth_kwargs` in the code below.

https://github.com/MongoEngine/mongoengine/blob/96802599045432274481b4ed9fcc4fad4ce5f89b/mongoengine/connection.py#L355-L365

I can put together a PR for this to start a discussion about code, but I wanted to check first that you are open to supporting this?


Discussion:
HI @davidsteiner, sure, please open a PR that would be a good addition
This issue is a bit stale now, but we have had a requirement to use AWS authentication and I ended up following the suggestions on this card and it's now working. Would you be interested in me opening a PR for this?
Yep please do so 👍

Resolving patch:
diff --git a/mongoengine/connection.py b/mongoengine/connection.py
--- a/mongoengine/connection.py
+++ b/mongoengine/connection.py
@@ -58,6 +58,7 @@ def _get_connection_settings(
     password=None,
     authentication_source=None,
     authentication_mechanism=None,
+    authmechanismproperties=None,
     **kwargs,
 ):
     """Get the connection settings as a dict
@@ -88,6 +89,7 @@ def _get_connection_settings(
         "password": password,
         "authentication_source": authentication_source,
         "authentication_mechanism": authentication_mechanism,
+        "authmechanismproperties": authmechanismproperties
     }
 
     _check_db_name(conn_settings["name"])
@@ -158,6 +160,8 @@ def _get_connection_settings(
                     ):
                         conn_settings["read_preference"] = preference
                         break
+            if "authmechanismproperties" in uri_options:
+                conn_settings["authmechanismproperties"] = uri_options["authmechanismproperties"]
         else:
             resolved_hosts.append(entity)
     conn_settings["host"] = resolved_hosts
@@ -193,6 +197,7 @@ def register_connection(
     password=None,
     authentication_source=None,
     authentication_mechanism=None,
+    authmechanismproperties=None,
     **kwargs,
 ):
     """Register the connection settings.
@@ -225,6 +230,7 @@ def register_connection(
         password=password,
         authentication_source=authentication_source,
         authentication_mechanism=authentication_mechanism,
+        authmechanismproperties=authmechanismproperties,
         **kwargs,
     )
     _connection_settings[alias] = conn_settings
@@ -286,6 +292,7 @@ def _clean_settings(settings_dict):
                 "password",
                 "authentication_source",
                 "authentication_mechanism",
+                "authmechanismproperties"
             }
             rename_fields = {}
         else:
@@ -385,6 +392,7 @@ def get_db(alias=DEFAULT_CONNECTION_NAME, reconnect=False):
                 conn_settings["password"]
                 or conn_settings["authentication_mechanism"] == "MONGODB-X509"
             )
+            and ("authmechanismproperties" not in conn_settings.keys())
         ):
             auth_kwargs = {"source": conn_settings["authentication_source"]}
             if conn_settings["authentication_mechanism"] is not None:


Test patch: