> 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/ldap-authentication.md).

# Xác thực LDAP

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.

{% hint style="warning" %}
Overleaf sử dụng **passport-ldapauth** thư viện, vốn khá cũ, khả năng tương thích LDAP không thể được đảm bảo hoàn toàn. Với một số nhà cung cấp danh tính LDAP nhất định (ví dụ, <https://goauthentik.io/>), có thể xảy ra lỗi đăng nhập. Do đó, nếu có thể, bạn nên sử dụng phương thức OAuth/SAML trước.
{% endhint %}

### LDAP là gì

LDAP là một giao thức xác thực dùng để xác minh danh tính bên ngoài. Overleaf Server Pro cung cấp một biểu mẫu đăng nhập LDAP riêng trong giao diện web, tách biệt với phương thức xác thực tiêu chuẩn. Khi người dùng gửi tên người dùng và mật khẩu LDAP của họ, backend của Overleaf sẽ xác minh thông tin xác thực với máy chủ LDAP đã cấu hình, ví dụ `ldap://ldap:10389`.

<figure><img src="/files/a92ae1e09f3b5f56718f91356490b8a49b2a78d3" alt=""><figcaption><p>Một ví dụ Server Pro cho LDAP</p></figcaption></figure>

### Cấu hình

Bên trong, Overleaf LDAP sử dụng [passport-ldapauth](https://github.com/vesse/passport-ldapauth) thư viện. Hầu hết các tùy chọn cấu hình này được chuyển tiếp tới `máy chủ` đối tượng config được dùng để cấu hình `passport-ldapauth`. Nếu bạn gặp vấn đề khi cấu hình LDAP, bạn nên đọc README của `passport-ldapauth` để 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 LDAP. 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 `ldap` thì xác thực LDAP sẽ được kích hoạt.

Ví dụ: `EXTERNAL_AUTH=ldap saml`

Khác với Overleaf CEP, trong phiên bản ayaka-notes của chúng tôi, chúng tôi giới hạn xác thực LDAP chỉ là một phương thức xác thực thuần túy, có thể dùng tại `http://your-overleaf.com/ldap/login`.

Khi sử dụng phương thức xác thực LDAP, người dùng nhập `tên người dùng` và `mật khẩu` trong biểu mẫu đăng nhập, hệ thống sẽ thực hiện:

1. Một người dùng LDAP được tìm kiếm trong thư mục LDAP bằng bộ lọc được định nghĩa bởi `OVERLEAF_LDAP_SEARCH_FILTER` và được xác thực.
2. Nếu xác thực thành công, cơ sở dữ liệu người dùng của Overleaf sẽ được kiểm tra để tìm người dùng có địa chỉ email chính khớp với địa chỉ email của người dùng LDAP đã xác thực:
   * Nếu tìm thấy người dùng khớp, `hashedPassword` trường của người dùng này sẽ bị xóa (nếu tồn tại). Điều này đảm bảo rằng sau này người dùng chỉ có thể đăng nhập qua xác thực LDAP.
   * Nếu không tìm thấy người dùng khớp, một người dùng Overleaf mới sẽ được tạo bằng email, tên và họ lấy từ máy chủ LDAP.

{% hint style="danger" %}
Đối với người dùng đăng nhập qua LDAP, chúng tôi không lưu trữ (hoặc xóa nếu đã tồn tại) mật khẩu băm trong cơ sở dữ liệu Mongo của Overleaf.
{% endhint %}

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

* `OVERLEAF_LDAP_URL` **(bắt buộc)**
  * URL của máy chủ LDAP.
    * Ví dụ: `ldaps://ldap.example.com:636` (LDAP qua SSL)
    * Ví dụ: `ldap://ldap.example.com:389` (không mã hóa hoặc STARTTLS, nếu được cấu hình).
* `OVERLEAF_LDAP_IDENTITY_SERVICE_NAME`
  * Tên hiển thị cho dịch vụ danh tính LDAP, dùng trên trang đăng nhập.
  * Mặc định là `Đăng nhập bằng nhà cung cấp LDAP`.
* `OVERLEAF_LDAP_EMAIL_ATT`
  * Thuộc tính email do máy chủ LDAP trả về, mặc định là `mail`. Mỗi người dùng LDAP phải có ít nhất một địa chỉ email. Nếu cung cấp nhiều địa chỉ, chỉ địa chỉ đầu tiên sẽ được dùng.
* `OVERLEAF_LDAP_FIRST_NAME_ATT`
  * Tên thuộc tính chứa tên của người dùng được dùng trong ứng dụng, thường là `givenName`.
* `OVERLEAF_LDAP_LAST_NAME_ATT`
  * Tên thuộc tính chứa họ của người dùng được dùng trong ứng dụng, thường là `sn`.
* `OVERLEAF_LDAP_NAME_ATT`
  * Tên thuộc tính chứa họ tên đầy đủ của người dùng, thường là `cn`. Nếu một trong hai biến trước đó không được định nghĩa, tên và/hoặc họ của người dùng sẽ được trích xuất từ biến này. Nếu không, nó không được sử dụng.
* `OVERLEAF_LDAP_PLACEHOLDER`
  * Chỗ giữ chỗ cho biểu mẫu đăng nhập, mặc định là `Tên người dùng`.
* `OVERLEAF_LDAP_UPDATE_USER_DETAILS_ON_LOGIN`
  * Nếu được đặt thành `true`, sẽ cập nhật người dùng LDAP `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 trang `/user/settings` cho người dùng LDAP. Nếu không, thông tin chỉ sẽ được lấy ở lần đăng nhập đầu tiên.
* `OVERLEAF_LDAP_BIND_DN`
  * Tên định danh của người dùng LDAP nên được dùng cho kết nối LDAP (người dùng này nên có thể tìm kiếm/liệt kê tài khoản trên máy chủ LDAP), ví dụ, `cn=ldap_reader,dc=example,dc=com`. Nếu không được định nghĩa, sẽ dùng liên kết ẩn danh.
* `OVERLEAF_LDAP_BIND_CREDENTIALS`
  * Mật khẩu cho `OVERLEAF_LDAP_BIND_DN`.
* `OVERLEAF_LDAP_BIND_PROPERTY`
  * Thuộc tính của người dùng để ràng buộc với client, mặc định là `dn`.
* `OVERLEAF_LDAP_SEARCH_BASE` **(bắt buộc)**
  * DN cơ sở để tìm kiếm người dùng. Ví dụ, `ou=people,dc=example,dc=com`.
* `OVERLEAF_LDAP_SEARCH_FILTER`
  * Bộ lọc tìm kiếm LDAP dùng để tìm một người dùng. Dùng nguyên văn '{{username}}' để chèn tên người dùng được cung cấp vào truy vấn tìm kiếm LDAP.
    * Ví dụ: `(|(uid={{username}})(mail={{username}}))` (người dùng có thể đăng nhập bằng email hoặc tên đăng nhập).
    * Ví dụ: `(sAMAccountName={{username}})` (Active Directory).
* `OVERLEAF_LDAP_SEARCH_SCOPE`
  * Phạm vi tìm kiếm có thể là `base`, `one`, hoặc `sub` (mặc định).
* `OVERLEAF_LDAP_SEARCH_ATTRIBUTES`
  * Mảng JSON các thuộc tính cần lấy từ máy chủ LDAP, ví dụ, `["uid", "mail", "givenName", "sn"]`. Theo mặc định, tất cả các thuộc tính đều được lấy.
* `OVERLEAF_LDAP_STARTTLS`
  * Nếu `true`, LDAP qua TLS được sử dụng.
* `OVERLEAF_LDAP_TLS_OPTS_CA_PATH`
  * Đường dẫn tới tệp chứa chứng chỉ CA dùng để xác minh chứng chỉ SSL/TLS của máy chủ LDAP. Nếu có nhiều chứng chỉ, nó có thể là một mảng JSON các đường dẫn tới các chứng chỉ. Các tệp phải có thể truy cập được bởi container Docker.
    * Ví dụ (một chứng chỉ): `/var/lib/overleaf/certs/ldap_ca_cert.pem`
    * Ví dụ (nhiều chứng chỉ): `["/var/lib/overleaf/certs/ldap_ca_cert1.pem", "/var/lib/overleaf/certs/ldap_ca_cert2.pem"]`
* `OVERLEAF_LDAP_TLS_OPTS_REJECT_UNAUTH`
  * Nếu `true`, chứng chỉ máy chủ sẽ được xác minh dựa trên danh sách các CA được cung cấp.
* `OVERLEAF_LDAP_CACHE`
  * Nếu `true`, thì tối đa 100 thông tin xác thực cùng lúc sẽ được lưu vào bộ nhớ đệm trong 5 phút.
* `OVERLEAF_LDAP_TIMEOUT`
  * Thời gian client cho phép các thao tác tồn tại trước khi hết thời gian chờ, ms (Mặc định: Infinity).
* `OVERLEAF_LDAP_CONNECT_TIMEOUT`
  * Thời gian client nên chờ trước khi hết thời gian chờ đối với kết nối TCP, ms (Mặc định: mặc định của hệ điều hành).
* `OVERLEAF_LDAP_IS_ADMIN_ATT` và `OVERLEAF_LDAP_IS_ADMIN_ATT_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ơ LDAP chứa thuộc tính được chỉ định bởi `OVERLEAF_LDAP_IS_ADMIN_ATT` và giá trị của nó hoặc khớp với `OVERLEAF_LDAP_IS_ADMIN_ATT_VALUE` hoặc là một mảng chứa `OVERLEAF_LDAP_IS_ADMIN_ATT_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.

Năm biến sau được dùng để cấu hình cách danh bạ người dùng được truy xuất từ máy chủ LDAP.

* `OVERLEAF_LDAP_CONTACTS_FILTER`
  * Bộ lọc dùng để tìm kiếm người dùng trong máy chủ LDAP để nạp vào danh bạ. Chỗ giữ chỗ '{{userProperty}}' trong bộ lọc sẽ được thay bằng giá trị của thuộc tính được chỉ định bởi `OVERLEAF_LDAP_CONTACTS_PROPERTY` từ người dùng LDAP khởi tạo tìm kiếm. Nếu không được định nghĩa, sẽ không có người dùng nào được truy xuất từ máy chủ LDAP vào danh bạ.
* `OVERLEAF_LDAP_CONTACTS_SEARCH_BASE`
  * Chỉ định DN cơ sở từ đó bắt đầu tìm kiếm danh bạ. Mặc định là `OVERLEAF_LDAP_SEARCH_BASE`.
* `OVERLEAF_LDAP_CONTACTS_SEARCH_SCOPE`
  * Phạm vi tìm kiếm có thể là `base`, `one`, hoặc `sub` (mặc định).
* `OVERLEAF_LDAP_CONTACTS_PROPERTY`
  * Chỉ định thuộc tính của đối tượng người dùng sẽ thay thế chỗ giữ chỗ '{{userProperty}}' trong `OVERLEAF_LDAP_CONTACTS_FILTER`.
* `OVERLEAF_LDAP_CONTACTS_NON_LDAP_VALUE`
  * Chỉ định giá trị của `OVERLEAF_LDAP_CONTACTS_PROPERTY` nếu tìm kiếm được khởi tạo bởi người dùng không phải LDAP. Nếu biến này không được định nghĩa, bộ lọc kết quả sẽ không khớp gì cả. Giá trị `*` có thể được dùng làm ký tự đại diện.

<details>

<summary><strong>Ví dụ</strong></summary>

```
OVERLEAF_LDAP_CONTACTS_FILTER=(gidNumber={{userProperty}})
OVERLEAF_LDAP_CONTACTS_PROPERTY=gidNumber
OVERLEAF_LDAP_CONTACTS_NON_LDAP_VALUE=1000
```

Ví dụ trên sẽ tải vào danh bạ của người dùng LDAP hiện tại tất cả người dùng LDAP có cùng UNIX `gid`. Người dùng không phải LDAP sẽ có tất cả người dùng LDAP có UNIX `gid=1000` trong danh bạ của họ.

</details>

<details>

<summary><strong>Tệp variables.env mẫu</strong></summary>

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

#################
## LDAP cho CE ##
#################

EXTERNAL_AUTH=ldap
OVERLEAF_LDAP_URL=ldap://ldap.example.com:389
OVERLEAF_LDAP_STARTTLS=true
OVERLEAF_LDAP_TLS_OPTS_CA_PATH=/var/lib/overleaf/certs/ldap_ca_cert.pem
OVERLEAF_LDAP_SEARCH_BASE=ou=people,dc=example,dc=com
OVERLEAF_LDAP_SEARCH_FILTER=(|(uid={{username}})(mail={{username}}))
OVERLEAF_LDAP_BIND_DN=cn=ldap_reader,dc=example,dc=com
OVERLEAF_LDAP_BIND_CREDENTIALS=GoodNewsEveryone
OVERLEAF_LDAP_EMAIL_ATT=mail
OVERLEAF_LDAP_FIRST_NAME_ATT=givenName
OVERLEAF_LDAP_LAST_NAME_ATT=sn
# OVERLEAF_LDAP_NAME_ATT=cn
OVERLEAF_LDAP_SEARCH_ATTRIBUTES=["uid", "sn", "givenName", "mail"]

OVERLEAF_LDAP_UPDATE_USER_DETAILS_ON_LOGIN=true

OVERLEAF_LDAP_PLACEHOLDER='Tên người dùng hoặc địa chỉ email'

OVERLEAF_LDAP_IS_ADMIN_ATT=mail
OVERLEAF_LDAP_IS_ADMIN_ATT_VALUE=admin@example.com

OVERLEAF_LDAP_CONTACTS_FILTER=(gidNumber={{userProperty}})
OVERLEAF_LDAP_CONTACTS_PROPERTY=gidNumber
OVERLEAF_LDAP_CONTACTS_NON_LDAP_VALUE='*'
```

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