> ## Documentation Index
> Fetch the complete documentation index at: https://ayakaleaf-pro.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Автентифікація OIDC

<Info>
  Цю функцію розроблено в [yu-i-i/overleaf-cep](https://github.com/yu-i-i/overleaf-cep). Тут ми наводимо документацію для її налаштування.
</Info>

### Налаштування

Внутрішньо модуль OIDC в Overleaf використовує бібліотеку [passport-openidconnect](https://github.com/jaredhanson/passport-openidconnect). Якщо у вас виникають проблеми з налаштуванням OpenID Connect, варто прочитати README для `passport-openidconnect`, щоб зрозуміти, яку конфігурацію вона очікує.

Для ввімкнення модуля автентифікації OIDC потрібна змінна середовища `EXTERNAL_AUTH`. Ця змінна середовища визначає, які методи зовнішньої автентифікації активовано. Значенням цієї змінної є список. Якщо список містить `oidc`, автентифікацію OIDC буде активовано.

Наприклад: `EXTERNAL_AUTH=ldap oidc`

Під час використання методу автентифікації OIDC користувача перенаправляють на сайт автентифікації постачальника ідентичності (IdP). Якщо IdP успішно автентифікує користувача, у базі даних користувачів Overleaf шукається запис, що містить поле `thirdPartyIdentifiers` такої структури:

```text theme={null}
thirdPartyIdentifiers: [
  {
    externalUserId: "...",
    externalData: null,
    providerId: "..."
  }
]
```

`externalUserId` має збігатися з ID користувача в профілі, який повертає сервер IdP (див. змінну середовища `OVERLEAF_OIDC_USER_ID_FIELD`), а `providerId` має збігатися з ID постачальника OIDC (див. `OVERLEAF_OIDC_PROVIDER_ID`).

Якщо відповідного запису не знайдено, у базі даних шукається користувач, чия основна адреса електронної пошти збігається з адресою в профілі користувача IdP:

* Якщо такого користувача знайдено, поле `thirdPartyIdentifiers` оновлюється.
* Якщо відповідного користувача не знайдено, а створення облікових записів JIT не вимкнено, створюється новий користувач з адресою електронної пошти та `thirdPartyIdentifiers` з профілю IdP.

В обох випадках вважається, що користувача «пов'язано» із зовнішнім користувачем OIDC. Користувач може скасувати зв'язок із постачальником OIDC на сторінці `/user/settings`.

#### Пошук значень за допомогою документа виявлення

Кожен постачальник OpenID (OP) публікує документ виявлення (discovery document) за адресою `<issuer>/.well-known/openid-configuration`. Копіюйте значення з нього, а не вводьте їх вручну: одного неправильного символу достатньо, щоб вхід перестав працювати.

<Steps>
  <Step title="Знайдіть URL виявлення">
    Ваш OP показує його на сторінці клієнта (постачальника), створеного для Overleaf. В Authentik відкрийте **Applications > Providers**, виберіть постачальника та знайдіть **OpenID Configuration URL** і **OpenID Configuration Issuer**:

    <Frame caption="Authentik: URL виявлення та issuer постачальника (тестовий екземпляр)">
      <img src="https://mintcdn.com/ayakaleaf-pro/TjqwH4XzxYAkHStq/images/on-premises/oidc-authentik-provider.png?fit=max&auto=format&n=TjqwH4XzxYAkHStq&q=85&s=e3cb5603d959665472b53e39b58b2775" alt="" width="1280" height="633" data-path="images/on-premises/oidc-authentik-provider.png" />
    </Frame>

    Зазвичай URL виглядає так:

    * Keycloak: `https://keycloak.example.com/realms/<realm>/.well-known/openid-configuration`
    * Authentik: `https://authentik.example.com/application/o/<application-slug>/.well-known/openid-configuration`
  </Step>

  <Step title="Прочитайте значення">
    Відкрийте URL у браузері або виконайте на сервері Overleaf:

    ```shell theme={null}
    curl -s https://authentik.example.com/application/o/overleaf/.well-known/openid-configuration \
      | jq '{issuer, authorization_endpoint, token_endpoint, userinfo_endpoint, end_session_endpoint}'
    ```

    Відповідь Authentik виглядає так:

    ```json theme={null}
    {
      "issuer": "https://authentik.example.com/application/o/overleaf/",
      "authorization_endpoint": "https://authentik.example.com/application/o/authorize/",
      "token_endpoint": "https://authentik.example.com/application/o/token/",
      "userinfo_endpoint": "https://authentik.example.com/application/o/userinfo/",
      "end_session_endpoint": "https://authentik.example.com/application/o/overleaf/end-session/"
    }
    ```

    Authentik також наводить ці URL нижче на сторінці постачальника:

    <Frame caption="Authentik: ендпоінти постачальника (тестовий екземпляр)">
      <img src="https://mintcdn.com/ayakaleaf-pro/TjqwH4XzxYAkHStq/images/on-premises/oidc-authentik-endpoints.png?fit=max&auto=format&n=TjqwH4XzxYAkHStq&q=85&s=55d130cbbbf27fd11aebafa1ab3f090c" alt="" width="1280" height="633" data-path="images/on-premises/oidc-authentik-endpoints.png" />
    </Frame>
  </Step>

  <Step title="Скопіюйте їх у `variables.env`">
    | Поле в документі виявлення | Змінна середовища |
    | - | - |
    | `issuer` | `OVERLEAF_OIDC_ISSUER` |
    | `authorization_endpoint` | `OVERLEAF_OIDC_AUTHORIZATION_URL` |
    | `token_endpoint` | `OVERLEAF_OIDC_TOKEN_URL` |
    | `userinfo_endpoint` | `OVERLEAF_OIDC_USER_INFO_URL` |
    | `end_session_endpoint` | `OVERLEAF_OIDC_LOGOUT_URL` |

    ```dotenv theme={null}
    OVERLEAF_OIDC_ISSUER=https://authentik.example.com/application/o/overleaf/
    OVERLEAF_OIDC_AUTHORIZATION_URL=https://authentik.example.com/application/o/authorize/
    OVERLEAF_OIDC_TOKEN_URL=https://authentik.example.com/application/o/token/
    OVERLEAF_OIDC_USER_INFO_URL=https://authentik.example.com/application/o/userinfo/
    OVERLEAF_OIDC_LOGOUT_URL=https://authentik.example.com/application/o/overleaf/end-session/
    ```
  </Step>

  <Step title="Перевірте, що Overleaf може дістатися до OP">
    Overleaf звертається до ендпоінтів token і userinfo зсередини свого контейнера, тому OP має бути доступним звідти, а не лише з вашого браузера:

    ```shell theme={null}
    docker exec sharelatex curl -sS -o /dev/null -w "%{http_code}\n" \
      https://authentik.example.com/application/o/overleaf/.well-known/openid-configuration
    ```

    Команда має вивести `200`.
  </Step>
</Steps>

<Warning>
  Копіюйте `issuer` точно, включно з кінцевою скісною рискою. Overleaf посимвольно порівнює його з issuer в ID-токені; будь-яка відмінність призводить до того, що кожен вхід через OIDC завершується помилкою:

  `{"message":{"message":"ID token not issued by expected OpenID provider."}}`

  В Authentik issuer належить застосунку (`.../application/o/<application-slug>/`). Це не адреса сервера Authentik, хоча URL authorize, token і userinfo спільні для всіх застосунків.
</Warning>

#### Змінні середовища

Значення наведених нижче п'яти обов'язкових змінних можна знайти за допомогою ендпоінта `.well-known/openid-configuration` вашого постачальника OpenID (OP), див. вище.

* `OVERLEAF_OIDC_ISSUER` <strong>(обов'язково)</strong>
* `OVERLEAF_OIDC_AUTHORIZATION_URL` <strong>(обов'язково)</strong>
* `OVERLEAF_OIDC_TOKEN_URL` <strong>(обов'язково)</strong>
* `OVERLEAF_OIDC_USER_INFO_URL` <strong>(обов'язково)</strong>
* `OVERLEAF_OIDC_LOGOUT_URL` <strong>(обов'язково)</strong>

Значення наведених нижче двох обов'язкових змінних надасть адміністратор вашого OP

* `OVERLEAF_OIDC_CLIENT_ID` <strong>(обов'язково)</strong>
* `OVERLEAF_OIDC_CLIENT_SECRET` <strong>(обов'язково)</strong>
* `OVERLEAF_OIDC_SCOPE`
  * За замовчуванням: `openid profile email`
* `OVERLEAF_OIDC_PROVIDER_ID`
  * Довільний ID OP, за замовчуванням `oidc`.
* `OVERLEAF_OIDC_PROVIDER_NAME`
  * Назва OP, що використовується в розділі `Linked Accounts` на сторінці `/user/settings`, за замовчуванням `OIDC Provider`.
* `OVERLEAF_OIDC_IDENTITY_SERVICE_NAME`
  * Відображувана назва сервісу ідентифікації, що використовується на сторінці входу (за замовчуванням: `Log in with $OVERLEAF_OIDC_PROVIDER_NAME`).
* `OVERLEAF_OIDC_PROVIDER_DESCRIPTION`
  * Опис OP, що використовується в розділі `Linked Accounts` (за замовчуванням: `Log in with $OVERLEAF_OIDC_PROVIDER_NAME`).
* `OVERLEAF_OIDC_PROVIDER_INFO_LINK`
  * URL `Learn more` в описі OP; за замовчуванням посилання `Learn more` в описі немає.
* `OVERLEAF_OIDC_PROVIDER_HIDE_NOT_LINKED`
  * Не показувати OP на сторінці `/user/settings`, якщо обліковий запис користувача не пов'язано з OP; за замовчуванням `false`.
* `OVERLEAF_OIDC_USER_ID_FIELD`
  * Значення цього атрибута Overleaf використовуватиме як зовнішній ID користувача; за замовчуванням `id`. Інші можливі доречні значення — `email` і `username` (відповідає claim OIDC `preferred_username`).
* `OVERLEAF_OIDC_ALLOWED_EMAIL_DOMAINS`
  * Обмежує створення облікових записів Just-in-Time (JIT) для користувачів, які автентифікуються через OIDC. Якщо задано список доменних імен, розділених комами, новий обліковий запис буде створено лише тоді, коли домен адреси електронної пошти користувача збігається з одним із доменів у списку. Якщо домен не збігається, адміністратор має вручну створити обліковий запис користувача з адресою електронної пошти користувача OIDC, з надійним випадковим паролем або, що краще, взагалі без поля `hashedPassword`. Доменні імена можуть містити на початку символ підстановки `*.` для відповідності піддоменам.
    * Приклад: щоб дозволити створення облікових записів JIT для користувачів з адресами на кшталт `name@example.com` і `name@math.example.com`:\
      `OVERLEAF_OIDC_ALLOWED_EMAIL_DOMAINS=example.com, *.example.com`
    * Приклад: щоб повністю вимкнути створення облікових записів JIT:\
      `OVERLEAF_OIDC_ALLOWED_EMAIL_DOMAINS=`
* `OVERLEAF_OIDC_UPDATE_USER_DETAILS_ON_LOGIN`
  * Якщо встановлено `true`, під час входу оновлюються поля користувача `first_name` і `last_name`, а форма даних користувача на сторінці `/user/settings` вимикається.
* `OVERLEAF_OIDC_IS_ADMIN_FIELD` і `OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE`
  * Коли задано обидві змінні середовища, процес входу встановлює `user.isAdmin = true`, якщо профіль, повернутий OP, містить атрибут, вказаний у `OVERLEAF_OIDC_IS_ADMIN_FIELD`, і його значення або збігається з `OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE`, або є масивом, що містить `OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE` (наприклад, claim `groups`); інакше `user.isAdmin` встановлюється в `false`. Якщо `OVERLEAF_OIDC_IS_ADMIN_FIELD` має значення `email`, для перевірки збігу використовується значення атрибута `emails[0].value`.

URL перенаправлення для вашого постачальника OpenID: `https://my-overleaf-instance.com/oidc/login/callback`.

<Accordion title="Приклад файлу variables.env">
  ```dotenv title="variables.env" wrap theme={null}
  OVERLEAF_APP_NAME="Our Overleaf Instance"

  ENABLED_LINKED_FILE_TYPES=project_file,project_output_file,url

  # Enables Thumbnail generation using ImageMagick
  ENABLE_CONVERSIONS=true

  # Disables email confirmation requirement
  EMAIL_CONFIRMATION_DISABLED=true

  ## Nginx
  # NGINX_WORKER_PROCESSES=4
  # NGINX_WORKER_CONNECTIONS=768

  ## Set for TLS via nginx-proxy
  # 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": "Contact your support team", "url": "mailto:support@example.com"}]
  OVERLEAF_RIGHT_FOOTER=[{"text":"Hello, I am on the Right", "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=This system is run by department x

  OVERLEAF_PROXY_LEARN=true
  NAV_HIDE_POWERED_BY=true

  #################
  ## OIDC for CE ##
  #################

  EXTERNAL_AUTH=oidc

  OVERLEAF_OIDC_PROVIDER_ID=oidc
  OVERLEAF_OIDC_ISSUER=https://keycloak.provider.com/realms/example
  OVERLEAF_OIDC_AUTHORIZATION_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/auth
  OVERLEAF_OIDC_TOKEN_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/token
  OVERLEAF_OIDC_USER_INFO_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/userinfo
  OVERLEAF_OIDC_LOGOUT_URL=https://keycloak.provider.com/realms/example/protocol/openid-connect/logout
  OVERLEAF_OIDC_CLIENT_ID=Overleaf-OIDC
  OVERLEAF_OIDC_CLIENT_SECRET=DoNotUseThisATGgaAcTgCcATgGATTACAagGtTCaGcGTAG
  OVERLEAF_OIDC_IDENTITY_SERVICE_NAME='Log in with Keycloak OIDC Provider'
  OVERLEAF_OIDC_PROVIDER_NAME=OIDC Keycloak Provider
  OVERLEAF_OIDC_PROVIDER_INFO_LINK=https://openid.net
  OVERLEAF_OIDC_IS_ADMIN_FIELD=email
  OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE=overleaf.admin@example.com
  OVERLEAF_OIDC_UPDATE_USER_DETAILS_ON_LOGIN=false
  ```
</Accordion>

## Покрокова інструкція: goauthentik

Тут описано налаштування, протестоване з [goauthentik](https://goauthentik.io/). Замініть `https://overleaf.example.com` на ваш `OVERLEAF_SITE_URL`, а `https://authentik.example.com` — на адресу вашого Authentik.

<Steps>
  <Step title="Створіть постачальника">
    В Authentik відкрийте **Applications > Providers**, натисніть **New Provider**, виберіть **OAuth2/OpenID Provider** і натисніть **Next**.

    * **Client Type**: `Confidential`.
    * **Redirect URIs** (у розділі **Protocol settings**): додайте `https://overleaf.example.com/oidc/login/callback` з режимом зіставлення `Strict`.
    * Одразу скопіюйте **Client ID** і **Client Secret** у `OVERLEAF_OIDC_CLIENT_ID` і `OVERLEAF_OIDC_CLIENT_SECRET`.

    <Frame caption="Authentik: Client ID і Client Secret нового постачальника">
      <img src="https://mintcdn.com/ayakaleaf-pro/TjqwH4XzxYAkHStq/images/on-premises/oidc-authentik-create.png?fit=max&auto=format&n=TjqwH4XzxYAkHStq&q=85&s=f127a92eaf3063714e9af515fe97c263" alt="" width="1120" height="808" data-path="images/on-premises/oidc-authentik-create.png" />
    </Frame>

    <Warning>
      Authentik показує client secret лише під час створення постачальника. Пізніше форма редагування пропонує тільки **Modify**, що замінює секрет новим.
    </Warning>
  </Step>

  <Step title="Створіть застосунок">
    Відкрийте **Applications > Applications**, створіть новий застосунок, задайте йому назву та slug, наприклад `overleaf`, і виберіть постачальника. Slug стає частиною issuer: `https://authentik.example.com/application/o/overleaf/`.
  </Step>

  <Step title="Скопіюйте URL">
    Дотримуйтеся розділу [Пошук значень за допомогою документа виявлення](#пошук-значень-за-допомогою-документа-виявлення) вище, щоб заповнити п'ять URL.
  </Step>

  <Step title="Зіставте адміністраторів (необов'язково)">
    Authentik надсилає групи користувача як claim `groups` — масив. Щоб члени групи Authentik `Admins` стали адміністраторами Overleaf:

    ```dotenv theme={null}
    OVERLEAF_OIDC_IS_ADMIN_FIELD=groups
    OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE=Admins
    ```

    <Warning>
      Прапорець адміністратора оновлюється під час кожного входу через OIDC. Якщо поле або значення неправильні, кожен адміністратор, який входить через OIDC, втрачає права адміністратора, зокрема й адміністратор, створений у launchpad. Спершу протестуйте зіставлення з другим обліковим записом адміністратора.
    </Warning>
  </Step>
</Steps>

<Accordion title="Протестований variables.env для goauthentik">
  ```dotenv title="variables.env" wrap theme={null}
  EXTERNAL_AUTH=oidc
  OVERLEAF_OIDC_PROVIDER_ID=authentik
  OVERLEAF_OIDC_IDENTITY_SERVICE_NAME=Log in with Authentik
  OVERLEAF_OIDC_ISSUER=https://authentik.example.com/application/o/overleaf/
  OVERLEAF_OIDC_AUTHORIZATION_URL=https://authentik.example.com/application/o/authorize/
  OVERLEAF_OIDC_TOKEN_URL=https://authentik.example.com/application/o/token/
  OVERLEAF_OIDC_USER_INFO_URL=https://authentik.example.com/application/o/userinfo/
  OVERLEAF_OIDC_LOGOUT_URL=https://authentik.example.com/application/o/overleaf/end-session/
  OVERLEAF_OIDC_CLIENT_ID=<Client ID>
  OVERLEAF_OIDC_CLIENT_SECRET=<Client Secret>
  OVERLEAF_OIDC_USER_ID_FIELD=username
  OVERLEAF_OIDC_IS_ADMIN_FIELD=groups
  OVERLEAF_OIDC_IS_ADMIN_FIELD_VALUE=Admins
  OVERLEAF_OIDC_UPDATE_USER_DETAILS_ON_LOGIN=true
  ```
</Accordion>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.