> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/on-premises/zh-tw/she-ding/overleaf-toolkit/authentication/saml-authentication.md).

# SAML 驗證

此功能由 [yu-i-i/overleaf-cep](https://github.com/yu-i-i/overleaf-cep)。這裡提供一些文件供您的設定參考。

### 設定

在內部，Overleaf SAML 模組使用 [passport-saml](https://github.com/node-saml/passport-saml) 函式庫，以下大多數設定選項都會傳遞給 `passport-saml`。如果你在設定 SAML 時遇到問題，值得閱讀 … 的 README。 `passport-saml` 了解它預期的設定方式。

環境變數 `EXTERNAL_AUTH` 是啟用 SAML 驗證模組所必需的。此環境變數指定會啟用哪些外部驗證方式。此變數的值是一個清單。如果清單包含 `saml` 則會啟用 SAML 驗證。

例如： `EXTERNAL_AUTH=ldap saml`

當使用 SAML 驗證方法時，使用者會重新導向至身分提供者（IdP）驗證網站。如果 IdP 成功驗證使用者，系統會在 Overleaf 使用者資料庫中查找一筆包含 `samlIdentifiers` 欄位，其結構如下：

```json
samlIdentifiers: [
  {
    externalUserId: "...",
    providerId: "1",
    userIdAttribute: "..."
  }
]
```

此 `externalUserId` 必須符合由以下屬性指定的值： `userIdAttribute` 於 IdP 伺服器回傳的使用者設定檔中。

如果找不到相符的記錄，系統會在資料庫中搜尋其主要電子郵件地址與 IdP 使用者設定檔中的電子郵件相符的使用者：

* 如果找到這樣的使用者，則 `hashedPassword` 欄位會被刪除以停用本機驗證，並且 `samlIdentifiers` 欄位會被加入。
* 如果找不到相符的使用者，則會使用電子郵件地址和 `samlIdentifiers` 來自 IdP 設定檔的資料建立新使用者。

**注意：** 目前只支援一個 SAML IdP。 `providerId` 欄位在 `samlIdentifiers` 中被固定為 `'1'`.

#### 環境變數

* `OVERLEAF_SAML_IDENTITY_SERVICE_NAME`
  * 身分服務的顯示名稱，用於登入頁面（預設： `使用 SAML IdP 登入`).
* `OVERLEAF_SAML_USER_ID_FIELD`
  * 此屬性的值將由 Overleaf 用作外部使用者 ID，預設為 `nameID`.
* `OVERLEAF_SAML_EMAIL_FIELD`
  * 使用者設定檔中 Email 欄位的名稱，預設為 `nameID`.
* `OVERLEAF_SAML_FIRST_NAME_FIELD`
  * 使用者設定檔中 firstName 欄位的名稱，預設為 `givenName`.
* `OVERLEAF_SAML_LAST_NAME_FIELD`
  * 使用者設定檔中 lastName 欄位的名稱，預設為 `lastName`
* `OVERLEAF_SAML_UPDATE_USER_DETAILS_ON_LOGIN`
  * 若設為 `true`，登入時會更新使用者的 `first_name` 以及 `last_name` 登入時更新欄位，並關閉使用者詳細資料表單於 `/user/settings` 頁面。
* `OVERLEAF_SAML_ENTRYPOINT` **（必填）**
  * SAML 身分服務的入口 URL。
    * 範例： `https://idp.example.com/simplesaml/saml2/idp/SSOService.php`
    * Azure 範例： `https://login.microsoftonline.com/8b26b46a-6dd3-45c7-a104-f883f4db1f6b/saml2`
* `OVERLEAF_SAML_ISSUER` **（必填）**
  * 發行者名稱。
* `OVERLEAF_SAML_AUDIENCE`
  * 預期的 saml 回應 Audience，預設為以下值： `OVERLEAF_SAML_ISSUER`.
* `OVERLEAF_SAML_IDP_CERT` **（必填）**
  * 包含身分提供者公開憑證的檔案路徑，用於驗證傳入 SAML 回應的簽章。如果身分提供者有多個有效的簽署憑證，也可以是一個包含憑證路徑的 JSON 陣列。
    * 範例（單一憑證）： `/var/lib/overleaf/certs/idp_cert.pem`
    * 範例（多個憑證）： `["var/lib/overleaf/certs/idp_cert.pem", "/var/lib/overleaf/certs/idp_cert_old.pem"]`
* `OVERLEAF_SAML_PUBLIC_CERT`
  * 包含公用簽署憑證的檔案路徑，該憑證會嵌入驗證請求中，以便 IdP 驗證傳入 SAML Request 的簽章。在設定 [中繼資料端點](https://github.com/yu-i-i/overleaf-cep/wiki/Extended-CE:-SAML-Authentication#metadata-for-the-identity-provider) 時，當策略設定為使用 `OVERLEAF_SAML_PRIVATE_KEY`。可提供一個包含憑證路徑的 JSON 陣列，以支援憑證輪替。當提供憑證陣列時，陣列中的第一個項目應與目前的 `OVERLEAF_SAML_PRIVATE_KEY`。陣列中的其他項目可用來在變更之前，向 IdP 發布即將啟用的憑證。 `OVERLEAF_SAML_PRIVATE_KEY`.
* `OVERLEAF_SAML_PRIVATE_KEY`
  * 包含與以下項目相符的 PEM 格式私密金鑰的檔案路徑： `OVERLEAF_SAML_PUBLIC_CERT` 用來對 passport-saml 傳送的驗證請求進行簽署。
* `OVERLEAF_SAML_DECRYPTION_CERT`
  * 包含公用憑證的檔案路徑，用於 [中繼資料端點](https://github.com/yu-i-i/overleaf-cep/wiki/Extended-CE:-SAML-Authentication#metadata-for-the-identity-provider).
* `OVERLEAF_SAML_DECRYPTION_PVK`
  * 包含與以下項目相符的私密金鑰的檔案路徑： `OVERLEAF_SAML_DECRYPTION_CERT` 將用於嘗試解密收到的任何加密 Assertion。
* `OVERLEAF_SAML_SIGNATURE_ALGORITHM`
  * 可選擇設定用於簽署請求的簽章演算法，有效值為 'sha1'（預設）、'sha256'（較佳）、'sha512'（最安全，請確認你的 IdP 是否支援）。
* `OVERLEAF_SAML_ADDITIONAL_PARAMS`
  * 要加入所有請求的額外查詢參數之 JSON 字典。
* `OVERLEAF_SAML_ADDITIONAL_AUTHORIZE_PARAMS`
  * 要加入到 'authorize' 請求的額外查詢參數之 JSON 字典。
    * 範例： `{"some_key": "some_value"}`
* `OVERLEAF_SAML_IDENTIFIER_FORMAT`
  * 要向身分提供者請求的名稱識別子格式（預設： `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`）。如果使用 `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent`，請確保 `OVERLEAF_SAML_EMAIL_FIELD` 已定義環境變數。如果 `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` 是必需的，你還必須定義 `OVERLEAF_SAML_ID_FIELD` 環境變數，例如可設為使用者的電子郵件地址。
* `OVERLEAF_SAML_ACCEPTED_CLOCK_SKEW_MS`
  * 在檢查 OnBefore 與 NotOnOrAfter assertion 條件有效性時間戳記時，客戶端與伺服器之間可接受的偏差毫秒數。設為 -1 將完全停用這些條件的檢查。預設為 0。
* `OVERLEAF_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX`
  * `AttributeConsumingServiceIndex` 要加入 AuthnRequest 的屬性，用以指示 IdP 要將哪個屬性集合附加到回應（[link](http://blog.aniljohn.com/2014/01/data-minimization-front-channel-saml-attribute-requests.html)).
* `OVERLEAF_SAML_AUTHN_CONTEXT`
  * 用於請求驗證內容的名稱識別子格式值之 JSON 陣列。預設： `["urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"]`.
* `OVERLEAF_SAML_FORCE_AUTHN`
  * 如果 `true`，服務提供者發出的初始 SAML 請求會指定 IdP 即使使用者已有有效工作階段，也應強制重新驗證使用者。
* `OVERLEAF_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT`
  * 如果 `true`，不要請求特定的驗證內容。例如，你可以將這個設為 `true` 以允許其他內容，例如無密碼登入（`urn:oasis:names:tc:SAML:2.0:ac:classes:X509`）。是否支援其他內容取決於你的 IdP。
* `OVERLEAF_SAML_AUTHN_REQUEST_BINDING`
  * 若設為 `HTTP-POST`，則會透過 HTTP POST 綁定向 IdP 請求驗證，否則預設為 HTTP-Redirect。
* `OVERLEAF_SAML_VALIDATE_IN_RESPONSE_TO`
  * 如果 `always`，則會從傳入的 SAML 回應驗證 InResponseTo。
  * 如果 `絕不要`，則不會驗證 InResponseTo（預設）。
  * 如果 `ifPresent`，則只有在傳入的 SAML 回應中存在時才會驗證 InResponseTo。
* `OVERLEAF_SAML_WANT_ASSERTIONS_SIGNED` 以及 `OVERLEAF_SAML_WANT_AUTHN_RESPONSE_SIGNED`
  * 當設為 `true` （預設），Overleaf 預期 SAML Assertions，以及整個 SAML Authentication Response，皆由 IdP 簽署。當這兩個選項都 `false`，則至少必須有一個 assertion 或回應被簽署。
* `OVERLEAF_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS`
  * 定義為 SAML 請求產生的 Request ID 在 SAML 回應的以下欄位中出現時將失效的到期時間： `InResponseTo` 欄位。預設：28800000（8 小時）。
* `OVERLEAF_SAML_LOGOUT_URL`
  * 處理登出請求時所呼叫的基底位址（預設： `entryPoint`).
    * 範例： `https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php`
* `OVERLEAF_SAML_ADDITIONAL_LOGOUT_PARAMS`
  * 要加入到 'logout' 請求的額外查詢參數之 JSON 字典。
* `OVERLEAF_SAML_IS_ADMIN_FIELD` 以及 `OVERLEAF_SAML_IS_ADMIN_FIELD_VALUE`
  * 當這兩個環境變數都設定時，登入程序會更新 `user.isAdmin = true` 如果 SAML IdP 回傳的設定檔包含由以下指定的屬性 `OVERLEAF_SAML_IS_ADMIN_FIELD` 且其值符合 `OVERLEAF_SAML_IS_ADMIN_FIELD_VALUE` 或是包含下列值的陣列： `OVERLEAF_SAML_IS_ADMIN_FIELD_VALUE`，否則 `user.isAdmin` 會設為 `false`。如果這兩個變數其中之一未設定，則管理員狀態只會設定為 `true` ，於 Launchpad 建立管理員使用者時。

**身分提供者的中繼資料**

目前版本的 Overleaf CE 包含一個用於擷取服務提供者中繼資料的端點： `http://my-overleaf-instance.com/saml/meta`

必須將身分提供者設定為將 Overleaf 伺服器識別為「服務提供者」。請參閱你的 SAML 伺服器文件，以了解如何進行設定。

以下是一個適當的服務提供者中繼資料範例：

<details>

<summary><strong>ol-meta.xml</strong></summary>

```
<?xml version="1.0"?>
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
                  xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
                  entityID="MyOverleaf"
                  ID="_b508c83b7dda452f5b269383fb391107116f8f57">
  <SPSSODescriptor protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol" AuthnRequestsSigned="true" WantAssertionsSigned="true">
    <KeyDescriptor use="signing">
      <ds:KeyInfo>
        <ds:X509Data>
          <ds:X509Certificate>MII...
[已略過]
</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </KeyDescriptor>
    <KeyDescriptor use="encryption">
      <ds:KeyInfo>
        <ds:X509Data>
          <ds:X509Certificate>MII...
[已略過]
</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
      <EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
      <EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes128-gcm"/>
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes256-cbc"/>
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
    </KeyDescriptor>
    <SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                         Location="https://my-overleaf-instance.com/saml/logout/callback"/>
    <NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</NameIDFormat>
    <AssertionConsumerService index="1"
                              isDefault="true"
                              Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                              Location="https://my-overleaf-instance.com/saml/login/callback"/>
  </SPSSODescriptor>
</EntityDescriptor>

```

</details>

請注意這些憑證， `AssertionConsumerService.Location`, `SingleLogoutService.Location` 以及 `EntityDescriptor.entityID` 並在你的 IdP 設定中適當設定，或將中繼資料檔傳送給 IdP 管理員。

<details>

<summary><strong>範例 variables.env 檔案（最小）</strong></summary>

<pre><code>OVERLEAF_APP_NAME="Our Overleaf Instance"

ENABLED_LINKED_FILE_TYPES=project_file,project_output_file,url

# 啟用使用 ImageMagick 生成縮圖
ENABLE_CONVERSIONS=true

# 停用電子郵件確認需求
EMAIL_CONFIRMATION_DISABLED=true

## Nginx
# NGINX_WORKER_PROCESSES=4
# NGINX_WORKER_CONNECTIONS=768

## 透過 nginx-proxy 設定 TLS
# OVERLEAF_BEHIND_PROXY=true
# OVERLEAF_SECURE_COOKIE=true

OVERLEAF_SITE_URL=http://my-overleaf-instance.com
OVERLEAF_NAV_TITLE=Our Overleaf Instance
# OVERLEAF_HEADER_IMAGE_URL=http://somewhere.com/mylogo.png
OVERLEAF_ADMIN_EMAIL=support@example.com

OVERLEAF_LEFT_FOOTER=[{"text": "聯絡您的支援團隊", "url": "mailto:support@example.com"}]
OVERLEAF_RIGHT_FOOTER=[{"text":"哈囉，我在右側", "url":"https://github.com/yu-i-i/overleaf-cep"}]

OVERLEAF_EMAIL_FROM_ADDRESS=team@example.com
OVERLEAF_EMAIL_SMTP_HOST=smtp.example.com
OVERLEAF_EMAIL_SMTP_PORT=587
OVERLEAF_EMAIL_SMTP_SECURE=false
# OVERLEAF_EMAIL_SMTP_USER=
# OVERLEAF_EMAIL_SMTP_PASS=
# OVERLEAF_EMAIL_SMTP_NAME=
OVERLEAF_EMAIL_SMTP_LOGGER=false
OVERLEAF_EMAIL_SMTP_TLS_REJECT_UNAUTH=true
OVERLEAF_EMAIL_SMTP_IGNORE_TLS=false
OVERLEAF_CUSTOM_EMAIL_FOOTER=此系統由 x 部門營運

OVERLEAF_PROXY_LEARN=true
NAV_HIDE_POWERED_BY=true

#################
##     SAML    ##
#################

EXTERNAL_AUTH=saml
OVERLEAF_SAML_ISSUER=MyOverleaf
OVERLEAF_SAML_IDENTITY_SERVICE_NAME='使用 SAML 提供者登入'
OVERLEAF_SAML_EMAIL_FIELD=Email
OVERLEAF_SAML_FIRST_NAME_FIELD=DisplayName
OVERLEAF_SAML_LAST_NAME_FIELD=DisplayName
OVERLEAF_SAML_ENTRYPOINT=http://localhost:18000/login/saml/authorize/admin/SAML_Overleaf
<strong>OVERLEAF_SAML_IDP_CERT=/var/lib/overleaf/certs/idp_cert.pem
</strong>OVERLEAF_SAML_SIGNATURE_ALGORITHM=
</code></pre>

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/on-premises/zh-tw/she-ding/overleaf-toolkit/authentication/saml-authentication.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
