diff --git a/en_US/admin/api.md b/en_US/admin/api.md
index 01f9dc029b..6a7745af40 100644
--- a/en_US/admin/api.md
+++ b/en_US/admin/api.md
@@ -1,14 +1,14 @@
# REST API
-EMQX exposes an HTTP management API designed following OpenAPI (Swagger) 3.0 specification.
+EMQX exposes an HTTP management API designed following the OpenAPI (Swagger) 3.0 specification.
After EMQX is started, you can visit [http://localhost:18083/api-docs/index.html](http://localhost:18083/api-docs/index.html) to view the API document and execute the management APIs from the Swagger UI. By default, under the Dashboard configuration, `swagger_support` is set to `true`, indicating Swagger UI support is enabled, which means all Swagger-related features are turned on, such as generating interactive API documentation. You can also set it to `false` to disable this feature. For more information, see [Dashboard configuration](../configuration/dashboard.md).
-The section introduces how to work with EMQX REST API.
+The section introduces how to work with the EMQX REST API.
## Basic Path
-EMQX has version control on the REST API, all API paths from EMQX 5.0.0 start with `/api/v5`.
+EMQX has version control on the REST API; all API paths from EMQX 5.0.0 start with `/api/v5`.
## HTTP Headers
@@ -46,7 +46,31 @@ For security reasons, starting from EMQX 5.0.0, you cannot use Dashboard user cr
#### Create API Keys
-You can manually create API keys for authentication on the Dashboard by navigating to **System** -> **API Key**. For instructions, see [System - API Keys](../dashboard/system.md#api-keys).
+##### Dashboard
+
+You can manually create API keys on the Dashboard by navigating to **System** -> **API Key**:
+
+1. Click the **+ Create** button in the top right corner to open the Create dialog.
+2. Configure the API key details:
+ - **Name** (required): Enter a name for the API key.
+ - **Expire At**: Leave empty for the key to never expire.
+ - **Is Enable**: Defaults to enabled.
+ - **Role**: Select a role (optional). See [Roles and Permissions](#roles-and-permissions).
+ - **Scopes**: Select the scopes to grant (optional). Defaults to all scope permissions. See [API Scopes](#api-scopes).
+ - **Note**: Optionally enter a description for the key.
+3. Click **Confirm**. The API key and secret key are displayed in the **Created Successfully** dialog.
+
+ ::: warning Important Notice
+
+ Save the API key and secret key immediately. The secret key will not be shown again.
+
+ :::
+
+4. Click **Close** to dismiss the dialog.
+
+You can view key details by clicking its name, edit its expiration, status, or note via the **Edit** button, or remove it with the **Delete** button.
+
+##### Bootstrap File
You can also create API keys using the bootstrap file method. Add the following configuration file to specify the file location:
@@ -56,11 +80,12 @@ api_key = {
}
```
-In the specified file, add multiple API keys in the format `{API Key}:{Secret Key}:{?Role}`, separated by new lines:
+In the specified file, add multiple API keys in the format `{API Key}:{Secret Key}:{?Role}:{?Scopes}`, separated by new lines:
- **API Key**: Any string as the key identifier.
- **Secret Key**: Use a random string as the secret key.
- **Role (optional)**: Specify the key's [role](#roles-and-permissions).
+- **Scopes (optional)**: Specify the [API Scopes](#api-scopes) the key is allowed to access, as a comma-separated list. When omitted, the key receives all user-visible scopes by default (administrative all-allow, for backward compatibility with earlier releases).
For example:
@@ -68,11 +93,13 @@ For example:
my-app:AAA4A275-BEEC-4AF8-B70B-DAAC0341F8EB
ec3907f865805db0:Ee3taYltUKtoBVD9C3XjQl9C6NXheip8Z9B69BpUv5JxVHL:viewer
foo:3CA92E5F-30AB-41F5-B3E6-8D7E213BE97E:publisher
+integration-svc:6f1a9f2d09c84e6b:viewer:monitoring,cluster_operations
+rules-mgr:2b8e4a1c9d7e4f3b:administrator:data_integration,access_control
```
API keys created this way are valid indefinitely.
-Each time EMQX starts, it will add the data set in the file to the API key list. If an API key already exists, its Secret Key and Role will be updated.
+Each time EMQX starts, it will add the data set in the file to the API key list. If an API key already exists, its Secret Key, Role, and Scopes will be updated.
#### Roles and Permissions
@@ -82,6 +109,80 @@ The REST API implements role-based access control. When creating an API key, you
- **Viewer**: This role can only view resources and data, corresponding to all GET requests in the REST API. The corresponding role identifier is `viewer`.
- **Publisher**: Designed specifically for MQTT message publishing, this role is limited to accessing APIs related to message publishing. The corresponding role identifier is `publisher`.
+#### API Scopes
+
+Scopes are a per-key permission dimension introduced in EMQX 5.10 that declare which business areas of the REST API a key is allowed to reach. Scopes and [Roles and Permissions](#roles-and-permissions) are independent of each other and enforced together, forming two separate layers of access control:
+
+| Dimension | Purpose | Granularity |
+| --------- | ------- | ----------- |
+| **Role** | Limits HTTP verbs (read-only vs. writes, publish-only, etc.) | Request action |
+| **Scope** | Limits the API domain (clients, rules, monitoring, ...) | Resource area |
+
+Every request is checked against both dimensions: the role check and the scope check. A request is accepted only when both checks pass.
+
+##### Why Scopes
+
+In microservice and integration scenarios, external systems typically need access to only a subset of EMQX's management surface:
+
+- A monitoring platform only needs the `monitoring` scope (`/metrics`, `/stats`, `/prometheus`, ...);
+- A rules-publishing service only needs `data_integration` (`/rules`, `/connectors`, `/actions`, ...);
+- A cluster operator tool only needs `cluster_operations` (`/cluster`, `/nodes`, `/load_rebalance`, ...).
+
+With only `administrator` / `viewer` / `publisher` available, granularity is coarse: the only way to grant a service write access to rules is to hand it to an `administrator`, which effectively gives it full control over the whole system.
+
+Scopes let you assign keys using the principle of least privilege: grant only the scopes required for the task, and minimize the blast radius if a key is ever leaked.
+
+##### Built-in Scopes
+
+EMQX 5.10 ships with 10 scopes that you can combine freely when creating a key:
+
+| Scope | Name | Typical API areas |
+| --- | --- | --- |
+| `connections` | Connection management | `/clients`, `/subscriptions`, `/topics`, `/banned`, `/retainer`, `/file_transfer`, `/mqtt/delayed`, `/mqtt/topic_rewrite`, ... |
+| `publish` | Message publishing | `/publish`, `/publish/bulk` |
+| `data_integration` | Data integration | `/rules`, `/connectors`, `/actions`, `/schema_registry`, `/schema_validations`, `/message_transformations`, `/exhooks`, `/ai/*` |
+| `access_control` | Access control | `/authentication`, `/authorization/*` |
+| `gateways` | Protocol gateways | `/gateways`, `/coap/*`, `/lwm2m/*`, `/gcp_devices`, ... |
+| `monitoring` | Monitoring data | `/metrics`, `/stats`, `/monitor*`, `/alarms`, `/trace`, `/slow_subscriptions`, `/telemetry`, `/prometheus/{auth,stats,data_integration,...}`, ... |
+| `cluster_operations` | Cluster operations | `/cluster*`, `/nodes`, `/load_rebalance`, `/node_eviction`, `/mt/*`, ... |
+| `system` | System configuration | `/configs*`, `/listeners*`, `/plugins*`, `/ds/*`, `/data/*`, `/status`, `/relup`, `/opentelemetry*`, `/prometheus`, ... |
+| `audit` | Audit log | `/audit` |
+| `license` | License | `/license*` |
+
+::: tip
+Scope names are stable identifiers that do not change across EMQX upgrades. Even if a route's OpenAPI tag is renamed, a key configured with the same scope keeps working.
+:::
+
+Dashboard login, SSO callbacks, and API key self-management endpoints (for example,`/api_key`) do not accept API-key authentication, regardless of the key's `scopes` configuration. This is a built-in Dashboard security boundary, unrelated to the scope model.
+
+##### Default Behaviour of `scopes`
+
+The `scopes` field on an API key follows these rules:
+
+| Value of `scopes` | Meaning |
+| --- | --- |
+| **Absent** (field missing) | All business endpoints are allowed. This is the backward-compatible default for keys created before the scopes feature existed. |
+| **Empty list** `[]` | Every business endpoint is denied. Useful as a soft disable without removing the key. |
+| **Explicit list** (e.g. `["monitoring", "cluster_operations"]`) | Only requests under those scopes are allowed. |
+
+When a bootstrap file entry omits the scopes segment, the key is explicitly written with all user-visible scopes (administrative all-allow), so upgrades don't silently strip privileges from existing bootstrap-provisioned keys.
+
+##### List Available Scopes
+
+EMQX exposes `GET /api/v5/api_key/scopes` to return the current version's user-visible scope catalogue with descriptions. Use it to populate a scope-picker UI or validate automation scripts:
+
+```bash
+curl -u "$API_KEY:$API_SECRET" http://localhost:18083/api/v5/api_key/scopes
+```
+
+##### Assign Scopes
+
+Scopes can be set from any of the following entry points:
+
+- **Dashboard**: When creating or editing a key under **System** -> **API Key**, tick the scopes to grant.
+- **REST API**: Include `"scopes": ["monitoring", "cluster_operations"]` in the create/update request body.
+- **Bootstrap file**: Provide a comma-separated scope list as the 4th segment of each line, e.g. `my-app:my-secret:administrator:monitoring,cluster_operations`.
+
#### Authentication Method Using API Keys
Once you have your API key and secret key, you can use them to authenticate your requests. The API key is used as the username and the secret key as the password for Basic Authentication.
diff --git a/en_US/dashboard/sso-ldap.md b/en_US/dashboard/sso-ldap.md
index aaf57af4f9..33a9809672 100644
--- a/en_US/dashboard/sso-ldap.md
+++ b/en_US/dashboard/sso-ldap.md
@@ -15,7 +15,7 @@ Be familiar with the basic concepts of [Single Sign-On (SSO)](./sso.md).
## Configure OpenLDAP SSO
-This section guides you on how to enable and configure the OpenLDAP SSO in the EMQX Dashboard.
+This section guides you through enabling and configuring OpenLDAP SSO in the EMQX Dashboard.
1. Go to Dashboard, and click **System Settings** -> **Single Sign-On** from the left navigation menu.
@@ -25,6 +25,7 @@ This section guides you on how to enable and configure the OpenLDAP SSO in the E
| Option | Description |
| ------------------ | ------------------------------------------------------------ |
+ | Force MFA | When enabled, all users from this LDAP backend are required to set up and verify MFA at login. Disabled by default. For details, see [Forced MFA for SSO Users](../multi-factor-authn/multi-factor-authentication.md#forced-mfa-for-sso-users). |
| Server | The address of the OpenLDAP server, for example, `localhost:389`. |
| Username | The Bind DN to access the OpenLDAP server. |
| Password | The user password to access the OpenLDAP server. |
@@ -89,6 +90,8 @@ Before you configure the Microsoft Extra ID SSO in the Dashboard, you need to fo
- Here, you are using IP address + secure LDAP direct access, so you need to click **Enable TLS** and disable **Verify Server Certificate**.
+ - **Force MFA**: Optionally enable this to require all users from this backend to complete TOTP verification at login. Disabled by default.
+
4. Click the **Update** button to save the configuration.
@@ -103,7 +106,7 @@ After enabling LDAP-based SSO, the EMQX Dashboard will display the LDAP SSO opti
-After successfully authenticating with LDAP, EMQX will automatically add a Dashboard user, which you can manage in [Users](./system.md#users), such as assigning roles and permissions.
+After successfully authenticating with LDAP, EMQX will automatically add a Dashboard user, which you can manage in [Users](./system.md#users), such as assigning roles and permissions. To require LDAP users to complete a TOTP second factor at login, see [Forced MFA for SSO Users](../multi-factor-authn/multi-factor-authentication.md#forced-mfa-for-sso-users).
## Logout
diff --git a/en_US/dashboard/sso-oidc.md b/en_US/dashboard/sso-oidc.md
index c10db87d67..ad3abf6693 100644
--- a/en_US/dashboard/sso-oidc.md
+++ b/en_US/dashboard/sso-oidc.md
@@ -40,6 +40,7 @@ For more detailed instructions, refer to the [Okta documentation](https://help.o
1. In the EMQX Dashboard, navigate to **System** -> **SSO**.
2. Click the **Enable** button on the **OIDC** card.
3. On the configuration page, enter the following information:
+ - **Force MFA**: Optionally enable this to require all users from this backend to complete TOTP verification at login. Disabled by default. For details, see [Forced MFA for SSO Users](../multi-factor-authn/multi-factor-authentication.md#forced-mfa-for-sso-users).
- **Provider**: Choose `Okta` or select `Generic` for other providers.
- **Issuer URL**: This is the URL of your Okta authorization server, e.g., `https://example-org.okta.com`.
- **Client ID**: Copy it from the application created in **Step 1**.
@@ -56,7 +57,7 @@ After enabling OIDC SSO, the EMQX Dashboard will display the SSO option on the l
-After successful authentication, EMQX will automatically add a Dashboard user, which you can manage in [Users](./system.md#users), such as assigning roles and permissions.
+After successful authentication, EMQX will automatically add a Dashboard user, which you can manage in [Users](./system.md#users), such as assigning roles and permissions. To require OIDC users to complete a TOTP second factor at login, see [Forced MFA for SSO Users](../multi-factor-authn/multi-factor-authentication.md#forced-mfa-for-sso-users).
## Logout
diff --git a/en_US/dashboard/sso-saml.md b/en_US/dashboard/sso-saml.md
index af9c6906f2..4ad6a31dda 100644
--- a/en_US/dashboard/sso-saml.md
+++ b/en_US/dashboard/sso-saml.md
@@ -26,6 +26,7 @@ This section guides you on how to use Okta as an Identity Provider (IdP) and con
1. Go to **System** -> **SSO** in the Dashboard.
2. Click the **Enable** button on the **SAML 2.0** card.
3. On the configuration page, enter the following information:
+ - **Force MFA**: Optionally enable this to require all users from this backend to complete TOTP verification at login. Disabled by default. For details, see [Forced MFA for SSO Users](../multi-factor-authn/multi-factor-authentication.md#forced-mfa-for-sso-users).
- **Dashboard Address**: Ensure users can access the actual access address of the Dashboard, without specifying a specific path. For example, `http://localhost:18083`. This address will be automatically concatenated to generate the **SSO Address** and **Metadata Address** for IdP-side configuration.
- **SAML Metadata URL**: Leave it temporarily blank and wait for Step 2 configuration.
4. Click **Update** to finish the configuration.
@@ -65,7 +66,7 @@ After enabling SAML Single Sign-On, the EMQX Dashboard will display the SSO opti
-After successful SAML authentication, EMQX will automatically add a Dashboard user, which you can manage in [Users](./system.md#users), such as assigning roles and permissions.
+After successful SAML authentication, EMQX will automatically add a Dashboard user, which you can manage in [Users](./system.md#users), such as assigning roles and permissions. To require SAML users to complete a TOTP second factor at login, see [Forced MFA for SSO Users](../multi-factor-authn/multi-factor-authentication.md#forced-mfa-for-sso-users).
## Logout
diff --git a/en_US/dashboard/sso.md b/en_US/dashboard/sso.md
index a55baa96ce..9e8af873ac 100644
--- a/en_US/dashboard/sso.md
+++ b/en_US/dashboard/sso.md
@@ -2,7 +2,7 @@
Single Sign-On (SSO) is an authentication mechanism that allows users to log in to multiple applications or systems using a single set of credentials, such as a username and password, without the need for separate authentication in each application. When EMQX Dashboard enables the SSO feature, users can conveniently log in to the EMQX Dashboard using their enterprise account credentials. Organizations can centrally manage user identities and permissions and simplify their user management processes. This feature enhances the security of enterprise data and systems while ensuring user convenience.
-EMQX implements SSO functionality based on Lightweight Directory Access Protocol (LDAP) and the Security Assertion Markup Language (SAML) 2.0 standard, supporting integration with mainstream identity services such as [OpenLDAP](https://www.openldap.org/), [Azure AD (Microsoft Entra ID](https://azure.microsoft.com/en-in/products/active-directory), [Okta](https://www.okta.com/), [OneLogin](https://www.onelogin.com/), and more.
+EMQX implements SSO functionality based on Lightweight Directory Access Protocol (LDAP), the Security Assertion Markup Language (SAML) 2.0 standard, and OpenID Connect (OIDC), supporting integration with mainstream identity services such as [OpenLDAP](https://www.openldap.org/), [Azure AD (Microsoft Entra ID)](https://azure.microsoft.com/en-in/products/active-directory), [Okta](https://www.okta.com/), [OneLogin](https://www.onelogin.com/), and more.
## LDAP-Based SSO
@@ -16,17 +16,28 @@ EMQX Dashboard allows you to integrate Identity Provider (IdP) services that sup
With SAML SSO, users only need to authenticate themselves once with the Identity Provider. The Identity Provider generates a SAML assertion containing user information and sends it to the EMQX Dashboard. Upon receiving and successfully verifying the SAML assertion, EMQX Dashboard creates user session information and logs the user into the Dashboard. SAML provides the capability for cross-domain authentication and authorization, supporting seamless integration between multiple applications. Enterprises can easily incorporate EMQX into their existing SAML identity systems, enabling users to access EMQX services conveniently and securely.
+## OIDC-Based SSO
+
+EMQX Dashboard allows you to integrate Identity Provider (IdP) services that support OIDC for SSO. OIDC is an identity layer built on top of the OAuth 2.0 protocol, providing a standardized way to verify user identity and obtain user information.
+
+With OIDC SSO, users authenticate with the Identity Provider, which returns an ID token containing user information to the EMQX Dashboard. Upon receiving and successfully validating the ID token, EMQX Dashboard creates user session information and logs the user into the Dashboard. OIDC provides a modern, RESTful approach to authentication, making it easy to integrate with contemporary identity services.
+
## Configuration and Usage Workflow
1. Administrators configure and enable SSO in the Dashboard. Once configured, the EMQX Dashboard displays an SSO entry point on the login page.
2. User information is configured on the Identity Provider (IdP) side.
3. Users are guided to choose different Single Sign-On methods on the Dashboard login page.
-4. After a successful login, EMQX Dashboard creates a session based on user information, allowing users to access the Dashboard.
+4. After a successful login, EMQX Dashboard creates a session based on user information, allowing users to access the Dashboard. If `force_mfa` is enabled for the backend, users are also required to complete TOTP verification before the session is issued.
5. Administrators assign roles and permissions to different users. Users can access corresponding resources after refreshing their login.
+## MFA for SSO Users
+
+Starting from EMQX 5.10, you can require SSO users to complete a TOTP second factor at login by enabling `force_mfa` on each SSO backend. For details, see [Forced MFA for SSO Users](../multi-factor-authn/multi-factor-authentication.md#forced-mfa-for-sso-users).
+
## Configuration Examples
-Below are configuration examples for SSO based on LDAP and SAML 2.0:
+Below are configuration examples for each SSO method:
- [Configure LDAP Single Sign-On](./sso-ldap.md)
- [Configure SAML Single Sign-On](./sso-saml.md)
+- [Configure OIDC Single Sign-On](./sso-oidc.md)
diff --git a/en_US/dashboard/system.md b/en_US/dashboard/system.md
index 2db4295080..b9398b3113 100644
--- a/en_US/dashboard/system.md
+++ b/en_US/dashboard/system.md
@@ -33,30 +33,7 @@ For a detailed overview of the Audit Log feature, see [Audit Log](../dashboard/a
## API Keys
-On the **API Keys** page, you can generate an API key and secret key for accessing the [HTTP API](../admin/api.md) by following the steps below.
-
-1. Click the **+ Create** button in the top right corner of the page to bring up the Create API Key pop-up dialog.
-
-2. On the Create API Key dialog, configure the detailed information for the API key.
-
- - The API key will never expire if the Expire At box is left empty.
- - Select a role for the API key (optional). For more information about roles, see [Roles and Permissions](../admin/api.md#roles-and-permissions).
-
-3. Click the **Confirm** button, and the API key and secret Key are created and displayed in the **Created Successfully** dialog.
-
- ::: warning Notice
-
- You need to save the API Key and Secret Key in a safe place because the secret key will not be shown again.
-
- :::
-
- Click the **Close** button to close the dialog.
-
-
-
-You can view the details of the API key by clicking the name in the **Name** column. You click the **Edit** button in the **Actions** column to reset the expiration time, change the status, and edit the note of the API key. If an API key is no longer needed, you can delete it by clicking the **Delete** button.
-
-
+The **API Keys** page allows you to create and manage API keys for accessing the [HTTP API](../admin/api.md). For instructions on creating and managing API keys, including role and scope assignment, see [Create API Keys](../admin/api.md#create-api-keys).
## License
diff --git a/en_US/multi-factor-authn/multi-factor-authentication.md b/en_US/multi-factor-authn/multi-factor-authentication.md
index d252b5dbfe..a498c7bb71 100644
--- a/en_US/multi-factor-authn/multi-factor-authentication.md
+++ b/en_US/multi-factor-authn/multi-factor-authentication.md
@@ -122,3 +122,77 @@ After you've completed the initial setup, you can use the authenticator app to l
If the code is valid, you will be logged into the Dashboard.
4. **Invalid Code**:
If the code is incorrect or expired, you will see an error message. In this case, you can try entering the current code from your authenticator app.
+
+## Forced MFA for SSO Users
+
+Starting from EMQX 5.10, MFA can also be required for SSO users. Once you have enabled [Single Sign-On (SSO)](../dashboard/sso.md) (SAML, OIDC, or LDAP), you can turn on a per-backend `force_mfa` switch that requires every user arriving from that backend to pass a TOTP second factor in addition to the IdP authentication.
+
+This matters especially for EMQX deployments exposed on public networks: even if an identity is leaked at the upstream IdP, an attacker still cannot reach the Dashboard without also owning the user's authenticator device.
+
+`force_mfa` is configured for each SSO backend (`saml`, `oidc`, and `ldap`) independently. Local accounts are unaffected. Each SSO user's TOTP secret is stored separately from local users'. Administrators can enable, disable, or reset MFA for any individual SSO user; a user with MFA disabled is exempt from TOTP even when the backend has `force_mfa = true`, which is useful for break-glass admin accounts.
+
+### Enable Forced MFA for an SSO Backend
+
+In `base.hocon`, add `force_mfa = true` to each backend that must require MFA. You can also configure this in the Dashboard SSO configuration UI; see [Configure LDAP SSO](../dashboard/sso-ldap.md), [Configure SAML SSO](../dashboard/sso-saml.md), and [Configure OIDC SSO](../dashboard/sso-oidc.md).
+
+Example configuration:
+
+```hocon
+dashboard {
+ sso {
+ saml {
+ enable = true
+ force_mfa = true # every SAML user must complete TOTP at login
+ # ... other SAML settings
+ }
+ oidc {
+ enable = true
+ force_mfa = false # not enforced; you can still enable it per user
+ # ... other OIDC settings
+ }
+ ldap {
+ enable = true
+ force_mfa = true
+ # ... other LDAP settings
+ }
+ }
+}
+```
+
+`force_mfa` defaults to `false`, preserving pre-5.10 behaviour.
+
+::: tip
+Turning `force_mfa` on does not retroactively invalidate existing sessions. It takes effect on the next fresh login.
+:::
+
+### Manage MFA for Individual SSO Users
+
+In the Dashboard, go to **System** -> **Users**. SSO users are listed with their backend shown next to the username. Click the **MFA Settings** button in the Actions column to:
+
+- **Enable MFA**: force this user to set up and use TOTP on the next login, even when the corresponding backend has `force_mfa` off.
+- **Disable MFA**: mark the user as exempt. They skip TOTP even when the backend requires it. This is useful for break-glass administrators.
+- **Reset TOTP secret**: clear the current secret. The user enters the setup flow again on the next login. Use this when a user loses their authenticator device.
+
+### SSO Login Flow with MFA
+
+Forcing MFA does not change the SSO login experience:
+
+1. Click the "Log in with SSO" button as usual.
+2. Authenticate at the IdP.
+3. After returning to the Dashboard, enter a TOTP code if MFA applies to you.
+4. On the first login when `force_mfa` is enabled, you will be guided through a one-time TOTP setup (scan QR / enter key) before reaching the Dashboard.
+
+::: tip Security Note
+By design, no Dashboard access credential is issued before TOTP succeeds. Intercepting the SSO callback link cannot bypass MFA.
+:::
+
+### FAQ
+
+**Q: Will already-logged-in SSO users be kicked out when I enable `force_mfa`?**
+A: No. `force_mfa` only gates new logins. Existing sessions remain valid until they expire.
+
+**Q: How do I temporarily disable MFA for a break-glass account?**
+A: Find the user under **System** -> **Users**, click **MFA Settings** -> **Disable MFA**. Subsequent logins skip TOTP until you re-enable or reset.
+
+**Q: Can I require MFA for only a subset of SSO users instead of the whole backend?**
+A: Yes — leave `force_mfa` at `false` and enable MFA for the users you want to cover one by one from the **Users** page.
diff --git a/zh_CN/admin/api.md b/zh_CN/admin/api.md
index a6e35192ce..38084daceb 100644
--- a/zh_CN/admin/api.md
+++ b/zh_CN/admin/api.md
@@ -44,7 +44,31 @@ EMQX 的 REST API 支持两种主要的认证方法:使用 API 密钥的基本
#### 创建 API 密钥
-您可以在 Dashboard **系统设置** -> **API 密钥** 页面中手动创建用于认证的 API 密钥,详细操作请参考 [Dashboard - API 密钥](../dashboard/system.md#api-密钥)。
+##### Dashboard
+
+您可以在 Dashboard **系统设置** -> **API 密钥**页面中手动创建 API 密钥:
+
+1. 单击页面右上角的**创建**按钮,打开创建对话框。
+2. 配置 API 密钥详细信息:
+ - **密钥名称**(必填):输入 API 密钥的名称。
+ - **到期时间**:留空表示永不过期。
+ - **是否启用**:默认为启用。
+ - **角色**:选择角色(可选),参见[角色与权限](#角色与权限)。
+ - **权限范围**:选择授予的范围(可选),默认拥有全部范围权限,参见 [API 范围(Scope)](#api-范围-scope)。
+ - **备注**:可选,填写密钥的描述信息。
+3. 单击**确认**,API 密钥和 Secret Key 将显示在**创建成功**对话框中。
+
+ ::: warning 重要提示
+
+ 请立即保存 API Key 和 Secret Key。Secret Key 后续将不再显示。
+
+ :::
+
+4. 单击**关闭**按钮关闭对话框。
+
+已创建的密钥可在列表页查看详情,通过**编辑**按钮修改到期时间、状态和备注,或通过**删除**按钮移除。
+
+##### Bootstrap 文件
您也可以通过 bootstrap 文件的方式创建 API 密钥。在 `base.hocon` 配置文件中添加以下配置,指定文件位置:
@@ -54,11 +78,12 @@ api_key = {
}
```
-在指定的文件中通过多行分割的 `{API Key}:{Secret Key}:{?Role}` 的格式添加多个 API 密钥:
+在指定的文件中通过多行分割的 `{API Key}:{Secret Key}:{?Role}:{?Scopes}` 的格式添加多个 API 密钥:
- **API Key**:任意字符串作为密钥标识。
- **Secret Key**:使用随机字符串作为密钥。
-- **Role (可选)**:指定密钥的[角色](#角色与权限)。
+- **Role(可选)**:指定密钥的[角色](#角色与权限)。
+- **Scopes(可选)**:指定密钥可访问的 [API 范围](#api-范围-scope),多个范围用英文逗号分隔。省略时密钥默认拥有全部用户可见范围(管理员场景下的向后兼容行为)。
例如:
@@ -66,20 +91,96 @@ api_key = {
my-app:AAA4A275-BEEC-4AF8-B70B-DAAC0341F8EB
ec3907f865805db0:Ee3taYltUKtoBVD9C3XjQl9C6NXheip8Z9B69BpUv5JxVHL:viewer
foo:3CA92E5F-30AB-41F5-B3E6-8D7E213BE97E:publisher
+integration-svc:6f1a9f2d09c84e6b:viewer:monitoring,cluster_operations
+rules-mgr:2b8e4a1c9d7e4f3b:administrator:data_integration,access_control
```
通过此方式创建的 API 密钥有效期为永久有效。
-每次 EMQX 启动时,会将文件中设置的数据添加到 API 密钥列表中,如果存在相同的 API Key,则将更新其 Secret Key 与 Role。
+每次 EMQX 启动时,会将文件中设置的数据添加到 API 密钥列表中,如果存在相同的 API Key,则将更新其 Secret Key、Role 与 Scopes。
#### 角色与权限
-在 EMQX 企业版中,REST API 实现了基于角色的访问控制,API 密钥创建时,可以分配以下3个预定义的角色:
+在 EMQX 企业版中,REST API 实现了基于角色的访问控制,API 密钥创建时,可以分配以下 3 个预定义的角色:
- **管理员**:此角色可以访问所有资源,未指定角色时默认使用此值。对应的角色标识为 `administrator`。
- **查看者**:此角色只能查看资源和数据,对应于 REST API 中的所有 GET 请求。对应的角色标识为 `viewer`。
- **发布者**:专门为 MQTT 消息发布定制,此角色仅限于访问与消息发布相关的 API。对应的角色标识为 `publisher`。
+#### API 范围(Scope)
+
+**Scope(范围)** 是 EMQX 5.10 引入的 API 密钥权限控制维度,用来声明一个密钥可以访问哪些业务领域的 API。它与[角色与权限](#角色与权限)相互独立、共同生效,形成两层权限控制:
+
+| 维度 | 作用 | 粒度 |
+| ---- | ---- | ---- |
+| **Role(角色)** | 限制 HTTP 方法(只读 vs 可写、只能发布等) | 请求动作 |
+| **Scope(范围)** | 限制可访问的 API 领域(客户端、规则、监控等) | 资源领域 |
+
+一次请求会先后通过两个检查:Role 校验 + Scope 校验。只有两个检查都通过,请求才会被接受。
+
+##### 为什么需要 Scope
+
+在微服务与集成场景中,不同的外部系统通常只需要访问 EMQX 的一部分管理接口:
+
+- 监控平台只需要读 `/metrics`、`/stats`、`/prometheus` 等 `monitoring` 范围的接口;
+- 规则发布服务只需要操作 `/rules`、`/connectors`、`/actions` 等 `data_integration` 范围的接口;
+- 集群运维工具只需要访问 `/cluster`、`/nodes`、`/load_rebalance` 等 `cluster_operations` 范围的接口。
+
+以前只有 `administrator` / `viewer` / `publisher` 三种角色,颗粒度较粗:想让一个服务只能改规则,就不得不授予 `administrator`,这等于把整个系统的管理权都交给对方。
+
+通过 Scope,您可以按最小权限原则分配密钥:只授予完成任务所需的最少范围,降低单个密钥被泄露带来的影响面。
+
+##### 内置范围
+
+EMQX 5.10 提供 10 个 Scope,可在创建密钥时自由组合:
+
+| Scope 标识 | 名称 | 涵盖的典型 API 领域 |
+| --- | --- | --- |
+| `connections` | 连接管理 | `/clients`、`/subscriptions`、`/topics`、`/banned`、`/retainer`、`/file_transfer`、`/mqtt/delayed`、`/mqtt/topic_rewrite` 等 |
+| `publish` | 消息发布 | `/publish`、`/publish/bulk` |
+| `data_integration` | 数据集成 | `/rules`、`/connectors`、`/actions`、`/schema_registry`、`/schema_validations`、`/message_transformations`、`/exhooks`、`/ai/*` |
+| `access_control` | 访问控制 | `/authentication`、`/authorization/*` |
+| `gateways` | 协议网关 | `/gateways`、`/coap/*`、`/lwm2m/*`、`/gcp_devices` 等 |
+| `monitoring` | 监控数据 | `/metrics`、`/stats`、`/monitor*`、`/alarms`、`/trace`、`/slow_subscriptions`、`/telemetry`、`/prometheus/{auth,stats,data_integration,...}` 等 |
+| `cluster_operations` | 集群运维 | `/cluster*`、`/nodes`、`/load_rebalance`、`/node_eviction`、`/mt/*` 等 |
+| `system` | 系统配置 | `/configs*`、`/listeners*`、`/plugins*`、`/ds/*`、`/data/*`、`/status`、`/relup`、`/opentelemetry*`、`/prometheus` 等 |
+| `audit` | 审计日志 | `/audit` |
+| `license` | 许可证 | `/license*` |
+
+::: tip 提示
+Scope 是稳定标识符,不会随 EMQX 版本升级而改名;即便某个 API 的 OpenAPI tag 发生变化,只要您使用的是同一个 Scope,密钥行为保持不变。
+:::
+
+Dashboard 自身的登录、SSO 回调以及 API 密钥自身的管理接口不支持使用 API 密钥进行认证/授权;例如,API 密钥管理接口 `/api_key` 仅允许使用 bearer token。这与密钥的业务范围无关,属于 Dashboard 的内置安全边界。
+
+##### Scope 的默认行为
+
+`scopes` 字段在 API 密钥中的行为遵循以下规则:
+
+| `scopes` 字段的值 | 语义 |
+| --- | --- |
+| **未设置**(字段不存在) | 放行所有业务端点。主要用于历史升级场景,保持与旧版本兼容。 |
+| **空列表** `[]` | 拒绝所有业务端点。常用于临时禁用密钥而不删除它。 |
+| 显式列出的范围(如 `["monitoring", "cluster_operations"]`) | 只允许请求这些范围下的端点。 |
+
+Bootstrap 文件中不指定 Scopes 时,密钥将显式写入所有用户可见范围(等同于管理员全权限),确保升级路径下已有的 bootstrap 文件不会因为新加了 Scope 机制而突然失去权限。
+
+##### 查询可用范围
+
+EMQX 提供 `GET /api/v5/api_key/scopes` 端点返回当前版本支持的用户可见 Scope 列表及其描述,可用于前端渲染 Scope 选择 UI 或运维脚本校验配置:
+
+```bash
+curl -u "$API_KEY:$API_SECRET" http://localhost:18083/api/v5/api_key/scopes
+```
+
+##### 如何分配 Scope
+
+Scope 可以在以下任一入口指定:
+
+- **Dashboard**:在**系统设置** -> **API 密钥**创建或编辑密钥时,勾选需要授予的范围。
+- **REST API**:在创建 / 更新 API 密钥时,请求体加入 `"scopes": ["monitoring", "cluster_operations"]`。
+- **Bootstrap 文件**:在每一行的第四段以逗号分隔范围名,例如 `my-app:my-secret:administrator:monitoring,cluster_operations`。
+
#### 认证方式
使用生成的 API Key 以及 Secret Key 分别作为 Basic 认证的用户名与密码,请求示例如下:
diff --git a/zh_CN/changes/changes-ee-v5.md b/zh_CN/changes/changes-ee-v5.md
index 94acd0fe68..574280efcd 100644
--- a/zh_CN/changes/changes-ee-v5.md
+++ b/zh_CN/changes/changes-ee-v5.md
@@ -835,8 +835,7 @@
- 管理员命名空间(管理员用户组)功能不包括在此次提交中,仍在开发中。
- [#14884](https://github.com/emqx/emqx/pull/14884) 添加了 HTTP API 用于管理命名空间配置。
-
-- [#14840](https://github.com/emqx/emqx/pull/14840) Added HTTP API endpoints to configure client and tenant rate limiters for multi-tenancy feature.
+- [#14840](https://github.com/emqx/emqx/pull/14840) 为多租户功能新增了 HTTP API 接口,用于配置客户端和租户的速率限制器。
#### 认证与授权
diff --git a/zh_CN/dashboard/sso-ldap.md b/zh_CN/dashboard/sso-ldap.md
index d493054cd2..e89f8eb705 100644
--- a/zh_CN/dashboard/sso-ldap.md
+++ b/zh_CN/dashboard/sso-ldap.md
@@ -25,6 +25,7 @@
| 选项 | 说明 |
| ------------ | ------------------------------------------------------------ |
+ | 强制启用 MFA | 开启后,该 SSO 后端的所有用户在登录时须完成 MFA 设置或验证。默认关闭。详情参见[为 SSO 用户强制启用 MFA](../multi-factor-authn/multi-factor-authentication.md#为-sso-用户强制启用-mfa)。 |
| 服务 | LDAP服务器的地址,例如`localhost:389`。 |
| 用户名 | 访问 LDAP 服务器的绑定 DN(Bind DN)。 |
| 密码 | 访问 LDAP 服务器的用户密码。 |
@@ -71,6 +72,7 @@
1. 转到 Dashboard **系统设置** -> **单点登录** 页面。
2. 选择 **LDAP** 选项,点击 **启用** 按钮。
3. 在配置页面中,输入 LDAP 服务器的基本信息:
+ - **强制启用 MFA**:可选。开启后,该后端的所有用户在登录时须完成 TOTP 验证。默认关闭。
- **服务**:填写 `ip:port`,其中 IP 为 Microsoft Entra ID 的安全 LDAP 外部 IP 地址,端口为加密 LDAP `636`.
- **用户名**、**密码**:填写 Entra ID 中创建的用于连接 Entra ID 的用户以及其密码。
- **基本 DN**:根据 Azure AD 的域名填写,例如 `emqxqa.onmicrosoft.com` 填写为 `DC=emqxqa,DC=onmicrosoft,DC=com`。可以添加其他属性,将用户限制在某个部门或者分组内。
@@ -89,7 +91,7 @@
-成功进行 LDAP 身份验证后,EMQX 会自动添加一个 Dashboard 用户,您可以在[用户](./system.md#用户)中进行管理,例如为其分配角色与权限。
+成功进行 LDAP 身份验证后,EMQX 会自动添加一个 Dashboard 用户,您可以在[用户](./system.md#用户)中进行管理,例如为其分配角色与权限。如需要求 LDAP 用户在登录时完成 TOTP 二次验证,请参见[为 SSO 用户强制启用 MFA](../multi-factor-authn/multi-factor-authentication.md#为-sso-用户强制启用-mfa)。
## 退出登录
diff --git a/zh_CN/dashboard/sso-oidc.md b/zh_CN/dashboard/sso-oidc.md
index 1442bf0f99..620f91bd6d 100644
--- a/zh_CN/dashboard/sso-oidc.md
+++ b/zh_CN/dashboard/sso-oidc.md
@@ -34,6 +34,7 @@ EMQX Dashboard 可以与支持 OIDC 协议的身份服务集成,以启用基
1. 在 EMQX Dashboard 中,导航到 **System** -> **SSO**。
2. 在 **OIDC** 选项卡中点击**启用**按钮。
3. 在配置页面中,输入以下信息:
+ - **强制启用 MFA**:可选。开启后,该后端的所有用户在登录时须完成 TOTP 验证。默认关闭。详情参见[为 SSO 用户强制启用 MFA](../multi-factor-authn/multi-factor-authentication.md#为-sso-用户强制启用-mfa)。
- **提供商**:选择 `Okta` 或为其他提供商选择 `通用`。
- **签发者 URL**:这是您的 Okta 授权服务器的 URL,例如 `https://example-org.okta.com`。
- **Client ID**:从**第一步**创建的应用程序中复制。
@@ -49,7 +50,7 @@ EMQX Dashboard 可以与支持 OIDC 协议的身份服务集成,以启用基
-认证成功后,EMQX 将自动添加一个 Dashboard 用户,您可以在[用户](./system.md#用户)中管理该用户,例如分配角色和权限。
+认证成功后,EMQX 将自动添加一个 Dashboard 用户,您可以在[用户](./system.md#用户)中管理该用户,例如分配角色和权限。如需要求 OIDC 用户在登录时完成 TOTP 二次验证,请参见[为 SSO 用户强制启用 MFA](../multi-factor-authn/multi-factor-authentication.md#为-sso-用户强制启用-mfa)。
## 退出登录
diff --git a/zh_CN/dashboard/sso-saml.md b/zh_CN/dashboard/sso-saml.md
index fb4c4a7e92..828f8d3bc7 100644
--- a/zh_CN/dashboard/sso-saml.md
+++ b/zh_CN/dashboard/sso-saml.md
@@ -25,6 +25,7 @@ EMQX Dashboard 可以与以下支持 SAML 2.0 协议的身份服务集成,实
1. 转到 Dashboard **系统设置** -> **单点登录**页面。
2. 选择 **SAML 2.0** 选项,点击**启用**按钮。
3. 在配置页面中,输入以下信息:
+ - **强制启用 MFA**:可选。开启后,该后端的所有用户在登录时须完成 TOTP 验证。默认关闭。详情参见[为 SSO 用户强制启用 MFA](../multi-factor-authn/multi-factor-authentication.md#为-sso-用户强制启用-mfa)。
- **Dashboard 地址**:确保用户能够访问 Dashboard 的实际访问地址,不需要带具体路径。例如 `http://localhost:18083`。该地址将自动拼接生成**单点登录地址**与**元数据地址**供 IdP 侧配置使用。
- **SAML 元数据 URL**:暂时留空,等待第 2 步配置生成。
@@ -62,7 +63,7 @@ EMQX Dashboard 可以与以下支持 SAML 2.0 协议的身份服务集成,实
-登录成功后,将跳转回到 Dashboard,EMQX 会自动添加一个 Dashboard 用户,您可以在[用户](./system.md#用户)中进行管理,例如为其分配角色与权限。
+登录成功后,将跳转回到 Dashboard,EMQX 会自动添加一个 Dashboard 用户,您可以在[用户](./system.md#用户)中进行管理,例如为其分配角色与权限。如需要求 SAML 用户在登录时完成 TOTP 二次验证,请参见[为 SSO 用户强制启用 MFA](../multi-factor-authn/multi-factor-authentication.md#为-sso-用户强制启用-mfa)。
## 退出登录
diff --git a/zh_CN/dashboard/sso.md b/zh_CN/dashboard/sso.md
index b640040bc9..407c66f14d 100644
--- a/zh_CN/dashboard/sso.md
+++ b/zh_CN/dashboard/sso.md
@@ -2,7 +2,7 @@
单点登录(Single Sign-On, SSO)是一种身份验证机制,它允许用户使用一组凭据(例如用户名和密码)登录到多个应用程序或系统中,而无需在每个应用程序中单独进行身份验证。EMQX Dashboard 开启单点登录后,用户可以方便地使用企业账号管理系统登录到 EMQX Dashboard。 企业能够集中管理用户身份和权限,简化用户管理流程,在提高企业数据和系统的安全性的同时,兼顾了用户使用的便捷性。
-EMQX 基于轻量级目录访问协议(LDAP)和安全断言标记语言(SAML )2.0 标准实施 SSO 功能,支持集成例如 [OpenLDAP](https://www.openldap.org/)、[Azure AD(Microsoft Entra ID)](https://azure.microsoft.com/en-in/products/active-directory) 以及 [Okta](https://www.okta.com/)、[OneLogin](https://www.onelogin.com/) 等主流身份服务提供商。
+EMQX 基于轻量级目录访问协议(LDAP)、安全断言标记语言(SAML)2.0 标准以及 OpenID Connect(OIDC)实施 SSO 功能,支持集成例如 [OpenLDAP](https://www.openldap.org/)、[Azure AD(Microsoft Entra ID)](https://azure.microsoft.com/en-in/products/active-directory) 以及 [Okta](https://www.okta.com/)、[OneLogin](https://www.onelogin.com/) 等主流身份服务提供商。
## 基于 LDAP 的单点登录
@@ -16,17 +16,28 @@ EMQX Dashboard 允许您集成支持 SAML 的身份提供商服务实现单点
使用 SAML 单点登录时,用户只需在身份提供商验证身份一次,身份提供商即可生成包含用户信息的 SAML 断言发送给 EMQX Dashboard。EMQX Dashboard 收到并验证 SAML 断言成功后,即可创建用户会话信息并登录进入 Dashboard。SAML 提供了跨域认证和授权的能力,支持多个应用程序之间的无缝集成。企业可以轻松将 EMQX 接入已有的 SAML 身份体系中,使用户能更便捷安全地访问 EMQX 提供的服务。
+## 基于 OIDC 的单点登录
+
+EMQX Dashboard 允许您集成支持 OIDC 的身份提供商服务实现单点登录。OIDC 是建立在 OAuth 2.0 协议之上的身份层,提供了一种标准化的方式来验证用户身份并获取用户信息。
+
+使用 OIDC 单点登录时,用户在身份提供商处进行身份验证,身份提供商会返回包含用户信息的 ID 令牌给 EMQX Dashboard。EMQX Dashboard 收到并验证 ID 令牌成功后,即可创建用户会话信息并登录进入 Dashboard。OIDC 提供了现代化的 RESTful 身份验证方式,便于与现代身份服务集成。
+
## 配置和使用流程
1. 管理员在 Dashboard 中配置并启用单点登录,配置完成后,EMQX Dashboard 会在登录页面展示单点登录入口。
2. 在身份服务提供商(Identity Provider,IdP)侧配置用户信息。
3. 引导用户在 Dashboard 登录页面选择不同的单点登录方式。
-4. 登录成功后,EMQX Dashboard 会根据用户信息创建会话,用户即可访问 Dashboard。
+4. 登录成功后,EMQX Dashboard 会根据用户信息创建会话,用户即可访问 Dashboard。如果该后端开启了 `force_mfa`,用户还需完成 TOTP 验证后才能获得会话凭据。
5. 管理员为不同用户分配角色与权限,用户刷新登录后即可访问对应的资源。
+## 为 SSO 用户启用 MFA
+
+EMQX 5.10 起支持为 SSO 用户强制启用多因素认证(MFA),通过在各 SSO 后端配置 `force_mfa` 要求用户在完成 IdP 认证后额外通过 TOTP 验证。详情参见[为 SSO 用户强制启用 MFA](../multi-factor-authn/multi-factor-authentication.md#为-sso-用户强制启用-mfa)。
+
## 配置示例
-以下为您提供基于 LDAP 与 SAML 2.0 的 SSO 配置示例:
+以下为各 SSO 方式的配置示例:
- [配置 LDAP 单点登录](./sso-ldap.md)
- [配置 SAML 单点登录](./sso-saml.md)
+- [配置 OIDC 单点登录](./sso-oidc.md)
diff --git a/zh_CN/dashboard/system.md b/zh_CN/dashboard/system.md
index 59fc647027..4894ba8104 100644
--- a/zh_CN/dashboard/system.md
+++ b/zh_CN/dashboard/system.md
@@ -32,32 +32,7 @@ EMQX Dashboard 中的**系统设置** 菜单提供一系列管理功能入口,
## API 密钥
-点击左侧**系统设置**菜单下的 **API 密钥**,可以来到 API 密钥页面。如果需要 API 密钥来创建一些脚本调用 [HTTP API](../admin/api.md),可以在此页面进行创建获取操作。点击页面右上角**创建**按钮打开创建 API 密钥弹框,填写 API 密钥相关数据,如果**到期时间**未填写 API 密钥将永不过期,点击**确定**提交数据,提交成功后页面上将提供此次创建的 API 密钥的 API Key 和 Secret Key,**其中 Secret Key 后续将不再显示**,用户需立即将 API Key 和 Secret Key 保存至安全的地方;保存数据完毕可点击**关闭**按钮关闭弹框。
-
-在 API 密钥页面上,您可以按照以下步骤生成用于访问 [HTTP API](../admin/api.md) 的 API 密钥和 Secret key。
-
-1. 单击页面右上角的**创建**按钮,弹出创建 API 密钥的对话框。
-
-2. 在创建 API 密钥对话框上,配置 API 密钥的详细信息。
-
- - 如果**到期时间**文本框留空,API 密钥将永不过期。
- - 您可以指定密钥的[角色](../admin/api.md#角色与权限)(可选)。
-
-3. 单击**确认**按钮,API 密钥和密钥将被创建并显示在**创建成功**对话框中。
-
- ::: tip
-
- 您需要将 API Key 和 Secret Key 保存在安全的地方,因为 Secret Key 将不再显示。
-
- :::
-
- 单击**关闭**按钮以关闭对话框。
-
-
-
-已创建的 API 密钥可在页面上进行查看和切换启用状态,点击 API 密钥名称可查看密钥详情。点击**编辑**按钮可重新设置 API 密钥的到期时间、启用状态和备注,如某 API 密钥已过期,可在此延长 API 密钥的可使用时间。如果某个 API 密钥已不再需要,可点击 API 密钥右侧**删除**按钮删除 API 密钥。
-
-
+**API 密钥**页面用于创建和管理访问 [HTTP API](../admin/api.md) 所需的 API 密钥。有关创建和管理 API 密钥(包括角色与范围分配)的操作说明,请参见[创建 API 密钥](../admin/api.md#创建-api-密钥)。
## License
diff --git a/zh_CN/multi-factor-authn/multi-factor-authentication.md b/zh_CN/multi-factor-authn/multi-factor-authentication.md
index 41388af36d..78dcc0cc56 100644
--- a/zh_CN/multi-factor-authn/multi-factor-authentication.md
+++ b/zh_CN/multi-factor-authn/multi-factor-authentication.md
@@ -113,3 +113,77 @@ dashboard.default_mfa = {mechanism: totp}
2. **输入 TOTP 代码**: 验证密码后,系统会提示您输入由身份验证应用程序生成的 TOTP 代码。
3. **成功登录**: 如果验证码有效,您将成功登录 Dashboard。
4. **验证码无效**: 如果验证码错误或过期,您将看到一条错误消息。在这种情况下,您可以尝试重新输入当前身份验证应用程序中的验证码。
+
+## 为 SSO 用户强制启用 MFA
+
+除了 Dashboard 的本地账户之外,EMQX 5.10 起还支持为 SSO 用户强制启用 MFA。当您启用了 [单点登录(SSO)](../dashboard/sso.md)(SAML、OIDC 或 LDAP)后,可以针对每个 SSO 后端单独开启该功能,要求所有通过该后端登录的用户在完成 IdP(身份提供方)认证后,额外完成一次 TOTP 双因素验证。
+
+这对部署在公共网络上的 EMQX 尤其重要:即使外部 IdP 的账户不慎泄露,攻击者依然无法登录 Dashboard,除非他们同时掌握用户的 TOTP 验证器。
+
+`force_mfa` 可以针对每个 SSO 后端(`saml`、`oidc` 和 `ldap`)单独配置,不影响本地用户。SSO 用户的 TOTP 密钥与本地用户完全隔离。管理员可以为任意 SSO 用户启用、禁用或重置 MFA;被禁用的用户即便后端开启了 `force_mfa = true` 也会被豁免,适合用于紧急救援账号。
+
+### 为 SSO 后端开启强制 MFA
+
+在 `base.hocon` 中,为每个需要强制 MFA 的后端加上 `force_mfa = true`。也可以在 Dashboard 的 SSO 配置页面中进行配置,详见[配置 LDAP 单点登录](../dashboard/sso-ldap.md)、[配置 SAML 单点登录](../dashboard/sso-saml.md)和[配置 OIDC 单点登录](../dashboard/sso-oidc.md)。
+
+配置示例:
+
+```hocon
+dashboard {
+ sso {
+ saml {
+ enable = true
+ force_mfa = true # 所有 SAML 用户登录时必须完成 TOTP
+ # ... 其他 SAML 配置
+ }
+ oidc {
+ enable = true
+ force_mfa = false # 不强制;可以在 Dashboard 对单个用户启用
+ # ... 其他 OIDC 配置
+ }
+ ldap {
+ enable = true
+ force_mfa = true
+ # ... 其他 LDAP 配置
+ }
+ }
+}
+```
+
+`force_mfa` 默认是 `false`,即升级前的行为,SSO 用户按旧流程登录。
+
+::: tip
+开启 `force_mfa` 不会追溯影响已经登录的用户;只会在用户下一次登录时生效。
+:::
+
+### 管理单个 SSO 用户的 MFA
+
+在 Dashboard 的**系统设置** -> **用户**页面可以找到所有 SSO 用户(用户名旁会标注所属后端)。点击该用户行的 **MFA 设置**可以:
+
+- **启用 MFA**:让该用户在下次登录时必须绑定并使用 TOTP,即便对应后端的 `force_mfa` 没开。
+- **禁用 MFA**:把该用户标记为豁免,即便后端 `force_mfa = true` 也跳过。适用于紧急救援账号。
+- **重置 TOTP 密钥**:清除当前密钥,用户下次登录时会重新进入首次设置流程。常用于用户丢失验证器设备时。
+
+### 登录体验
+
+对最终用户而言,强制 MFA 并不会改变 SSO 登录的交互:
+
+1. 正常点击"使用 SSO 登录"按钮;
+2. 在 IdP 页面完成身份认证;
+3. 回到 Dashboard 后,如果您启用了 MFA,会要求输入一次 TOTP 验证码;
+4. 首次登录且该后端已开启 `force_mfa` 时,会先引导您完成 TOTP 绑定(扫码 / 手动添加密钥),再进入 Dashboard。
+
+::: tip 安全说明
+登录流程的设计保证了 TOTP 未通过之前**不会**签发任何 Dashboard 访问凭据,即便回调链接被他人截获也无法绕过 MFA。
+:::
+
+### 常见问题
+
+**Q:已经登录的 SSO 用户,会因为我开启 `force_mfa` 被踢下线吗?**
+A:不会。`force_mfa` 只影响下一次新登录。已有会话继续有效直到过期。
+
+**Q:如何为一个紧急救援账号临时禁用 MFA?**
+A:在 Dashboard **用户**页面找到该 SSO 用户,**MFA 设置** -> **禁用 MFA**。该用户后续登录会跳过 TOTP,直到您重新启用或重置。
+
+**Q:能不能只对某一批 SSO 用户启用 MFA,而不是整个后端?**
+A:可以。不开启 `force_mfa`(保持 `false`),然后在**用户**页面逐个为需要 MFA 的用户手动启用即可。