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

Bên trong, 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 cách 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 người dùng thành công, cơ sở dữ liệu người dùng Overleaf sẽ được kiểm tra để tìm 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, cơ sở dữ liệu sẽ được tìm kiếm để tìm 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, thì `hashedPassword` trường sẽ bị xóa để vô hiệu hóa xác thực cục bộ, và `samlIdentifiers` trường sẽ đượ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 SAML IdP. Trường `providerId` trong `samlIdentifiers` được cố định là `'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 SAML IdP`).
* `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 thông tin 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 của Issuer.
* `OVERLEAF_SAML_AUDIENCE`
  * Audience mong đợi của phản hồi SAML, 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, dùng để xác thực chữ ký của các phản hồi SAML đi vào. Nếu Nhà cung cấp Danh tính có nhiều chứng chỉ ký hợp lệ, thì có thể là một mảng JSON các đường dẫn tới 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 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 SAML Request đi vào. Tệp này được yêu cầu 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 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 `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 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, 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ỳ khẳng định đượ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ý 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 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 đị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 định nghĩa. 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ể được đặt thành địa chỉ email của người dùng.
* `OVERLEAF_SAML_ACCEPTED_CLOCK_SKEW_MS`
  * Độ lệch thời gian tính bằng mili giây được chấp nhận giữa client và server khi kiểm tra tính hợp lệ của các dấu thời gian đ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 chỉ thị cho IdP bộ thuộc tính nào sẽ được đính kèm vào phản hồi ([link](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 đị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 nên buộc người dùng xác thực lại, 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 một ngữ cảnh xác thực cụ thể. Ví dụ, bạn có thể đặt điều 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`). Việc hỗ trợ 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 sẽ 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 đi vào.
  * Nếu `không bao giờ`, thì InResponseTo sẽ không được xác thực (mặc định).
  * Nếu `ifPresent`, thì InResponseTo chỉ được xác thực nếu có trong phản hồi SAML đi vào.
* `OVERLEAF_SAML_WANT_ASSERTIONS_SIGNED` và `OVERLEAF_SAML_WANT_AUTHN_RESPONSE_SIGNED`
  * Khi được đặt thành `true` (mặc định), Overleaf mong đợi các SAML Assertion, tương ứng toàn bộ SAML Authentication Response, được IdP ký. Khi cả hai tùy chọn đều `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 ở trường `InResponseTo` . Mặc định: 28800000 (8 giờ).
* `OVERLEAF_SAML_LOGOUT_URL`
  * địa chỉ cơ sở để gọi bằng 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`, nếu không thì `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ị chỉ được đặt thành `true` trong quá trình tạo người dùng quản trị trong Launchpad.

**Metadata 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 để truy xuất Metadata của 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 như một "Service Provider". Hãy tham khảo tài liệu của máy chủ SAML của bạn để biết cách thực hiện.

Dưới đây là một ví dụ về metadata phù hợp của Nhà cung cấp Dịch vụ:

<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à thiết lập phù hợp trong cấu hình IdP của bạn, hoặc gửi tệp metadata 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="Our Overleaf Instance"

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

## Thiết lập 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 department 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://overleaf-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.
