> 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/vi/cau-hinh/overleaf-toolkit/authentication/saml-authentication.md).

# Xác thực SAML

Tính năng này được phát triển bởi [yu-i-i/overleaf-cep](https://github.com/yu-i-i/overleaf-cep). Ở đây chúng tôi cung cấp một số tài liệu cho cấu hình của bạn.

### Cấu hình

Về mặt nội bộ, mô-đun SAML của Overleaf sử dụng [passport-saml](https://github.com/node-saml/passport-saml) thư viện, hầu hết các tùy chọn cấu hình sau được chuyển tiếp tới `passport-saml`. Nếu bạn đang gặp vấn đề khi cấu hình SAML, nên đọc README của `passport-saml` để nắm được kiểu cấu hình mà nó mong đợi.

Biến môi trường `EXTERNAL_AUTH` là bắt buộc để bật mô-đun xác thực SAML. Biến môi trường này chỉ định những phương thức xác thực bên ngoài nào được kích hoạt. Giá trị của biến này là một danh sách. Nếu danh sách bao gồm `saml` thì xác thực SAML sẽ được kích hoạt.

Ví dụ: `EXTERNAL_AUTH=ldap saml`

Khi sử dụng phương thức xác thực SAML, người dùng sẽ được chuyển hướng đến trang xác thực của Nhà cung cấp Danh tính (IdP). Nếu IdP xác thực thành công người dùng, cơ sở dữ liệu người dùng của Overleaf sẽ được kiểm tra để tìm một bản ghi chứa một `samlIdentifiers` trường được cấu trúc như sau:

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

Trường `externalUserId` phải khớp với giá trị của thuộc tính được chỉ định bởi `userIdAttribute` trong hồ sơ người dùng do máy chủ IdP trả về.

Nếu không tìm thấy bản ghi khớp nào, cơ sở dữ liệu sẽ được tìm kiếm để tìm một người dùng có địa chỉ email chính khớp với email trong hồ sơ người dùng IdP:

* Nếu tìm thấy người dùng như vậy, `hashedPassword` trường này bị xóa để vô hiệu hóa xác thực cục bộ, và `samlIdentifiers` trường được thêm vào.
* Nếu không tìm thấy người dùng khớp, một người dùng mới sẽ được tạo với địa chỉ email và `samlIdentifiers` từ hồ sơ IdP.

**Lưu ý:** Hiện tại, chỉ hỗ trợ một IdP SAML duy nhất. Trường `providerId` trường trong `samlIdentifiers` được cố định thành `'1'`.

#### Các biến môi trường

* `OVERLEAF_SAML_IDENTITY_SERVICE_NAME`
  * Tên hiển thị cho dịch vụ danh tính, được dùng trên trang đăng nhập (mặc định: `Đăng nhập bằng IdP SAML`).
* `OVERLEAF_SAML_USER_ID_FIELD`
  * Giá trị của thuộc tính này sẽ được Overleaf dùng làm ID người dùng bên ngoài, mặc định là `nameID`.
* `OVERLEAF_SAML_EMAIL_FIELD`
  * Tên của trường Email trong hồ sơ người dùng, mặc định là `nameID`.
* `OVERLEAF_SAML_FIRST_NAME_FIELD`
  * Tên của trường firstName trong hồ sơ người dùng, mặc định là `givenName`.
* `OVERLEAF_SAML_LAST_NAME_FIELD`
  * Tên của trường lastName trong hồ sơ người dùng, mặc định là `lastName`
* `OVERLEAF_SAML_UPDATE_USER_DETAILS_ON_LOGIN`
  * Nếu được đặt thành `true`, cập nhật người dùng `first_name` và `last_name` trường khi đăng nhập, và tắt biểu mẫu thông tin người dùng trên `/user/settings` trang.
* `OVERLEAF_SAML_ENTRYPOINT` **(bắt buộc)**
  * URL điểm vào cho dịch vụ danh tính SAML.
    * Ví dụ: `https://idp.example.com/simplesaml/saml2/idp/SSOService.php`
    * Ví dụ Azure: `https://login.microsoftonline.com/8b26b46a-6dd3-45c7-a104-f883f4db1f6b/saml2`
* `OVERLEAF_SAML_ISSUER` **(bắt buộc)**
  * Tên Issuer.
* `OVERLEAF_SAML_AUDIENCE`
  * Audience phản hồi SAML mong đợi, mặc định là giá trị của `OVERLEAF_SAML_ISSUER`.
* `OVERLEAF_SAML_IDP_CERT` **(bắt buộc)**
  * Đường dẫn đến tệp chứa chứng chỉ công khai của Nhà cung cấp Danh tính, được dùng để xác thực chữ ký của các phản hồi SAML gửi đến. Nếu Nhà cung cấp Danh tính có nhiều chứng chỉ ký hợp lệ, thì có thể dùng một mảng JSON các đường dẫn đến các chứng chỉ đó.
    * Ví dụ (một chứng chỉ): `/var/lib/overleaf/certs/idp_cert.pem`
    * Ví dụ (nhiều chứng chỉ): `["var/lib/overleaf/certs/idp_cert.pem", "/var/lib/overleaf/certs/idp_cert_old.pem"]`
* `OVERLEAF_SAML_PUBLIC_CERT`
  * Đường dẫn đến tệp chứa chứng chỉ ký công khai, được dùng để nhúng vào các yêu cầu xác thực để IdP có thể xác thực chữ ký của Yêu cầu SAML gửi đến. Bắt buộc khi thiết lập [điểm cuối metadata](https://github.com/yu-i-i/overleaf-cep/wiki/Extended-CE:-SAML-Authentication#metadata-for-the-identity-provider) khi chiến lược được cấu hình với một `OVERLEAF_SAML_PRIVATE_KEY`. Có thể cung cấp một mảng JSON gồm các đường dẫn đến chứng chỉ để hỗ trợ xoay vòng chứng chỉ. Khi cung cấp một mảng chứng chỉ, mục đầu tiên trong mảng phải khớp với chứng chỉ hiện tại `OVERLEAF_SAML_PRIVATE_KEY`. Các mục bổ sung trong mảng có thể được dùng để công bố các chứng chỉ sắp tới cho các IdP trước khi thay đổi `OVERLEAF_SAML_PRIVATE_KEY`.
* `OVERLEAF_SAML_PRIVATE_KEY`
  * Đường dẫn đến tệp chứa khóa riêng định dạng PEM khớp với `OVERLEAF_SAML_PUBLIC_CERT` được dùng để ký các yêu cầu xác thực do passport-saml gửi.
* `OVERLEAF_SAML_DECRYPTION_CERT`
  * Đường dẫn đến tệp chứa chứng chỉ công khai, được dùng cho [điểm cuối metadata](https://github.com/yu-i-i/overleaf-cep/wiki/Extended-CE:-SAML-Authentication#metadata-for-the-identity-provider).
* `OVERLEAF_SAML_DECRYPTION_PVK`
  * Đường dẫn đến tệp chứa khóa riêng khớp với `OVERLEAF_SAML_DECRYPTION_CERT` sẽ được dùng để cố gắng giải mã bất kỳ assertion được mã hóa nào nhận được.
* `OVERLEAF_SAML_SIGNATURE_ALGORITHM`
  * Tùy chọn đặt thuật toán chữ ký cho việc ký các yêu cầu, các giá trị hợp lệ là 'sha1' (mặc định), 'sha256' (ưu tiên), 'sha512' (an toàn nhất, hãy kiểm tra xem IdP của bạn có hỗ trợ hay không).
* `OVERLEAF_SAML_ADDITIONAL_PARAMS`
  * Từ điển JSON của các tham số truy vấn bổ sung để thêm vào tất cả các yêu cầu.
* `OVERLEAF_SAML_ADDITIONAL_AUTHORIZE_PARAMS`
  * Từ điển JSON của các tham số truy vấn bổ sung để thêm vào các yêu cầu 'authorize'.
    * Ví dụ: `{"some_key": "some_value"}`
* `OVERLEAF_SAML_IDENTIFIER_FORMAT`
  * Định dạng mã định danh tên để yêu cầu từ nhà cung cấp danh tính (mặc định: `urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress`). Nếu sử dụng `urn:oasis:names:tc:SAML:2.0:nameid-format:persistent`, hãy đảm bảo `OVERLEAF_SAML_EMAIL_FIELD` biến môi trường được xác định. Nếu `urn:oasis:names:tc:SAML:2.0:nameid-format:transient` được yêu cầu, bạn cũng phải định nghĩa `OVERLEAF_SAML_ID_FIELD` biến môi trường, ví dụ có thể đặt thành địa chỉ email của người dùng.
* `OVERLEAF_SAML_ACCEPTED_CLOCK_SKEW_MS`
  * Độ lệch tính bằng mili giây được chấp nhận giữa máy khách và máy chủ khi kiểm tra dấu thời gian hợp lệ của điều kiện assertion OnBefore và NotOnOrAfter. Đặt thành -1 sẽ vô hiệu hóa hoàn toàn việc kiểm tra các điều kiện này. Mặc định là 0.
* `OVERLEAF_SAML_ATTRIBUTE_CONSUMING_SERVICE_INDEX`
  * `AttributeConsumingServiceIndex` thuộc tính để thêm vào AuthnRequest nhằm hướng dẫn IdP tập thuộc tính nào cần đính kèm vào phản hồi ([liên kết](http://blog.aniljohn.com/2014/01/data-minimization-front-channel-saml-attribute-requests.html)).
* `OVERLEAF_SAML_AUTHN_CONTEXT`
  * Mảng JSON các giá trị định dạng mã định danh tên để yêu cầu ngữ cảnh xác thực. Mặc định: `["urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"]`.
* `OVERLEAF_SAML_FORCE_AUTHN`
  * Nếu `true`, yêu cầu SAML ban đầu từ nhà cung cấp dịch vụ chỉ định rằng IdP phải buộc xác thực lại người dùng, ngay cả khi họ có một phiên hợp lệ.
* `OVERLEAF_SAML_DISABLE_REQUESTED_AUTHN_CONTEXT`
  * Nếu `true`, không yêu cầu ngữ cảnh xác thực cụ thể. Ví dụ, bạn có thể đặt cái này thành `true` để cho phép các ngữ cảnh bổ sung như đăng nhập không mật khẩu (`urn:oasis:names:tc:SAML:2.0:ac:classes:X509`). Hỗ trợ cho các ngữ cảnh bổ sung phụ thuộc vào IdP của bạn.
* `OVERLEAF_SAML_AUTHN_REQUEST_BINDING`
  * Nếu được đặt thành `HTTP-POST`, sẽ yêu cầu xác thực từ IdP qua ràng buộc HTTP POST, nếu không thì mặc định là HTTP-Redirect.
* `OVERLEAF_SAML_VALIDATE_IN_RESPONSE_TO`
  * Nếu `always`, thì InResponseTo sẽ được xác thực từ các phản hồi SAML đến.
  * Nếu `không bao giờ`, thì InResponseTo sẽ không được xác thực (mặc định).
  * Nếu `ifPresent`, thì InResponseTo sẽ chỉ được xác thực nếu có trong phản hồi SAML đến.
* `OVERLEAF_SAML_WANT_ASSERTIONS_SIGNED` và `OVERLEAF_SAML_WANT_AUTHN_RESPONSE_SIGNED`
  * Khi được đặt thành `true` (mặc định), Overleaf kỳ vọng các SAML Assertion, và tương ứng là toàn bộ Phản hồi Xác thực SAML, sẽ được IdP ký. Khi cả hai tùy chọn đều là `false`, thì ít nhất một trong các assertion hoặc phản hồi phải được ký.
* `OVERLEAF_SAML_REQUEST_ID_EXPIRATION_PERIOD_MS`
  * Xác định thời gian hết hạn khi một Request ID được tạo cho yêu cầu SAML sẽ không còn hợp lệ nếu xuất hiện trong phản hồi SAML ở `InResponseTo` trường này. Mặc định: 28800000 (8 giờ).
* `OVERLEAF_SAML_LOGOUT_URL`
  * địa chỉ cơ sở để gọi với các yêu cầu đăng xuất (mặc định: `entryPoint`).
    * Ví dụ: `https://idp.example.com/simplesaml/saml2/idp/SingleLogoutService.php`
* `OVERLEAF_SAML_ADDITIONAL_LOGOUT_PARAMS`
  * Từ điển JSON của các tham số truy vấn bổ sung để thêm vào các yêu cầu 'logout'.
* `OVERLEAF_SAML_IS_ADMIN_FIELD` và `OVERLEAF_SAML_IS_ADMIN_FIELD_VALUE`
  * Khi cả hai biến môi trường đều được đặt, quá trình đăng nhập sẽ cập nhật `user.isAdmin = true` nếu hồ sơ do IdP SAML trả về chứa thuộc tính được chỉ định bởi `OVERLEAF_SAML_IS_ADMIN_FIELD` và giá trị của nó hoặc khớp với `OVERLEAF_SAML_IS_ADMIN_FIELD_VALUE` hoặc là một mảng chứa `OVERLEAF_SAML_IS_ADMIN_FIELD_VALUE`, ngược lại `user.isAdmin` được đặt thành `false`. Nếu một trong hai biến này không được đặt, thì trạng thái quản trị viên chỉ được đặt thành `true` trong quá trình tạo người dùng quản trị trong Launchpad.

**Siêu dữ liệu cho Nhà cung cấp Danh tính**

Phiên bản hiện tại của Overleaf CE bao gồm một điểm cuối để lấy Siêu dữ liệu Nhà cung cấp Dịch vụ: `http://my-overleaf-instance.com/saml/meta`

Nhà cung cấp Danh tính sẽ cần được cấu hình để nhận diện máy chủ Overleaf là một "Service Provider". Hãy tham khảo tài liệu của máy chủ SAML để biết hướng dẫn cách thực hiện điều này.

Dưới đây là ví dụ về siêu dữ liệu Service Provider phù hợp:

<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>

Lưu ý các chứng chỉ, `AssertionConsumerService.Location`, `SingleLogoutService.Location` và `EntityDescriptor.entityID` và đặt cho phù hợp trong cấu hình IdP của bạn, hoặc gửi tệp siêu dữ liệu cho quản trị viên IdP.

<details>

<summary><strong>Tệp variables.env mẫu (tối thiểu)</strong></summary>

<pre><code>OVERLEAF_APP_NAME="Phiên bản Overleaf của chúng tôi"

ENABLED_LINKED_FILE_TYPES=project_file,project_output_file,url

# Bật tạo hình thu nhỏ bằng ImageMagick
ENABLE_CONVERSIONS=true

# Tắt yêu cầu xác nhận email
EMAIL_CONFIRMATION_DISABLED=true

## Nginx
# NGINX_WORKER_PROCESSES=4
# NGINX_WORKER_CONNECTIONS=768

## Đặt cho TLS qua nginx-proxy
# OVERLEAF_BEHIND_PROXY=true
# OVERLEAF_SECURE_COOKIE=true

OVERLEAF_SITE_URL=http://my-overleaf-instance.com
OVERLEAF_NAV_TITLE=Phiên bản Overleaf của chúng tôi
# OVERLEAF_HEADER_IMAGE_URL=http://somewhere.com/mylogo.png
OVERLEAF_ADMIN_EMAIL=support@example.com

OVERLEAF_LEFT_FOOTER=[{"text": "Liên hệ đội hỗ trợ của bạn", "url": "mailto:support@example.com"}]
OVERLEAF_RIGHT_FOOTER=[{"text":"Xin chào, tôi ở bên phải", "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=Hệ thống này do bộ phận x vận hành

OVERLEAF_PROXY_LEARN=true
NAV_HIDE_POWERED_BY=true

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

EXTERNAL_AUTH=saml
OVERLEAF_SAML_ISSUER=MyOverleaf
OVERLEAF_SAML_IDENTITY_SERVICE_NAME='Đăng nhập bằng Nhà cung cấp 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/vi/cau-hinh/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.
