diff --git a/source/includes/security/enterprise-authentication.java b/source/includes/security/enterprise-authentication.java new file mode 100644 index 00000000..57fabc38 --- /dev/null +++ b/source/includes/security/enterprise-authentication.java @@ -0,0 +1,132 @@ +// start-gssapi-connection-string +MongoClient mongoClient = MongoClients + .create("@:/?authSource=$external&authMechanism=GSSAPI"); +// end-gssapi-connection-string + +// start-gssapi-mongocredential +MongoCredential credential = MongoCredential.createGSSAPICredential(""); + +MongoClient mongoClient = MongoClients.create( + MongoClientSettings.builder() + .applyToClusterSettings(builder -> + builder.hosts(Arrays.asList(new ServerAddress("", )))) + .credential(credential) + .build()); +// end-gssapi-mongocredential + +// start-gssapi-connection-string-properties +MongoClient mongoClient = MongoClients + .create("@:/?authSource=$external&authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:myService"); +// end-gssapi-connection-string-properties + +// start-gssapi-service-key +MongoCredential credential = MongoCredential + .createGSSAPICredential(""); +credential = credential + .withMechanismProperty(MongoCredential.SERVICE_NAME_KEY, ""); +// end-gssapi-service-key + +// start-gssapi-subject-key +LoginContext loginContext = new LoginContext(); +loginContext.login(); +Subject subject = loginContext.getSubject(); + +MongoCredential credential = MongoCredential + .createGSSAPICredential(""); +credential = credential + .withMechanismProperty(MongoCredential.JAVA_SUBJECT_KEY, subject); +// end-gssapi-subject-key + +// start-gssapi-ticket-cache +/* All MongoClient instances sharing this instance of KerberosSubjectProvider +will share a Kerberos ticket cache */ +String myLoginContext = "myContext"; +MongoCredential credential = MongoCredential + .createGSSAPICredential(); + +/* Login context defaults to "com.sun.security.jgss.krb5.initiate" +if unspecified in KerberosSubjectProvider */ +credential = credential + .withMechanismProperty(MongoCredential.JAVA_SUBJECT_PROVIDER_KEY, + new KerberosSubjectProvider(myLoginContext)); +// end-gssapi-ticket-cache + +// start-ldap-connection-string +MongoClient mongoClient = MongoClients + .create(":@:/?authSource=$external&authMechanism=PLAIN"); +// end-ldap-connection-string + +// start-ldap-mongocredential +MongoCredential credential = MongoCredential + .createPlainCredential(, "$external", ); + +MongoClient mongoClient = MongoClients.create( + MongoClientSettings.builder() + .applyToClusterSettings(builder -> + builder.hosts(Arrays.asList(new ServerAddress("", )))) + .credential(credential) + .build()); +// end-ldap-mongocredential + +// start-azure-oidc-connection-string +MongoClient mongoClient = MongoClients.create( + "mongodb://@:/?" + + "?authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=ENVIRONMENT:azure,TOKEN_RESOURCE:"); +// end-azure-oidc-connection-string + +// start-azure-oidc-mongocredential +MongoCredential credential = MongoCredential.createOidcCredential("") +.withMechanismProperty("ENVIRONMENT", "azure") +.withMechanismProperty("TOKEN_RESOURCE", ""); + +MongoClient mongoClient = MongoClients.create( + MongoClientSettings.builder() + .applyToClusterSettings(builder -> + builder.hosts(Arrays.asList(new ServerAddress("", )))) + .credential(credential) + .build()); +// end-azure-oidc-mongocredential + +// start-gcp-oidc-connection-string +MongoClient mongoClient = MongoClients.create( + "mongodb://:/?" + + "authMechanism=MONGODB-OIDC" + + "&authMechanismProperties=ENVIRONMENT:gcp,TOKEN_RESOURCE:"); +// end-gcp-oidc-connection-string + +// start-gcp-oidc-mongocredential +MongoCredential credential = MongoCredential.createOidcCredential() + .withMechanismProperty("ENVIRONMENT", "gcp") + .withMechanismProperty("TOKEN_RESOURCE", ""); + +MongoClient mongoClient = MongoClients.create( + MongoClientSettings.builder() + .applyToClusterSettings(builder -> + builder.hosts(Arrays.asList(new ServerAddress("", )))) + .credential(credential) + .build()); +// end-gcp-oidc-mongocredential + +// start-oidc-callback-create +MongoCredential credential = MongoCredential.createOidcCredential(null) + .withMechanismProperty("OIDC_CALLBACK", (context) -> { + String accessToken = ... + return new OidcCallbackResult(accessToken); +}); +// end-oidc-callback-create + +// start-oidc-callback +MongoCredential credential = MongoCredential.createOidcCredential(null) + .withMechanismProperty("OIDC_CALLBACK", (context) -> { + string accessToken = new String(Files.readAllBytes(Paths.get("access-token.dat")); + return new OidcCallbackResult(accessToken); + }); + + MongoClient mongoClient = MongoClients.create( + MongoClientSettings.builder() + .applyToClusterSettings(builder -> + builder.hosts(Arrays.asList(new ServerAddress("", )))) + .credential(credential) + .build()); +// end-oidc-callback \ No newline at end of file diff --git a/source/secure-your-data.txt b/source/secure-your-data.txt index 6da2fb8e..69542779 100644 --- a/source/secure-your-data.txt +++ b/source/secure-your-data.txt @@ -23,6 +23,7 @@ Secure Your Data :maxdepth: 1 /security/auth + /security/enterprise-authentication /security/encrypt Overview diff --git a/source/security/auth.txt b/source/security/auth.txt index e19a9bda..7139700c 100644 --- a/source/security/auth.txt +++ b/source/security/auth.txt @@ -17,8 +17,10 @@ Authentication :depth: 2 :class: singlecol -The driver supports all MongoDB authentication mechanisms, -including those available only in the MongoDB Enterprise Edition. +In this guide, you can learn how to authenticate with MongoDB using the +authentication mechanisms available in the MongoDB Community Edition. +Authentication mechanisms are processes by which the driver and server confirm +the identity of a client to ensure security before connecting. MongoCredential --------------- @@ -228,112 +230,3 @@ Or, you can use a connection string that explicitly specifies See the :manual:`Use x.509 Certificates to Authenticate Clients ` tutorial in the Server manual to learn more about determining the subject name from the certificate. - -Kerberos (GSSAPI) ------------------ - -MongoDB Enterprise supports proxy authentication through the Kerberos -service. To create a credential of type Kerberos (GSSAPI), use the -``createGSSAPICredential()`` static factory method: - -.. code-block:: java - - String user; // The Kerberos user name, including the realm, e.g. "user1@MYREALM.ME" - // ... - MongoCredential credential = MongoCredential.createGSSAPICredential(user); - - MongoClient mongoClient = MongoClients.create( - MongoClientSettings.builder() - .applyToClusterSettings(builder -> - builder.hosts(Arrays.asList(new ServerAddress("host1", 27017)))) - .credential(credential) - .build()); - -Or, you can use a connection string that explicitly specifies -``authMechanism=GSSAPI``: - -.. code-block:: java - - MongoClient mongoClient = MongoClients.create("mongodb://username%40REALM.ME@host1/?authMechanism=GSSAPI"); - -.. note:: - - The method refers to the ``GSSAPI`` authentication mechanism instead of - ``Kerberos`` because the driver authenticates by using the ``GSSAPI`` SASL mechanism. - -To successfully authenticate by using Kerberos, the application typically -must specify several system properties so that the underlying GSSAPI -Java libraries can acquire a Kerberos ticket: - -.. code-block:: none - - java.security.krb5.realm=MYREALM.ME - java.security.krb5.kdc=mykdc.myrealm.me - -Depending on the Kerberos setup, additional property specifications -might be required, either within the application code or, in some cases, -by using the ``withMechanismProperty()`` method of the ``MongoCredential`` -instance: - -- ``SERVICE_NAME`` -- ``CANONICALIZE_HOST_NAME`` -- ``JAVA_SUBJECT`` -- ``JAVA_SASL_CLIENT_PROPERTIES`` - -The following code shows how to specify the ``SERVICE_NAME`` property within the -``MongoCredential`` object: - -.. code-block:: java - - credential = credential.withMechanismProperty(MongoCredential.SERVICE_NAME_KEY, "othername"); - -Or, you can specify the ``SERVICE_NAME`` property within the ``ConnectionString``: - -.. code-block:: java - - uri = "mongodb://username%40MYREALM.com@myserver/?authMechanism=GSSAPI&authMechanismProperties=SERVICE_NAME:othername" - -.. note:: - - On Windows, Oracles JRE uses `LSA - `__ - rather than `SSPI - `__ - in its implementation of GSSAPI, which limits interoperability with Windows - Active Directory and in particular the ability to implement single - sign-on. - -LDAP (PLAIN) ------------- - -MongoDB Enterprise supports proxy authentication through a -Lightweight Directory Access Protocol (LDAP) service. To create a -credential of type ``LDAP`` use the ``createPlainCredential()`` static -factory method: - -.. code-block:: java - - String user; // The LDAP user name - char[] password; // The LDAP password - // ... - MongoCredential credential = MongoCredential.createPlainCredential(user, "$external", password); - - MongoClient mongoClient = MongoClients.create( - MongoClientSettings.builder() - .applyToClusterSettings(builder -> - builder.hosts(Arrays.asList(new ServerAddress("host1", 27017)))) - .credential(credential) - .build()); - -Or, you can use a connection string that explicitly specifies -``authMechanism=PLAIN``: - -.. code-block:: java - - MongoClient mongoClient = MongoClients.create("mongodb://user1@host1/?authSource=$external&authMechanism=PLAIN"); - -.. note:: - - The method refers to the ``PLAIN`` authentication mechanism instead of - ``LDAP`` because the driver authenticates by using the ``PLAIN`` - SASL mechanism. diff --git a/source/security/enterprise-authentication.txt b/source/security/enterprise-authentication.txt new file mode 100644 index 00000000..76933b2d --- /dev/null +++ b/source/security/enterprise-authentication.txt @@ -0,0 +1,417 @@ +.. _java-rs-enterprise-authentication-mechanisms: + +==================================== +Enterprise Authentication Mechanisms +==================================== + +.. contents:: On this page + :local: + :backlinks: none + :depth: 2 + :class: singlecol + +.. facet:: + :name: genre + :values: reference + +.. meta:: + :keywords: ldap, encryption, principal, tls, oidc + +Overview +-------- + +MongoDB Enterprise Edition includes authentication mechanisms that aren't +available in MongoDB Community Edition. In this guide, you can learn how to +authenticate to MongoDB by using these authentication mechanisms. To learn about +the other authentication mechanisms available in MongoDB, see the +:ref:`Authentication Mechanisms ` guide. + +Specify an Authentication Mechanism +----------------------------------- + +You can specify your authentication mechanism and credentials when connecting +to MongoDB by using either of the following: + +- Connection string +- ``MongoCredential`` factory method + +A **connection string** (also known as a **connection URI**) specifies how to +connect and authenticate to your MongoDB cluster. + +To authenticate by using a connection string, include your settings in your +connection string, then pass it to the ``MongoClients.create()`` method to +instantiate your ``MongoClient``. Select the :guilabel:`Connection String` +tab in the following sections to see the syntax for authenticating by using a connection string. + +You can also use the ``MongoCredential`` class to specify your +authentication details. The ``MongoCredential`` class contains static factory +methods that construct instances containing your authentication mechanism and +credentials. When you use the ``MongoCredential`` helper class, +use the ``MongoClientSettings.Builder`` class to configure your +connection settings. Select the +:guilabel:`MongoCredential` tab in the following sections to see the syntax for +authenticating using a ``MongoCredential``. + +Mechanisms +---------- + +.. _java-rs-gssapi-auth-mechanism: + +Kerberos (GSSAPI) +~~~~~~~~~~~~~~~~~~~~~~ + +The Generic Security Services API (GSSAPI) authentication mechanism +allows you to authenticate to a Kerberos service by using your +principal name. + +The following sections contain code examples that use the following placeholders: + +- ``username``: your URL-encoded principal name, such as ``"username%40REALM.ME"`` +- ``hostname``: network address of your MongoDB deployment that your + client can access +- ``port``: port number of your MongoDB deployment + +Select the :guilabel:`Connection String` or :guilabel:`MongoCredential` tabs to +see the corresponding syntax. + +.. tabs:: + + .. tab:: + :tabid: Connection String + + The following example authenticates to GSSAPI by using a connection string: + + .. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-gssapi-connection-string + :end-before: // end-gssapi-connection-string + :language: java + + .. tab:: + :tabid: MongoCredential + + To specify the GSSAPI authentication mechanism by using the + ``MongoCredential`` class, call the ``createGSSAPICredential()`` + method, as shown in the following example: + + .. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-gssapi-mongocredential + :end-before: // end-gssapi-mongocredential + :language: java + +To acquire a +`Kerberos ticket `__, +the GSSAPI Java libraries require you to specify the realm and Key Distribution +Center (KDC) system properties. You can set these settings as shown in the +following example: + +.. code-block:: none + + java.security.krb5.realm=MYREALM.ME + java.security.krb5.kdc=mykdc.myrealm.me + +You might need to specify one or more of the following additional +``MongoCredential`` mechanism properties, depending on your Kerberos setup: + +- ``SERVICE_NAME`` +- ``CANONICALIZE_HOST_NAME`` +- ``JAVA_SUBJECT`` +- ``JAVA_SASL_CLIENT_PROPERTIES`` +- ``JAVA_SUBJECT_PROVIDER`` + +.. tabs:: + :hidden: + + .. tab:: + :tabid: Connection String + + .. important:: + + You can specify the following GSSAPI properties only through the + ``MongoCredential`` class: + + - ``JAVA_SUBJECT`` + - ``JAVA_SASL_CLIENT_PROPERTIES`` + - ``JAVA_SUBJECT_PROVIDER`` + + Select the :guilabel:`MongoCredential` tab to learn how to specify these properties. + + To specify the GSSAPI additional properties, include the property in the + connection string as a URL parameter in the format: + ``:``. + + The following example authenticates to GSSAPI and specifies additional properties: + + .. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-gssapi-connection-string-properties + :end-before: // end-gssapi-connection-string-properties + :language: java + + .. tab:: + :tabid: MongoCredential + + To specify the GSSAPI additional properties, call the + ``withMechanismProperty()`` method on your ``MongoCredential`` + instance, and pass the property name and value as parameters. Use the + property name constants defined in the ``MongoCredential`` class: + + - `SERVICE_NAME_KEY <{+api+}/apidocs/mongodb-driver-core/com/mongodb/MongoCredential.html#SERVICE_NAME_KEY>`__ + - `CANONICALIZE_HOST_NAME_KEY <{+api+}/apidocs/mongodb-driver-core/com/mongodb/MongoCredential.html#CANONICALIZE_HOST_NAME_KEY>`__ + - `JAVA_SUBJECT_KEY <{+api+}/apidocs/mongodb-driver-core/com/mongodb/MongoCredential.html#JAVA_SUBJECT_KEY>`__ + - `JAVA_SASL_CLIENT_PROPERTIES_KEY <{+api+}/apidocs/mongodb-driver-core/com/mongodb/MongoCredential.html#JAVA_SASL_CLIENT_PROPERTIES_KEY>`__ + - `JAVA_SUBJECT_PROVIDER_KEY <{+api+}/apidocs/mongodb-driver-core/com/mongodb/MongoCredential.html#JAVA_SUBJECT_PROVIDER_KEY>`__ + + Select the :guilabel:`SERVICE_NAME_KEY` or :guilabel:`JAVA_SUBJECT_KEY` tab to + see how to specify the corresponding property: + + .. tabs:: + + .. tab:: + :tabid: SERVICE_NAME_KEY + + .. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-gssapi-service-key + :end-before: // end-gssapi-service-key + :language: java + + .. tab:: + :tabid: JAVA_SUBJECT_KEY + + .. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-gssapi-subject-key + :end-before: // end-gssapi-subject-key + :language: java + +By default, the {+driver-short+} caches Kerberos tickets by ``MongoClient`` instance. +If your deployment frequently creates and destroys ``MongoClient`` instances, +you can change the default Kerberos ticket caching behavior to cache by process +to improve performance. + +.. tabs:: + :hidden: + + .. tab:: + :tabid: Connection String + + To cache Kerberos tickets by process, you must use the ``MongoCredential`` authentication + mechanism, because the connection string authentication mechanism does not support the ``JAVA_SUBJECT_PROVIDER`` + mechanism property. Select the :guilabel:`MongoCredential` + tab to learn how to cache Kerberos tickets by process. + + .. tab:: + :tabid: MongoCredential + + To cache Kerberos tickets by process, specify the ``JAVA_SUBJECT_PROVIDER`` + mechanism property and provide a + `KerberosSubjectProvider `__ + in your ``MongoCredential`` instance, as shown in the following example: + + .. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-gssapi-ticket-cache + :end-before: // end-gssapi-ticket-cache + :language: java + +.. note:: + + On Windows, Oracle's JRE uses `LSA `__ + rather than `SSPI `__ + in its implementation of GSSAPI, which limits interoperability with + Windows Active Directory and implementations of single sign-on. See the + following resources for more information: + + - `JDK-8054026 `__ + - `JDK-6722928 `__ + - `SO 23427343 `__ + +.. _java-rs-plain-auth-mechanism: + +LDAP (PLAIN) +~~~~~~~~~~~~ + +You can authenticate to a Lightweight Directory Access Protocol (LDAP) +server by using your directory server username and password. + +.. tip:: + + The authentication mechanism is named ``PLAIN`` instead of ``LDAP`` since it + authenticates using the `PLAIN Simple Authentication and Security Layer + (SASL) defined in RFC-4616 `_. + +The following sections contain code examples that use the following placeholders: + +- ``ldap_username``: your LDAP username +- ``ldap_password``: your LDAP user's password +- ``hostname``: network address of your MongoDB deployment that your + client can access +- ``port``: port number of your MongoDB deployment + +Select the :guilabel:`Connection String` or :guilabel:`MongoCredential` tabs to +see the corresponding syntax. + +.. tabs:: + + .. tab:: + :tabid: Connection String + + .. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-ldap-connection-string + :end-before: // end-ldap-connection-string + :language: java + + .. tab:: + :tabid: MongoCredential + + To specify the LDAP (PLAIN) authentication mechanism by using the + ``MongoCredential`` class, call the ``createPlainCredential()`` + method, as shown in the following example: + + .. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-ldap-mongocredential + :end-before: // end-ldap-mongocredential + :language: java + +.. _java-rs-mongodb-oidc: + +MONGODB-OIDC +~~~~~~~~~~~~ + +.. important:: + + The MONGODB-OIDC authentication mechanism requires {+mdb-server+} v7.0 or later running + on a Linux platform. + +The following sections describe how to use the MONGODB-OIDC authentication mechanism to +authenticate to various platforms. + +For more information about the MONGODB-OIDC authentication mechanism, see +:manual:`OpenID Connect Authentication ` and +:manual:`MongoDB Server Parameters ` +in the MongoDB Server manual. + +.. _java-rs-mongodb-oidc-azure-imds: + +Azure IMDS +++++++++++ + +If your application runs on an Azure VM, or otherwise uses the +`Azure Instance Metadata Service `__ +(IMDS), you can authenticate to MongoDB by using the {+driver-short+}'s built-in Azure +support. + +You can specify Azure IMDS OIDC authentication either by +using a ``MongoCredential`` or as part of the connection string. + +Select the :guilabel:`Connection String` or :guilabel:`MongoCredential` tabs to +see the corresponding syntax. + +.. tabs:: + + .. tab:: Connection String + :tabid: mongodb-azure-imds-connection-string + + Replace the ```` placeholder with the client ID or application ID of the + Azure managed identity or enterprise application. Replace the ```` + placeholder in the following code with the percent-encoded value of the audience server + parameter configured on your MongoDB deployment. + + The comma (``,``) character and its encoding (``%2C``) are + reserved, and using these characters in a value causes the + driver to interpret commas as delimiters of key-value pairs. + You must specify values that contain commas in a ``MongoCredential`` instance, as + demonstrated in the :guilabel:`MongoCredential` tab. + + .. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-azure-oidc-connection-string + :end-before: // end-azure-oidc-connection-string + :language: java + + .. tab:: MongoCredential + :tabid: mongodb-azure-mongo-credential + + Replace the ```` placeholder with the client ID or application ID of the + Azure managed identity or enterprise application. Replace the ```` + placeholder with the value of the + ``audience`` server parameter configured on your MongoDB deployment. + + .. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-azure-oidc-mongocredential + :end-before: // end-azure-oidc-mongocredential + :language: java + +.. _java-rs-mongodb-oidc-gcp-imds: + +GCP IMDS +++++++++ + +If your application runs on a Google Compute Engine VM, or otherwise uses the +`GCP Instance Metadata Service `__, +you can authenticate to MongoDB by using the {+driver-short+}'s built-in GCP +support. + +You can specify GCP IMDS OIDC authentication either by +using a ``MongoCredential`` or as part of the connection string. + +The following sections contain code examples that use the following +placeholders: + +- ``hostname``: network address of your MongoDB deployment that your client can access +- ``port``: port number of your MongoDB deployment + +Select the :guilabel:`Connection String` or :guilabel:`MongoCredential` tabs to +see the corresponding syntax. + +.. tabs:: + + .. tab:: Connection String + :tabid: mongodb-gcp-imds-connection-string + + Replace the ```` placeholder in the + following code with the percent-encoded value of the audience server + parameter configured on your MongoDB deployment. + + The comma (``,``) character and its encoding (``%2C``) are + reserved, and using these characters in a value causes the + driver to interpret commas as delimiters of key-value pairs. + You must specify values that contain commas in a ``MongoCredential`` instance, as + demonstrated in the :guilabel:`MongoCredential` tab. + + .. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-gcp-oidc-connection-string + :end-before: // end-gcp-oidc-connection-string + :language: java + + .. tab:: MongoCredential + :tabid: mongodb-gcp-mongo-credential + + Replace the ```` placeholder with the value of the + ``audience`` server parameter configured on your MongoDB deployment. + + .. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-gcp-oidc-mongocredential + :end-before: // end-gcp-oidc-mongocredential + :language: java + +Custom Callback ++++++++++++++++ + +The {+driver-short+} doesn't offer built-in support for all platforms, including +Azure Functions and Azure Kubernetes Service (AKS). Instead, you +must define a custom callback to use OIDC to authenticate from these platforms. +To do so, use the ``"OIDC_CALLBACK"`` authentication property, as shown in the following +code example: + +.. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-oidc-callback-create + :end-before: // end-oidc-callback-create + :language: java + +The value of the ``"OIDC_CALLBACK"`` property must be a lambda or other implementation +of the ``OidcCallback`` functional interface that accepts an ``OidcCallbackContext`` +as a parameter and returns an ``OidcCallbackResult``. + +The following example uses an example callback to retrieve an OIDC token from a file +named ``"access-token.dat"`` in the local file system: + +.. literalinclude:: /includes/security/enterprise-authentication.java + :start-after: // start-oidc-callback + :end-before: // end-oidc-callback + :language: java