> ## Documentation Index
> Fetch the complete documentation index at: https://docs.alforse.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用飞书/Lark、钉钉和 OIDC 的单点登录

> 让员工通过飞书或 Lark、钉钉，或 Okta、Entra ID、Auth0、Keycloak 等任意 OpenID Connect 身份提供商登录 Alforse。

除 [SAML 2.0](https://docs.alforse.com/zh/docs/reference/single-sign-on.md) 外，Alforse 还可以把登录交给贵公司的飞书 / Lark 或钉钉组织，或任意 OpenID Connect（OIDC）身份提供商。公司管理员在**单点登录**页面设置一次；此后，输入已验证域名下工作邮箱的人会被导向该提供方登录。

## 概念

* **每家公司一个连接。** 贵公司只有一个单点登录连接，使用一种协议：**OpenID Connect**、**飞书 / Lark**、**钉钉**或 SAML。在本页保存前三者之一，会替换已有的 SAML 连接（参见[从 SAML 切换](#switching-from-saml)）。
* **已验证的域名决定登录路由。** 只有用 DNS 记录证明过的邮箱域名，才会把人导向该提供方。
* **先邀请。** 单点登录绝不会自行创建账户。一个人只能以现有成员的身份进入，或接受贵公司的待处理邀请。
* **已关联账号。** 第一次成功登录会把提供方账号与 Alforse 中的人员关联起来。之后的登录直接使用该关联。

## 开始之前

* **权限。** 您需要修改公司设置的权限（`settings` 更新）。没有该权限时，页面显示**“仅限管理员”**。
* **可用性。** 如果您的订阅不含单点登录，页面显示**“您的套餐不含单点登录”**。
* **提供方权限。** 您需要有权在身份提供商中创建应用：飞书 / Lark 开放平台中的企业自建应用、钉钉开发者后台中的企业内部应用，或 IdP 中的 OIDC Web 应用。
* **DNS 权限。** 您需要为每个邮箱域名发布一条 TXT 记录。

## 打开单点登录页面

1. 登录 ERP：[https://app.alforse.com。](https://app.alforse.com。)
2. 在同一浏览器中打开 **[https://api.alforse.com/identity](https://api.alforse.com/identity)**。

如果页面显示**“请先登录”**，请选择**登录**，登录 ERP 后再次打开该地址。页面顶部的 **EN** / **中文**按钮可在英文和简体中文之间切换页面语言。连接建立后，标题旁的状态显示**已启用**，否则显示**未配置**。

页面有五张卡片：**身份提供方**、**强制单点登录**、**邮箱域名**、**登录链接**和**已关联账号**。保存连接之前，只显示**身份提供方**。

Alforse screenshot**api.alforse.com/identity 上的单点登录页面：身份提供方卡片，含提供方选择、可复制的重定向 URI 字段和连接按钮**

所有提供方都在“身份提供方”卡片中设置。

## “身份提供方”卡片

| 字段 | 适用于 | 填写内容 |
| - | - | - |
| **提供方** | 全部 | **OpenID Connect（Okta、Entra ID、Auth0、Keycloak…）**、**飞书 / Lark**或**钉钉**。 |
| **重定向 URI** | 全部 | 只读，带复制按钮。请把这个确切的值注册到您的提供方。 |
| **查看配置指南** | 全部 | 在侧边面板中打开该提供方的专属步骤。 |
| **Issuer URL** | OpenID Connect | IdP 的 issuer，以 `https://` 开头。 |
| **区域** | 飞书 / Lark | **飞书（feishu.cn）**或 **Lark（larksuite.com）**。 |
| **Client ID** / **App ID** / **Client ID（原 AppKey）** | 全部 | 提供方给出的应用 ID。 |
| **Client Secret** / **App Secret** / **Client Secret（原 AppSecret）** | 全部 | 应用的密钥。保存后不会再显示；此时该字段提示“已保存。留空则保持不变。”。 |
| **租户 Key（tenant\_key）**（可选） | 飞书 / Lark | 您的飞书租户 Key。留空时，Alforse 会用 App Secret 从飞书读取。 |
| **CorpId** | 钉钉 | 您的钉钉组织的 CorpId。必填。 |

选择**连接**（已有连接则为**保存更改**）。Alforse 会在保存前与提供方核对设置，并提示“单点登录已保存”。

### 重定向 URI

每个提供方应用都必须使用这同一个重定向（回调）URI：

```text theme={null}
https://api.alforse.com/api/web/auth/v1/sso/oauth/callback
```

它对每家公司、每个提供方都相同。请从页面上复制，不要手动输入。

## 设置您的提供方

**飞书 / Lark**

**在飞书开放平台中**（[https://open.feishu.cn；Lark](https://open.feishu.cn；Lark) 为 [https://open.larksuite.com）：](https://open.larksuite.com）：)

1. 创建**企业自建应用**。
2. 在**凭证与基础信息**中，复制 **App ID** 和 **App Secret**。
3. 在**安全设置 → 重定向 URL**中，添加上面显示的重定向 URI。
4. 在**权限管理**中，开通：
   * 读取用户基本信息的权限（必需）；
   * 读取用户企业邮箱的权限，以便按邮箱匹配人员；
   * 读取企业信息的权限，如果您在 Alforse 中将**租户 Key**留空。
5. 创建版本，并发布给需要登录的人员。

**在 Alforse 中：**选择**飞书 / Lark**，选取与您所用平台一致的**区域**，粘贴 **App ID** 和 **App Secret**，可选地粘贴**租户 Key**，然后选择**连接**。

* 只有您的飞书租户签发的**企业邮箱**才算已验证。用户在自己资料中填写的邮箱地址绝不会用于匹配。
* 没有企业邮箱的人员，用一个[登录链接](#sign-in-links)关联一次即可。

**钉钉**

**在钉钉开发者后台中**（[https://open-dev.dingtalk.com）：](https://open-dev.dingtalk.com）：)

1. 在**应用开发**下，创建**企业内部应用**。
2. 在**凭证与基础信息**中，复制 **Client ID（原 AppKey）**和 **Client Secret（原 AppSecret）**。
3. 在**安全设置 → 重定向 URL（回调域名）**中，添加上面显示的重定向 URI。
4. 在**权限管理**中，开通个人信息读权限（`Contact.User.Read`）。
5. 在开发者后台首页复制您组织的 **CorpId**。

**在 Alforse 中：**选择**钉钉**，粘贴 **Client ID（原 AppKey）**、**Client Secret（原 AppSecret）**和 **CorpId**，然后选择**连接**。

> [!NOTE]
>
> 钉钉邮箱由用户自行维护，因此 Alforse 绝不会用它们进行匹配。请为每个人用一个[登录链接](#sign-in-links)关联一次；此后他们即可直接用钉钉登录。

**OpenID Connect**

**在您的身份提供商中**（Okta、Entra ID、Auth0、Keycloak 或任意 OIDC 提供方）：

1. 创建 OpenID Connect **Web 应用**。在 Okta 中：**Applications → Create App Integration → OIDC – Web Application**。
2. 将授权类型设为 **Authorization Code**，将登录重定向 URI 设为上面显示的重定向 URI。
3. 分配可以登录的人员或群组。
4. 复制 **Client ID** 和 **Client Secret**。
5. 找到 **Issuer URL**。在 Okta 中：**Security → API → Authorization Servers → Issuer URI**，例如 `https://your-org.okta.com/oauth2/default`。

**在 Alforse 中：**选择 **OpenID Connect**，输入 **Issuer URL**、**Client ID** 和 **Client Secret**，然后选择**连接**。

提供方一侧的要求：

* issuer 必须是不含凭据、查询参数和片段的 `https://` URL，并且必须与其发现文档中的 `issuer` 完全一致。
* 发现文档中的每个端点都必须是位于 issuer 同一主机上的 `https://` 地址。
* ID 令牌必须使用 **RS256** 签名。
* Alforse 请求的范围是 `openid email profile`，并使用 PKCE。ID 令牌必须携带 `email` 和 `email_verified: true`，才能按邮箱匹配人员。

## 验证邮箱域名

连接保存后，在**邮箱域名**卡片中添加员工用于登录的每个域名：在**添加域名**下输入域名（例如 `example.com`），然后选择**添加**。新域名为**待验证**状态，并显示需要发布的 TXT 记录：

| 字段 | 值 |
| - | - |
| **主机记录** | `_alforse-challenge.example.com` |
| **记录值** | `alforse-domain-verification=<your unique token>` |

通过您的 DNS 提供商发布该记录，然后选择**验证**。成功后，域名显示**已验证**，页面提示“域名已验证”。规则与 SAML 相同：参见[验证域名](https://docs.alforse.com/zh/docs/reference/single-sign-on.md#verifying-a-domain)。

## 登录如何匹配到人员

人员在 ERP 登录页输入工作邮箱并选择**继续**。已验证域名下的邮箱会把他们导向您的提供方。他们返回后，Alforse 只在贵公司范围内查找，顺序如下：

1. **已关联账号。** 提供方账号已关联到某个人：该人被登录。
2. **已验证邮箱。** 提供方报告了属于您某个已验证域名的已验证邮箱。匹配的启用成员会被登录；匹配的待处理邀请会被接受并应用其角色。随后账号被关联。
3. **登录链接。** 该人打开了您签发的一次性登录链接。账号会关联到该链接所针对的成员或邀请。

其他任何人都会被拒绝，且不会创建账户。对于飞书 / Lark 和钉钉，Alforse 还会检查提供方账号是否属于您连接中保存的租户 Key 或 CorpId。

NOTE

**每人每个提供方一个账号**

每个人在每个提供方下只能有一个已关联账号。要关联另一个账号，请先在**已关联账号**下撤销现有账号。

## 登录链接

用**登录链接**卡片来关联那些提供方无法证明其邮箱的人员：所有钉钉用户，以及没有企业邮箱的飞书用户。

1. 选择一个**待接受的邀请**，或输入**或现有成员的邮箱**。
2. 选择**创建链接**。
3. 从**登录链接已创建**对话框中复制链接，并自行发送给对方。

链接形如 `https://api.alforse.com/api/web/auth/v1/sso/oauth/invite?token=…`。对方打开它，用提供方登录，账号即被关联；此后他们正常登录即可。

* **只显示一次。** 链接只在该对话框中显示。如果丢失，请撤销它并创建新链接。
* **只能使用一次，7 天内有效。** 表格显示每个链接的**对象**、**状态**（**可用**、**已使用**、**已撤销**或**已过期**）和**过期时间**。选择**撤销**可取消可用的链接。
* **需要已验证域名。** 邀请或成员的邮箱必须位于该连接的已验证域名下。
* 登录链接适用于 OpenID Connect、飞书 / Lark 和钉钉连接，不适用于 SAML。

## 已关联账号

**已关联账号**卡片列出每个关联，包含**员工**、**提供方账号**、**关联方式**（**已验证邮箱**或**登录链接**）和**关联时间**。选择**撤销**可移除关联。该人的 Alforse 账户会保留；下次登录时，他们会再次按已验证邮箱匹配，或需要新的登录链接。

## 强制单点登录

开启**强制单点登录**，可使您的提供方成为已验证域名下人员唯一的登录入口。此后，魔法链接等其他登录方式对他们会被拒绝。该开关在至少一个域名通过验证后才会生效，因此您可以在强制之前先测试登录。

## 从 SAML 切换

如果贵公司已经在使用 [SAML](https://docs.alforse.com/zh/docs/reference/single-sign-on.md)，卡片会提示“贵公司目前使用 SAML 登录。在此保存其他提供方会替换它。”

* 保存 OpenID Connect、飞书 / Lark 或钉钉连接，会从您的连接中移除 SAML 设置（IdP 元数据）。SAML 登录随即停止。
* 您的邮箱域名及其验证状态保留，**强制单点登录**也保留。
* 只要有非 SAML 连接处于启用状态，**设置 → 安全**中的 SAML 卡片就无法保存。请先在本页停用该连接。

## 停用

在**身份提供方**卡片中选择**停用**，并在**停用单点登录**中确认。您域名下的人员将不再通过您的提供方登录。域名验证会被移除；已关联账号会保留，因此如果您之后重新连接同一个提供方，只需重新验证域名。

## 故障排除

| 现象或消息 | 原因 | 解决办法 |
| - | - | - |
| “Administrators only”（仅限管理员） | 您没有修改公司设置的权限。 | 请管理员授予 `settings` 更新权限。 |
| “Single sign-on isn't in your plan”（您的套餐不含单点登录） | 您的订阅不含单点登录。 | 升级套餐。 |
| “The issuer URL must start with [https://.”（Issuer](https://.”（Issuer) URL 必须以 https\:// 开头。） | issuer 不是 https URL、含有查询参数或片段，或与发现文档中的 `issuer` 不一致。 | 按发现文档中的写法原样输入 issuer。 |
| “The identity provider couldn't be reached. Check the issuer URL.”（无法连接身份提供方，请检查 Issuer URL。） | 无法获取发现文档，或其端点不是 issuer 主机上的 https 地址，或 IdP 没有用 RS256 签名 ID 令牌。 | 检查 Issuer URL 以及 IdP 的签名算法。 |
| “Enter a valid client secret.”（请填写有效的 Client Secret。） | 缺少密钥，或飞书拒绝了 App ID / App Secret。 | 重新复制 ID 和密钥，并检查**区域**。 |
| “Enter the CorpId.”（请填写 CorpId。） | 钉钉缺少 CorpId，或飞书既没有租户 Key 又读不到租户。 | 输入 CorpId，或粘贴飞书租户 Key，或开通读取企业信息的权限。 |
| “Verify this email's domain first.”（请先验证该邮箱的域名。） | 您为域名尚未验证的邮箱创建了登录链接。 | 先验证域名，再创建链接。 |
| “No invitation or member uses this email.”（没有使用此邮箱的邀请或成员。） | 该邮箱没有匹配到唯一的启用成员。 | 先邀请该人，再选择该邀请。 |
| “The TXT record wasn't found yet. Try again in a few minutes.”（暂未找到 TXT 记录，请几分钟后再试。） | DNS 尚未生效，或记录位于错误的主机。 | 检查主机名后重试。 |
| “The configuration changed in the meantime. It has been reloaded — check and try again.”（配置已被他人修改，已重新加载，请检查后重试。） | 另一位管理员保存了更改。 | 查看重新加载后的页面，再重复您的更改。 |
| 登录时：“Single sign-on succeeded, but this account is not yet linked to your company. Ask your administrator for a sign-in link.”（单点登录成功，但此账号尚未关联到贵公司。请向管理员索取登录链接。） | 提供方没有给出已验证邮箱（钉钉始终如此）。 | 为该人创建登录链接。 |
| 登录时：“Single sign-on succeeded but no invite exists for `jane@example.com`. Contact your administrator.”（单点登录成功，但不存在 `jane@example.com` 的邀请。请联系管理员。） | 邮箱已验证，但此人既不是成员也未被邀请。 | 邀请该人，然后请其再次登录。 |
| 登录时：“Single sign-on rejected: this email domain is not registered for your company's single sign-on connection.”（单点登录被拒绝：此邮箱域名未在贵公司的单点登录连接中注册。） | 提供方的邮箱位于您尚未验证的域名下。 | 验证该域名。 |
| 登录时：“This account belongs to another organization than your company's single sign-on connection.”（此账号所属的组织与贵公司的单点登录连接不同。） | 飞书租户、钉钉 CorpId 或 OIDC issuer 与连接不匹配。 | 该人必须使用您组织内的账号；检查已保存的租户 Key 或 CorpId。 |
| 登录时：“This sign-in link is unknown, already used, revoked or expired. Ask your administrator for a new one.”（此登录链接未知、已被使用、已撤销或已过期。请向管理员索取新链接。） | 链接已被使用、已被撤销，或已超过 7 天。 | 创建新链接。 |
| 登录时：“Another account of this identity provider is already linked to this user. Contact your administrator.”（此身份提供方的另一个账号已关联到该用户。请联系管理员。） | 该人已经关联了另一个提供方账号。 | 在**已关联账号**下撤销旧的关联。 |

## 相关内容

**使用 SAML 的单点登录**

在设置 → 安全中连接 SAML 2.0 身份提供商。

[Open](https://docs.alforse.com/zh/docs/reference/single-sign-on.md)

**人员**

邀请将要登录的人员。

[Open](https://docs.alforse.com/zh/docs/reference/people.md)

**双因素认证**

Alforse 为其他登录方式提供的第二重验证。

[Open](https://docs.alforse.com/zh/docs/reference/two-factor.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.