> For the complete documentation index, see [llms.txt](https://ayakaleaf-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://ayakaleaf-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 時遇到問題，值得閱讀 `passport-saml` 的 README，以了解其預期的設定。

環境變數 `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 回應受眾，預設為 `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 請求的簽章。這在設定 [中繼資料端點](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` ，將用於嘗試解密收到的任何加密斷言。
* `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 斷言條件有效時間戳記時，客戶端與伺服器之間可接受的偏差時間（毫秒）。設為 -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 binding 向 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 斷言，以及整個 SAML 驗證回應，皆由 IdP 簽署。當兩個選項都 `false`，則斷言或回應至少其一必須簽署。
* `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...
[skipped]
</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </KeyDescriptor>
    <KeyDescriptor use="encryption">
      <ds:KeyInfo>
        <ds:X509Data>
          <ds:X509Certificate>MII...
[skipped]
</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="我們的 Overleaf 實例"

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=我們的 Overleaf 實例
# 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://ayakaleaf-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.
