Перейти к содержанию

OIDC Аутентификация

Gramps Web поддерживает аутентификацию OpenID Connect (OIDC), позволяя пользователям входить в систему с использованием внешних поставщиков идентификации. Это включает встроенные поставщики Google и Microsoft, а также пользовательские OIDC-поставщики, такие как Keycloak, Authentik и Authelia.

GitHub как OIDC-поставщик больше не поддерживается

Если у вас установлены OIDC_GITHUB_CLIENT_ID / OIDC_GITHUB_CLIENT_SECRET из более ранней версии, удалите их – они теперь игнорируются, и пользователи, которые ранее входили через GitHub, больше не могут войти таким образом. GitHub является поставщиком OAuth 2.0, а не поставщиком OpenID Connect, и никогда не возвращал требование, на которое полагается Gramps Web для идентификации, поэтому он никогда не был полностью надежным.

Обзор

Аутентификация OIDC позволяет вам:

  • Использовать внешних поставщиков идентификации для аутентификации пользователей
  • Поддерживать несколько поставщиков аутентификации одновременно
  • Сопоставлять группы/роли OIDC с ролями пользователей Gramps Web
  • Реализовать единую аутентификацию (SSO) и единую выходную аутентификацию
  • При желании отключить локальную аутентификацию по имени пользователя/паролю

Конфигурация

Чтобы включить аутентификацию OIDC, вам нужно настроить соответствующие параметры в файле конфигурации Gramps Web или в переменных окружения. См. страницу Конфигурация сервера для полного списка доступных настроек OIDC.

Info

При использовании переменных окружения не забудьте добавить префикс GRAMPSWEB_ к каждому имени настройки (например, GRAMPSWEB_OIDC_ENABLED). См. Конфигурационный файл против переменных окружения для получения подробностей.

Встроенные Поставщики

Gramps Web имеет встроенную поддержку популярных поставщиков идентификации. Чтобы использовать их, вам нужно только предоставить идентификатор клиента и секрет клиента:

  • Google: OIDC_GOOGLE_CLIENT_ID и OIDC_GOOGLE_CLIENT_SECRET
  • Microsoft: OIDC_MICROSOFT_CLIENT_ID и OIDC_MICROSOFT_CLIENT_SECRET

Вы можете настроить несколько поставщиков одновременно. Система автоматически обнаружит, какие поставщики доступны на основе значений конфигурации.

Microsoft: развертывания с одним арендатором

Встроенный поставщик Microsoft использует многоарендный конечный пункт /common и принимает входы из любой учетной записи Microsoft по умолчанию. Если вы хотите разрешить вход только для пользователей из вашего собственного арендатора, используйте пользовательского OIDC-поставщика с вашим специфическим для арендатора URL-адресом эмитента, что сохраняет проверку эмитента активной и ограничивает входы только для этого арендатора.

Пользовательские OIDC Поставщики

Для пользовательских OIDC-поставщиков (таких как Keycloak, Authentik, Authelia или арендатор Microsoft Entra с одним арендатором) используйте следующие настройки:

Ключ Описание
OIDC_ENABLED Логическое значение, указывающее, следует ли включить аутентификацию OIDC. Установите в True.
OIDC_ISSUER URL-адрес эмитента вашего поставщика. Открытие документа осуществляется по адресу <issuer>/.well-known/openid-configuration.
OIDC_CLIENT_ID Идентификатор клиента для вашего OIDC-поставщика
OIDC_CLIENT_SECRET Секрет клиента для вашего OIDC-поставщика
OIDC_NAME Пользовательское имя для отображения (необязательно, по умолчанию "OIDC")
OIDC_SCOPES OAuth области (необязательно, по умолчанию "openid email profile")
OIDC_USERNAME_CLAIM Требование, используемое для генерации имени пользователя (необязательно, по умолчанию "preferred_username")
OIDC_PKCE Использовать ли PKCE, см. PKCE (необязательно, включается автоматически, если поставщик поддерживает это)

PKCE

С версии Gramps Web API 3.23 Gramps Web поддерживает PKCE (Proof Key for Code Exchange, метод S256) для потока авторизации с кодом. Некоторые поставщики идентификации, такие как Pocket ID, могут быть настроены на обязательное использование PKCE для клиента и отклонять входы, которые его не используют. Более ранние версии Gramps Web API никогда не использовали PKCE, поэтому входы с таким клиентом завершаются неудачей.

Использование PKCE определяется при входе следующим образом:

  • Если OIDC_PKCE установлено в True, используется PKCE.
  • Если OIDC_PKCE установлено в False, PKCE не используется, даже если поставщик его поддерживает.
  • Если OIDC_PKCE не установлено или установлено, но пусто, PKCE используется, если документ обнаружения поставщика (/.well-known/openid-configuration) содержит S256 в code_challenge_methods_supported, и не используется в противном случае.

Для большинства настроек вам не нужно ничего настраивать. Установите OIDC_PKCE в True, если ваш поставщик требует PKCE, но не рекламирует S256 в своем документе обнаружения, и в False, если ваш поставщик рекламирует S256, но неправильно его обрабатывает. В качестве переменных окружения логические значения должны быть в нижнем регистре (GRAMPSWEB_OIDC_PKCE=true), см. Конфигурация.

Для встроенных поставщиков соответствующие параметры – это OIDC_GOOGLE_PKCE и OIDC_MICROSOFT_PKCE.

Проверка кода PKCE хранится в сессии пользователя между перенаправлением к поставщику и обратным вызовом, поэтому это не требует изменений в URL-адресах перенаправления.

Многодеревьевые Настройки

На сервере с несколькими деревьями дерево, в которое пользователь входит, должно быть известно до того, как Gramps Web перенаправит к поставщику идентификации, поэтому вход начинается с:

GET /api/oidc/login/?provider=<id>&tree=<tree_id>

tree требуется в многодеревьях; его отсутствие или передача ID дерева, которого не существует, приводит к неудаче входа. На сервере с одним деревом tree является необязательным, но если он указан, он должен совпадать с настроенным TREE.

Идентичность OIDC привязана к ровно одной учетной записи Gramps Web, которая, в свою очередь, принадлежит ровно одному дереву – вход в другое дерево завершается неудачей, а не перемещением учетной записи. Нет способа связать одну идентичность у поставщика с учетными записями в нескольких деревьях; пользователи, которым нужен доступ к нескольким деревьям, должны иметь отдельные идентичности у поставщика (например, разные имена пользователей или учетные записи).

Warning

Учетная запись администратора сайта без связанного дерева (см. создание учетной записи администратора) не может войти через OIDC, так как вход OIDC всегда требует дерева. Такие учетные записи должны быть созданы и аутентифицированы с помощью локального имени пользователя/пароля.

Обязательные URL-адреса перенаправления

При настройке вашего OIDC-поставщика вы должны зарегистрировать следующий URL-адрес перенаправления:

Для OIDC-поставщиков, которые поддерживают подстановочные знаки: (например, Authentik)

  • https://your-gramps-backend.com/api/oidc/callback/*

Где * является подстановочным знаком regex. В зависимости от интерпретатора regex вашего поставщика это также может быть .* или аналогично. Убедитесь, что regex включен, если ваш поставщик этого требует (например, Authentik).

Для OIDC-поставщиков, которые не поддерживают подстановочные знаки: (например, Authelia)

  • https://your-gramps-backend.com/api/oidc/callback/custom

Дерево никогда не является частью URL-адреса перенаправления, даже на серверах с несколькими деревьями – оно передается отдельно в сессии, так как поставщики требуют, чтобы URL-адрес перенаправления точно совпадал с зарегистрированным.

Сопоставление Ролей

Gramps Web может автоматически сопоставлять группы или роли OIDC от вашего поставщика идентификации с ролями пользователей Gramps Web. Это позволяет вам централизованно управлять разрешениями пользователей в вашем поставщике идентификации. Сопоставление ролей работает одинаково для всех поставщиков, как встроенных, так и пользовательских.

Конфигурация

Используйте эти настройки для конфигурации сопоставления ролей:

Ключ Описание
OIDC_ROLE_CLAIM Имя требования в токене OIDC, которое содержит группы/роли пользователя. По умолчанию "groups". Поддерживаются точечные пути, например, realm_access.roles.
OIDC_GROUP_ADMIN Имя группы/роли от вашего OIDC-поставщика, которое сопоставляется с ролью "Admin" в Gramps
OIDC_GROUP_OWNER Имя группы/роли от вашего OIDC-поставщика, которое сопоставляется с ролью "Owner" в Gramps
OIDC_GROUP_EDITOR Имя группы/роли от вашего OIDC-поставщика, которое сопоставляется с ролью "Editor" в Gramps
OIDC_GROUP_CONTRIBUTOR Имя группы/роли от вашего OIDC-поставщика, которое сопоставляется с ролью "Contributor" в Gramps
OIDC_GROUP_MEMBER Имя группы/роли от вашего OIDC-поставщика, которое сопоставляется с ролью "Member" в Gramps
OIDC_GROUP_GUEST Имя группы/роли от вашего OIDC-поставщика, которое сопоставляется с ролью "Guest" в Gramps

Поведение Сопоставления Ролей

Если ни одна настройка OIDC_GROUP_* не настроена, сопоставление ролей отключено, и роли управляются вручную в Gramps Web; новые учетные записи OIDC создаются отключенными и должны быть одобрены существующим владельцем или администратором (см. Первый вход и начальная настройка ниже).

После настройки сопоставления ролей при каждом входе:

  • Если требование роли присутствует и пользователь принадлежит к сопоставленной группе, ему присваивается соответствующая роль.
  • Если требование роли присутствует, но пользователь не принадлежит ни к одной сопоставленной группе, его роль устанавливается как отключенная. Это поведение по умолчанию, а не ошибка – Gramps Web не может вывести роль для группы, которую он не распознает.
  • Если требование роли полностью отсутствует в токене, существующая роль остается без изменений; новая учетная запись по-прежнему по умолчанию отключена.

Google не отправляет требование групп

Токены Google никогда не включают требование groups, поэтому при включенном сопоставлении ролей входы Google попадают под "требование отсутствует" выше: существующие пользователи сохраняют свою роль, но новые пользователи Google создаются отключенными и требуют ручного одобрения. Имейте это в виду, прежде чем включать сопоставление ролей только для другого поставщика – это не отключает существующих пользователей Google.

Microsoft Entra возвращает роли приложений и членство в группах только в ID токене, а не из конечной точки userinfo. Gramps Web объединяет требования ID токена в ответ userinfo, чтобы OIDC_ROLE_CLAIM работал так же, как и для других поставщиков; если оба содержат требование, значение userinfo имеет приоритет.

Первый Вход и Начальная Настройка

Новые учетные записи, созданные через OIDC, начинают с отключенного состояния, если сопоставление ролей не назначает им роль (см. выше). На совершенно новом экземпляре никто не может одобрить отключенную учетную запись, и если OIDC_DISABLE_LOCAL_AUTH также включен, нет возможности входа с паролем.

Настройте группу владельцев/администраторов перед первым входом

Прежде чем кто-либо войдет через OIDC в первый раз, установите OIDC_GROUP_OWNER (или OIDC_GROUP_ADMIN) и убедитесь, что первый пользователь принадлежит к этой группе у поставщика. В противном случае экземпляр не сможет быть инициализирован через OIDC.

Учетные Записи и Имена Пользователей

Учетные записи, созданные через OIDC, получают сгенерированное имя пользователя, назначаемое один раз при создании учетной записи и никогда не изменяющееся при последующих входах:

  • Встроенные поставщики: <provider>_<claim value>, например, microsoft_alice@contoso.com
  • Пользовательский поставщик: простое значение требования, например, alice

Числовой суффикс добавляется при конфликте. Нет возможности переименовать имя пользователя учетной записи, созданной через OIDC, после этого; полное имя и адрес электронной почты, наоборот, обновляются при каждом входе.

Вход OIDC никогда не прикрепляется к существующей локальной учетной записи, которая случайно совпадает с ее адресом электронной почты – это сделано намеренно, так как связывание учетных записей по электронной почте является вектором захвата учетной записи. Пользователь, который уже имеет локальную учетную запись, получает вторую, отдельную учетную запись в первый раз, когда он входит через OIDC.

Адреса электронной почты от поставщика хранятся только в том случае, если поставщик помечает их как проверенные (или полностью опускает требование email_verified); в противном случае вход продолжается без хранения адреса электронной почты. Поскольку адреса электронной почты не обязательно должны быть уникальными (с версии Gramps Web API 3.22), адрес хранится, даже если другая учетная запись уже использует его.

Выход OIDC

Gramps Web поддерживает единую выходную аутентификацию (SSO logout) для OIDC-поставщиков. GET /api/oidc/logout/ ищет end_session_endpoint поставщика и возвращает его как logout_url в ответе; именно фронтенд Gramps Web направляет браузер туда, чтобы фактически завершить сессию у поставщика идентификации. logout_url равен null, когда у поставщика нет end_session_endpoint.

Токены не аннулируются при выходе

Выход завершает только сессию браузера; в настоящее время нет способа аннулировать токен Gramps Web, который уже был выдан. Токены остаются действительными до тех пор, пока они не истекут (JWT_ACCESS_TOKEN_EXPIRES, по умолчанию 15 минут для токенов доступа), независимо от того, вышел ли пользователь с Gramps Web или у поставщика идентификации.

Устранение Неполадок

Начните с точки, где вход останавливается, и следуйте по ветке. Gramps Web записывает причину неудачного обратного вызова (ищите OIDC callback error for provider в журнале сервера), что обычно более конкретно, чем сообщение, показанное в браузере.

1. Пропала кнопка входа?

  • Проверьте <BASE_URL>/api/oidc/config/. Если enabled равно false или providers пусто, OIDC не настроен: OIDC_ENABLED должен быть True, а пользовательский поставщик должен иметь как OIDC_ISSUER, так и OIDC_CLIENT_ID.
  • Встроенный поставщик (Google, Microsoft) регистрируется только в том случае, если установлены как его идентификатор клиента, так и его секрет клиента.
  • Посмотрите в журнал сервера при запуске на наличие Could not load discovery document. Это означает, что сервер не смог достичь <issuer>/.well-known/openid-configuration (или OIDC_OPENID_CONFIG_URL). Он повторяет попытку при первом использовании, но контейнер Gramps Web должен уметь разрешать и достигать URL-адреса эмитента сам, а не только ваш браузер.

2. Получает ли браузер ошибку сразу после отправки к поставщику?

Ошибка отображается поставщиком идентификации до того, как вы войдете.

  • "несоответствие URL-адреса перенаправления" (или аналогичное): URL-адрес перенаправления, зарегистрированный у поставщика, должен точно совпадать, включая схему, хост, порт и идентификатор поставщика. См. Обязательные URL-адреса перенаправления. Обратите внимание, что он формируется из BASE_URL, поэтому неправильный BASE_URL дает неправильный URL-адрес перенаправления.
  • Ошибка PKCE (например, invalid_request, "требуется код проверки" или отсутствующий параметр code_challenge): поставщик требует PKCE, но Gramps Web его не отправил. Перейдите к ветви PKCE ниже.

3. Поставщик принимает вход, но Gramps Web затем показывает ошибку?

  • mismatching_state, или ошибка упоминает сессию или состояние: браузер не отправил обратно cookie сессии, которую Gramps Web установил, когда вход начался. Этот cookie также содержит проверку кода PKCE. Убедитесь, что адрес в браузере совпадает с BASE_URL (та же схема и хост), что обратный прокси передает cookie и оригинальный хост, и что вход начинается и завершается в одной и той же вкладке или окне браузера.
  • OIDC authentication failed for <provider> (HTTP 401): проверьте журнал сервера на предмет основной причины. Общие причины – это неправильный секрет клиента, URL-адрес эмитента, который не совпадает с требованием iss токенов, и поставщик возвращает ошибку в обратный вызов (например, PKCE, см. ниже).
  • Слишком много попыток: конечные точки входа и обратного вызова имеют ограничение по количеству запросов (5 запросов в минуту). Подождите минуту и повторите попытку.

4. Вход успешен, но вы видите "Учетная запись на рассмотрении" или не можете ничего сделать?

Новые учетные записи создаются отключенными, если сопоставление ролей не назначает роль. См. Первый вход и начальная настройка и Поведение сопоставления ролей. Администратор также может активировать учетную запись в разделе Настройки > Администрирование > Управление пользователями.

Ветвь PKCE

Gramps Web решает, использовать ли PKCE, когда начинается вход (см. PKCE). Чтобы выяснить, что произошло в вашей настройке, пройдите через эти вопросы по порядку:

  1. Установлено ли OIDC_PKCE? (Для встроенных поставщиков – OIDC_GOOGLE_PKCE или OIDC_MICROSOFT_PKCE.)
    • True: используется PKCE. Перейдите к вопросу 3.
    • False: PKCE намеренно отключен, и документ обнаружения поставщика игнорируется. Если ваш поставщик требует PKCE, удалите настройку или установите ее в True.
    • Не установлено или пусто: продолжайте с вопроса 2.
  2. Содержит ли документ обнаружения S256? Откройте <issuer>/.well-known/openid-configuration и ищите S256 в code_challenge_methods_supported.
    • Да: PKCE используется автоматически. Продолжайте с вопроса 3.
    • Нет или поле отсутствует: PKCE не используется. Установите OIDC_PKCE в True, если ваш поставщик этого требует. Также проверьте журнал сервера на наличие Could not check the provider for PKCE support, что означает, что документ обнаружения не удалось получить, и PKCE, следовательно, был отключен.
  3. Действительно ли PKCE был отправлен? Начните вход и посмотрите на адрес страницы входа поставщика (или первое перенаправление в сетевой вкладке вашего браузера). Он должен содержать code_challenge= и code_challenge_method=S256.
    • Присутствует, но вход все равно завершается неудачей на обратном вызове: поставщик отклонил проверку кода. Cookie сессии могли быть потеряны между перенаправлением и обратным вызовом (см. ветвь 3 выше), или поставщик не поддерживает S256, в этом случае установите OIDC_PKCE в False, если поставщик не требует PKCE.
    • Отсутствует: вышеуказанные настройки не были применены. Проверьте, что переменная окружения имеет правильный префикс и значение в нижнем регистре (например, GRAMPSWEB_OIDC_PKCE=true в Docker; True не считывается как логическое значение), перезапустите сервер и снова посмотрите на конфигурацию.

Note

При включенном PKCE у поставщика как необязательном или вообще не включенном, входы работают независимо от того, отправляет ли Gramps Web вызов. Только поставщики (или клиенты), настроенные на обязательное использование PKCE, делают эту настройку важной.

Примеры Конфигураций

Пользовательский OIDC Поставщик (Keycloak)

TREE="Мое Семейное Дерево"
BASE_URL="https://mytree.example.com"
SECRET_KEY="..."  # ваш секретный ключ
USER_DB_URI="sqlite:////path/to/users.sqlite"

# Пользовательская OIDC Конфигурация
OIDC_ENABLED=True
OIDC_ISSUER="https://auth.example.com/realms/myrealm"
OIDC_CLIENT_ID="gramps-web"
OIDC_CLIENT_SECRET="ваш-секрет-клиента"
OIDC_NAME="Семейный SSO"
OIDC_SCOPES="openid email profile"
OIDC_AUTO_REDIRECT=True  # Необязательно: автоматически перенаправлять на вход SSO
OIDC_DISABLE_LOCAL_AUTH=True  # Необязательно: отключить вход по имени пользователя/паролю

# Необязательно: Сопоставление ролей из групп OIDC к ролям Gramps
OIDC_ROLE_CLAIM="groups"  # или "roles" в зависимости от вашего поставщика
OIDC_GROUP_ADMIN="gramps-admins"
OIDC_GROUP_EDITOR="gramps-editors"
OIDC_GROUP_MEMBER="gramps-members"

EMAIL_HOST="mail.example.com"
EMAIL_PORT=465
EMAIL_USE_SSL=True  # Использовать неявный SSL для порта 465
EMAIL_HOST_USER="gramps@example.com"
EMAIL_HOST_PASSWORD="..." # ваш SMTP пароль
DEFAULT_FROM_EMAIL="gramps@example.com"

Встроенный Поставщик (Google)

TREE="Мое Семейное Дерево"
BASE_URL="https://mytree.example.com"
SECRET_KEY="..."  # ваш секретный ключ
USER_DB_URI="sqlite:////path/to/users.sqlite"

# Google OAuth
OIDC_GOOGLE_CLIENT_ID="ваш-google-client-id"
OIDC_GOOGLE_CLIENT_SECRET="ваш-google-client-secret"

Несколько Поставщиков

Вы можете включить несколько OIDC-поставщиков одновременно:

TREE="Мое Семейное Дерево"
BASE_URL="https://mytree.example.com"
SECRET_KEY="..."  # ваш секретный ключ
USER_DB_URI="sqlite:////path/to/users.sqlite"

# Пользовательский поставщик
OIDC_ENABLED=True
OIDC_ISSUER="https://auth.example.com/realms/myrealm"
OIDC_CLIENT_ID="gramps-web"
OIDC_CLIENT_SECRET="ваш-секрет-клиента"
OIDC_NAME="Company SSO"

# Google OAuth
OIDC_GOOGLE_CLIENT_ID="ваш-google-client-id"
OIDC_GOOGLE_CLIENT_SECRET="ваш-google-client-secret"

# Microsoft OAuth
OIDC_MICROSOFT_CLIENT_ID="ваш-microsoft-client-id"
OIDC_MICROSOFT_CLIENT_SECRET="ваш-microsoft-client-secret"

Pocket ID

Создайте OIDC-клиента в Pocket ID с URL-адресом перенаправления <BASE_URL>/api/oidc/callback/custom (см. Обязательные URL-адреса перенаправления). Если вы включите "Требовать PKCE" для клиента, дополнительная конфигурация Gramps Web не требуется, так как Pocket ID рекламирует поддержку PKCE в своем документе обнаружения. Затем настройте:

GRAMPSWEB_OIDC_ENABLED=True
GRAMPSWEB_OIDC_ISSUER=https://id.example.com
GRAMPSWEB_OIDC_CLIENT_ID=<client id>
GRAMPSWEB_OIDC_CLIENT_SECRET=<client secret>
GRAMPSWEB_OIDC_NAME=Pocket ID

Authelia

Доступно руководство по настройке OIDC, созданное сообществом, для Gramps Web на официальном сайте документации Authelia.

Keycloak

Большую часть конфигурации для Keycloak можно оставить по умолчанию (Клиент → Создать клиента → Аутентификация клиента ВКЛ). Есть несколько исключений:

  1. Область OpenID – Область openid не включена по умолчанию во всех версиях Keycloak. Чтобы избежать проблем, добавьте ее вручную: Клиент → [Клиент Gramps] → Области клиентов → Добавить область → Имя: openid → Установить по умолчанию.
  2. Роли – Роли могут быть назначены либо на уровне клиента, либо глобально для каждого реалма.

    • Если вы используете клиентские роли, установите параметр конфигурации OIDC_ROLE_CLAIM на: resource_access.[gramps-client-name].roles
    • Чтобы сделать роли видимыми для Gramps, перейдите в Области клиентов (верхний уровень, не под конкретным клиентом), затем: Роли → Мапперы → клиентские роли → Добавить в userinfo → ВКЛ.