# Integrate with MongoDB

EMQX supports integrating with MongoDB for password authentication. EMQX MongoDB authenticator currently supports connecting to MongoDB running in three different modes, which are Single, [Replica Set](https://www.mongodb.com/docs/manual/reference/replica-configuration/) and [Sharding](https://www.mongodb.com/docs/manual/sharding/). This page gives detailed instructions on the data schema supported and on how to configure with EMQX Dashboard and configuration file. 

::: tip

Knowledge about [basic EMQX authentication concepts](../authn/authn.md)

:::

## Data Schema and Query Statement

EMQX MongoDB authenticator supports storing authentication data as MongoDB documents. Users need to provide a query statement template and ensure the following fields are included:

- `password_hash`: required; password (in plain text or hashed) stored in the database; this field supports renaming;
- `salt`: optional; `salt = ""` or just remove this field to indicate no salt value will be added; this field supports renaming;
- `is_superuser`: optional; flag if the current client is a superuser; default: `false`; this field supports renaming.

For example, if we want to add a document for a superuser (`is_superuser`: `true`) with username `user123`, password `secret`, suffixed salt `salt_foo123`, and password hash `sha256`, the query statement should be:

```
> db.mqtt_user.insertOne(
  {
      "username": "emqx_u",
      "salt": "slat_foo123",
      "is_superuser": true,
      "password_hash": "44edc2d57cde8d79c98145003e105b90a14f1460b79186ea9cfe83942fc5abb5"
  }
);
{
  "acknowledged" : true,
  "insertedId" : ObjectId("631989e20a33e26b05b15abe")
}
```

:::tip 

When there is a significant number of users in the system, please optimize and index the tables to be queried beforehand to shorten the query response time and reduce the load for EMQX.

 :::

For this MongoDB data schema, the corresponding Dashboard configuration parameters are: 

- **Password Hash**: `sha256`
- **Salt Position**: `suffix`
- **Collection**: `mqtt_user`
- **Filter**: `{ username = "${username}" }`
- **Password Hash field**: `password_hash`
- **Salt Field**: `salt`
- **is_superuser Field**： `is_superuser`

## Configure with Dashboard

You can use EMQX Dashboard to configure how to use MongoDB for password authentication. 

1. In the EMQX Dashboard, click **Access Control** -> **Authentication** from the left navigation menu.
2. On the **Authentication** page, click **Create** in the top right corner.
3. Click to select **Password-Based** as **Mechanism**, and **MongoDB** as **Backend** to go to the **Configuration** tab, as shown below. 

![authn-MongoDB_ee](./assets/authn-MongoDB_ee.png)

4. Follow the instructions below to configure the authentication backend:

   - Enter the information for connecting to MongoDB:
     - **MongoDB Mode**: Select how MongoDB is deployed, including `Single`, `Replica Set` and `Sharding`. 
     - **Server**: Specify the MongoDB server address that EMQX is to connect, if **MongoDB Mode** is set to `Replica Set` or `Sharding`, you will need to input all MondoDB servers (separated with a `,`) that EMQX is to connect.
     - **Replica Set Name**: Specify the Replica Set name to use; type: strings; only needed if you set **MongoDB Mode** to `Replica Set`.
     - **Database**: MongoDB database name; Data type: strings.
     - **Collection**: Name of MongoDB collection where authentication rules are stored; Data type: strings.
     - **Username**: Specify MongoDB user name. 
     - **Password**: Specify MongoDB user password. 
     - **Read Mode** (optional): Only needed if you set **MongoDB Mode** to `Replica Set`; Default: `master`; Options: `master`, `slave_ok`. 
       - **master**: Indicate each query in a sequence must only read fresh data (from a master/primary server). If the connected server is not a master, the first read will fail, and subsequent operations will be aborted.
       - **slave_ok**: Allows queries to read stale data from a secondary/slave server or fresh data from a master.
     - **Write Mode** (optional): Only needed if you set **MongoDB Mode** to `Replica Set`; Options: `unsafe`, `safe`; Default: `safe`.

   - Configure settings related to authentication:
     - **Password Hash Field**: Specify the field name of the password.
     - **Password Hash**: Select the password hashing algorithm applied to plain-text passwords before results are stored in the database. Available options are `plain`, `md5`, `sha`, `sha256`, `sha512`, `bcrypt`, and `pbkdf2`. Additional configurations depend on the selected algorithm:
       - For `md5`, `sha`, `sha256` or `sha512`:
         - **Salt Position**: Determines how salt (random data) is mixed with the password. Options are `suffix`, `prefix`, or `disable`. You can keep the default value unless you migrate user credentials from external storage into the EMQX built-in database.
         - Resulting hash is represented as a string of hexadecimal characters, and compared case-insensitively with the stored credential.
       - For `plain`:
         - **Salt Position**: should be `disable`.
       - For `bcrypt`:
         - **Salt Rounds**: Defines the number of times the hash function is applied, expressed as _2<sup>Salt Rounds</sup>_, also known as the "cost factor". The default value is `10`, with a permissible range of `5` to `10`. A higher value is recommended for enhanced security. Note: Increasing the cost factor by 1 doubles the necessary time for authentication.
       - For `pbkdf2`:
         - **Pseudorandom Function**: Selects the hash function that generates the key, such as `sha256`.
         - **Iteration Count**: Sets the number of times the hash function is executed. The default is `4096`.
         - **Derived Key Length** (optional): Specifies the length in bytes of the generated key. If left blank, the length will default to that determined by the selected pseudorandom function.
         - Resulting hash is represented as a string of hexadecimal characters, and compared case-insensitively with the stored credential. 
   - **Salt Field**: Specify the salt field in MongoDB.
   - **is_superuser Field**: Determine if the user is a super user. 
   - **Client ID Override Field**: Specifies the name of the field in the MongoDB authentication result that can be used to override the client-provided Client ID during connection. This allows assigning unique Client IDs based on authentication data, helping prevent session conflicts in scenarios such as multi-tenancy.
   - **Precondition**: A [Variform expression](../../configuration/configuration.md#variform-expressions) used to control whether this MongoDB authenticator should be applied to a client connection. The expression is evaluated against attributes from the client (such as `username`, `clientid`, `listener`, etc.). The authenticator will only be invoked if the expression evaluates to the string `"true"`. Otherwise, it will be skipped. For more information about the precondition, see [Authenticator Preconditions](./authn.md#authenticator-preconditions).
   - **Enable TLS**: Turn on the toggle switch if you want to enable TLS. For more information on enabling TLS, see [Network and TLS](../../network/overview.md).
   - **Filter**: A map interpreted as MongoDB selector for credential lookup. [Placeholders](./authn.md#authentication-placeholders) are supported.
   - **Advanced Settings**: Set the concurrent connections and waiting time before a connection is timed out.
     - **Connection Pool size** (optional): Specify the number of concurrent connections from an EMQX node to a MongoDB server. Default: `8`. 
     - **Connect Timeout** (optional): Define the duration to wait before considering a connection as timed out. Supported units: milliseconds, seconds, minutes, hours. Default: `20` second.

5. After you finish the settings, click **Create**.

## Configure with Configuration Items

You can configure the EMQX MongoDB authenticator with EMQX configuration items. <!--for detailed operating steps, see [authn-mongodb:standalone](../../configuration/configuration-manual.html#authn-mongodb:standalone), [authn-mongodb:sharded-cluster](../../configuration/configuration-manual.html#authn-mongodb:sharded-cluster) and [authn-mongodb:replica-set](../../configuration/configuration-manual.html#authn-mongodb:replica-set).-->

Below are code examples you may refer to:

:::: tabs type:card

::: tab Single mode

```bash
{
  mechanism = password_based
  backend = mongodb

  password_hash_algorithm {
    name = sha256
    salt_position = suffix
  }

  collection = "mqtt_user"
  filter { username = "${username}" }

  mongo_type = single
  server = "127.0.0.1:27017"

  database = "mqtt"
  username = "emqx"
  password = "secret"
}
```

:::

::: tab Replica set

```bash
{
  mechanism = password_based
  backend = mongodb

  password_hash_algorithm {
    name = sha256
    salt_position = suffix
  }

  collection = "mqtt_user"
  filter { username = "${username}" }

  mongo_type = rs
  servers = "10.123.12.10:27017,10.123.12.11:27017,10.123.12.12:27017"
  replica_set_name = "rs0"

  database = "mqtt"
  username = "emqx"
  password = "secret"
}
```

:::

::: tab Sharding

```bash
{
  mechanism = password_based
  backend = mongodb
  enable = true

  password_hash_algorithm {
    name = sha256
    salt_position = suffix
  }

  collection = "mqtt_user"
  filter { username = "${username}" }

  mongo_type = sharded
  servers = "10.123.12.10:27017,10.123.12.11:27017,10.123.12.12:27017"

  database = "mqtt"
  username = "emqx"
  password = "secret"
}
```

:::

::::
