> ## 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、釘釘，或任何 OpenID Connect 身分提供者（例如 Okta、Entra ID、Auth0 或 Keycloak）登入 Alforse。

除了 [SAML 2.0](https://docs.alforse.com/zh-Hant/docs/reference/single-sign-on.md) 之外，Alforse 也能把登入交給貴公司的飛書／Lark 或釘釘組織，或任何 OpenID Connect（OIDC）身分提供者。公司管理員只需在**單一登入**（Single Sign-On）頁面設定一次；此後，輸入已驗證網域工作電子郵件的人會被導向該提供者登入。

## 概念

* **每家公司一個連線。**你的公司只有一個單一登入連線，採用一種通訊協定：**OpenID Connect**、**Feishu / Lark**、**DingTalk** 或 SAML。在此頁面儲存前三者之一，會取代既有的 SAML 連線（請參閱[從 SAML 切換](#switching-from-saml)）。
* **已驗證的網域決定登入導向。**只有你以 DNS 記錄證明擁有的電子郵件網域，才會把人導向提供者。
* **先邀請再登入。**單一登入本身絕不會建立帳號。一個人只能以現有成員的身分進入，或接受貴公司的待處理邀請後進入。
* **已連結的帳號。**第一次成功登入時，會把提供者帳號連結到 Alforse 的人員。之後的登入直接使用該連結。

## 開始之前

* **權限。**你需要變更公司設定的權限（`settings` update）。沒有這項權限時，頁面會顯示 **"Administrators only"**（僅限管理員）。
* **可用性。**若你的訂閱不包含單一登入，頁面會顯示 **"Single sign-on isn't in your plan"**（你的方案不含單一登入）。
* **提供者存取權。**你需要有權在身分提供者中建立應用程式：飛書／Lark 開放平台中的自建應用、釘釘開發者後台中的企業內部應用，或你的 IdP 中的 OIDC 網頁應用程式。
* **DNS 存取權。**你需要為每個電子郵件網域發布一筆 TXT 記錄。

## 開啟單一登入頁面

1. 登入 [https://app.alforse.com](https://app.alforse.com) 的 ERP。
2. 在同一個瀏覽器中開啟 **[https://api.alforse.com/identity](https://api.alforse.com/identity)**。

若頁面顯示 **"Sign in to continue"**（登入以繼續），請選取 **Sign in**（登入）、登入 ERP，然後再次開啟該網址。頁面頂端的 **EN** / **中文** 按鈕可在英文與簡體中文之間切換頁面語言。標題旁的狀態在連線建立後顯示 **Active**（啟用中），否則顯示 **Not configured**（未設定）。

頁面有五張卡片：**Identity Provider**（身分提供者）、**Require single sign-on**（要求單一登入）、**Email Domains**（電子郵件網域）、**Sign-in Links**（登入連結）與 **Linked Accounts**（已連結的帳號）。在你儲存連線之前，只會顯示 **Identity Provider**。

Alforse screenshot**api.alforse.com/identity 的單一登入頁面：身分提供者卡片，含 Provider 選單、Redirect URI 複製欄位與 Connect 按鈕**

所有提供者都從「身分提供者」卡片設定。

## 身分提供者卡片

| 欄位 | 顯示於 | 要輸入的內容 |
| - | - | - |
| **Provider** | 全部 | **OpenID Connect (Okta, Entra ID, Auth0, Keycloak…)**、**Feishu / Lark** 或 **DingTalk**。 |
| **Redirect URI** | 全部 | 唯讀，附複製按鈕。請把這個值原樣登錄到你的提供者。 |
| **View setup guide** | 全部 | 在側邊面板中開啟該提供者專屬的步驟。 |
| **Issuer URL** | OpenID Connect | 你的 IdP 的簽發者（issuer），以 `https://` 開頭。 |
| **Region** | Feishu / Lark | **Feishu (feishu.cn)** 或 **Lark (larksuite.com)**。 |
| **Client ID** / **App ID** / **Client ID (AppKey)** | 全部 | 提供者給予該應用程式的 ID。 |
| **Client secret** / **App Secret** / **Client Secret (AppSecret)** | 全部 | 該應用程式的密鑰。儲存後就不會再顯示；此時欄位會顯示 "Saved. Leave empty to keep it."（已儲存。留空即保留原值。） |
| **Tenant key**（選填） | Feishu / Lark | 你的飛書租戶金鑰。若留空，Alforse 會使用 App Secret 從飛書讀取。 |
| **CorpId** | DingTalk | 你的釘釘組織的 CorpId。必填。 |

選取 **Connect**（連線；既有連線則為 **Save changes**）。Alforse 會在儲存前先向提供者檢查這些設定，並以 "Single sign-on saved"（單一登入已儲存）確認。

### Redirect URI

每個提供者應用程式都必須使用這同一個重新導向（回呼）URI：

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

它對每家公司、每個提供者都相同。請從頁面複製，不要自行輸入。

## 設定你的提供者

**Feishu / Lark**

**在飛書開放平台**（[https://open.feishu.cn；Lark](https://open.feishu.cn；Lark) 則為 [https://open.larksuite.com）：](https://open.larksuite.com）：)

1. 建立**自建應用**（企業自建应用）。
2. 在 **Credentials & Basic Info**（憑證與基本資訊）下，複製 **App ID** 與 **App Secret**。
3. 在 **Security Settings → Redirect URLs**（安全設定 → 重新導向 URL）下，加入上方顯示的 Redirect URI。
4. 在 **Permissions**（權限）下，允許：
   * 讀取使用者基本資訊（必要）；
   * 讀取使用者的企業電子郵件，以便依電子郵件比對人員；
   * 讀取租戶資訊（若你要在 Alforse 中將 **Tenant key** 留空）。
5. 建立版本，並將應用發布給需要登入的人。

**在 Alforse 中：**選擇 **Feishu / Lark**，挑選與你所用平台相符的 **Region**，貼上 **App ID** 與 **App Secret**，視需要貼上 **Tenant key**，然後選取 **Connect**。

* 只有你的飛書租戶核發的**企業電子郵件**才算已驗證。使用者自行填入個人資料的地址，絕不會用於比對。
* 沒有企業電子郵件的人，需透過[登入連結](#sign-in-links)連結一次。

**DingTalk**

**在釘釘開發者後台**（[https://open-dev.dingtalk.com）：](https://open-dev.dingtalk.com）：)

1. 在 **App Development**（應用開發）下，建立**企業內部應用**（企业内部应用）。
2. 在 **Credentials & Basic Info** 下，複製 **Client ID (AppKey)** 與 **Client Secret (AppSecret)**。
3. 在 **Security Settings → Redirect URL** 下，加入上方顯示的 Redirect URI。
4. 在 **Permissions** 下，允許讀取使用者的個人資訊（`Contact.User.Read`）。
5. 從開發者後台首頁複製你組織的 **CorpId**。

**在 Alforse 中：**選擇 **DingTalk**，貼上 **Client ID (AppKey)**、**Client Secret (AppSecret)** 與 **CorpId**，然後選取 **Connect**。

> [!NOTE]
>
> 釘釘的電子郵件由使用者自行維護，因此 Alforse 絕不會用它們來比對。請以[登入連結](#sign-in-links)為每個人連結一次；之後他們就能直接用釘釘登入。

**OpenID Connect**

**在你的身分提供者中**（Okta、Entra ID、Auth0、Keycloak，或任何 OIDC 提供者）：

1. 建立 OpenID Connect **網頁應用程式**（web application）。在 Okta 中：**Applications → Create App Integration → OIDC – Web Application**。
2. 將授權類型（grant type）設為 **Authorization Code**，並將登入重新導向 URI 設為上方顯示的 Redirect 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**，然後選取 **Connect**。

提供者端的需求：

* 簽發者必須是不含認證資訊、查詢字串或片段的 `https://` URL，且必須與其探索文件（discovery document）中的 `issuer` 完全一致。
* 探索文件中的每個端點都必須是簽發者自己主機上的 `https://`。
* ID 權杖必須以 **RS256** 簽署。
* Alforse 請求 `openid email profile` 範圍並使用 PKCE。ID 權杖必須帶有 `email` 與 `email_verified: true`，才能依電子郵件比對人員。

## 驗證你的電子郵件網域

連線儲存之後，請在 **Email Domains** 卡片中加入你的成員用來登入的每個網域：在 **Add a domain**（新增網域）下輸入（例如 `example.com`），然後選取 **Add**（新增）。新網域的狀態為**待處理**（Pending），並會顯示要發布的 TXT 記錄：

| 欄位 | 值 |
| - | - |
| **Host** | `_alforse-challenge.example.com` |
| **Value** | `alforse-domain-verification=<your unique token>` |

請用你的 DNS 供應商發布該記錄，然後選取 **Verify**（驗證）。成功後網域會顯示**已驗證**（Verified），頁面並顯示 "Domain verified"（網域已驗證）。規則與 SAML 相同：請參閱[驗證網域](https://docs.alforse.com/zh-Hant/docs/reference/single-sign-on.md#verifying-a-domain)。

## 登入如何對應到人員

成員在 ERP 登入頁面輸入工作電子郵件並選取**繼續**（Continue）。位於已驗證網域的電子郵件會把他們導向你的提供者。他們回來之後，Alforse 只在貴公司範圍內，依下列順序尋找：

1. **已連結的帳號。**該提供者帳號已連結到某位人員：該人員即登入。
2. **已驗證的電子郵件。**提供者回報了一個位於你已驗證網域的已驗證電子郵件。符合的啟用中成員會登入；符合的待處理邀請會被接受並套用其角色。帳號隨後被連結。
3. **登入連結。**此人開啟了你核發的一次性登入連結。帳號會連結到該連結所對應的成員或邀請。

其他任何人都會被拒絕，也不會建立帳號。對於飛書／Lark 與釘釘，Alforse 還會檢查該提供者帳號是否屬於你連線上所儲存的租戶金鑰或 CorpId。

NOTE

**每人一個提供者帳號**

每個人在每個提供者下只能有一個已連結的帳號。若要連結不同的帳號，請先在 **Linked Accounts** 下撤銷現有的連結。

## 登入連結

使用 **Sign-in Links** 卡片來連結那些提供者無法證明其電子郵件的人：所有釘釘使用者，以及沒有企業電子郵件的飛書使用者。

1. 選擇一個**待處理的邀請**（Pending invitation），或輸入 **Or an existing member's email**（或現有成員的電子郵件）。
2. 選取 **Create link**（建立連結）。
3. 從 **Sign-in link created**（登入連結已建立）對話方塊複製連結，並自行傳送給該人。

連結的形式類似 `https://api.alforse.com/api/web/auth/v1/sso/oauth/invite?token=…`。對方開啟後以提供者登入，帳號就會被連結；此後他們即可正常登入。

* **只顯示一次。**連結只會顯示在該對話方塊中。若遺失，請撤銷並建立新的連結。
* **可用一次，有效 7 天。**表格會顯示每個連結的 **For**（對象）、**Status**（狀態：**Open**、**Used**、**Revoked** 或 **Expired**）與 **Expires**（到期）。選取 **Revoke**（撤銷）可取消尚未使用的連結。
* **需要已驗證的網域。**邀請或成員的電子郵件必須位於該連線已驗證的網域。
* 登入連結適用於 OpenID Connect、飛書／Lark 與釘釘連線，不適用於 SAML。

## 已連結的帳號

**Linked Accounts** 卡片會列出每個連結，欄位為 **Person**（人員）、**Provider account**（提供者帳號）、**Linked by**（連結方式：**Verified email** 或 **Sign-in link**）與 **Linked**（連結時間）。選取 **Revoke** 可移除連結。該人員的 Alforse 帳號仍會保留；下次登入時，他們會再次依已驗證的電子郵件比對，或需要新的登入連結。

## 要求單一登入

開啟 **Require single sign-on**，可讓你的提供者成為已驗證網域上成員唯一的進入方式。屆時對這些成員而言，其他登入方式（例如魔術連結）都會被拒絕。此開關要在至少有一個網域通過驗證後才會生效，因此你可以在強制執行之前先測試登入。

## 從 SAML 切換

若貴公司已在使用 [SAML](https://docs.alforse.com/zh-Hant/docs/reference/single-sign-on.md)，卡片會顯示 "Your company currently signs in with SAML. Saving another provider here replaces it."（貴公司目前以 SAML 登入。在此儲存其他提供者會取代它。）

* 儲存 OpenID Connect、飛書／Lark 或釘釘連線，會從你的連線中移除 SAML 設定（IdP 中繼資料）。SAML 登入會在那一刻停止。
* 你的電子郵件網域及其驗證會保留，**Require single sign-on** 也會保留。
* 當非 SAML 連線處於啟用狀態時，**設定 → 安全性**上的 SAML 卡片無法儲存。請先在此頁面停用該連線。

## 停用

在 **Identity Provider** 卡片中選取 **Deactivate**（停用），並在 **Deactivate single sign-on** 中確認。屆時你網域上的成員不再透過你的提供者登入。網域驗證會被移除；已連結的帳號會保留，因此日後若重新連線同一個提供者，只需重新驗證網域。

## 疑難排解

| 症狀或訊息 | 原因 | 解決方式 |
| - | - | - |
| "Administrators only" | 你沒有變更公司設定的權限。 | 向管理員申請 `settings` update。 |
| "Single sign-on isn't in your plan" | 你的訂閱不包含單一登入。 | 升級你的方案。 |
| "The issuer URL must start with https\://." | 簽發者不是 https URL、含有查詢字串或片段，或與探索文件中的 `issuer` 不同。 | 完全照探索文件所載的名稱輸入簽發者。 |
| "The identity provider couldn't be reached. Check the issuer URL." | 無法擷取探索文件，或其端點不是簽發者主機上的 https，或 IdP 未以 RS256 簽署 ID 權杖。 | 檢查簽發者 URL 與 IdP 的簽署演算法。 |
| "Enter a valid client secret." | 缺少密鑰，或飛書拒絕了 App ID / App Secret。 | 重新複製 ID 與密鑰，並檢查 **Region**。 |
| "Enter the CorpId." | 釘釘沒有 CorpId，或飛書既沒有租戶金鑰、也無法讀取租戶。 | 輸入 CorpId，或貼上飛書租戶金鑰，或授予租戶資訊權限。 |
| "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." | 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." | 電子郵件已驗證，但此人既不是成員也沒有受邀。 | 邀請他們，然後請他們再次登入。 |
| 登入時："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 簽發者與連線不符。 | 此人必須使用貴組織內的帳號；請檢查已儲存的租戶金鑰或 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." | 此人已經連結了另一個提供者帳號。 | 在 **Linked Accounts** 下撤銷舊的連結。 |

## 相關內容

**使用 SAML 的單一登入**

從設定 → 安全性連線 SAML 2.0 身分提供者。

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

**人員**

邀請將要登入的人。

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

**雙重驗證**

Alforse 為其他登入方式提供的自有第二重驗證。

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


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