mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
All 181 docs markdown files translated into 20 languages (apps/docs/<locale>/**). Companion to the i18n code PR; admin-merged because the file count exceeds GitHub's per-PR CI trigger limit. Validated by pnpm i18n:check (all surfaces, 0 stale/missing) and a clean all-locale docs build.
299 lines
19 KiB
Markdown
299 lines
19 KiB
Markdown
---
|
||
description: "Настройка провижининга SCIM 2.0 для синхронизации пользователей и групп из вашего поставщика идентификации в SnapOtter. Охватывает Okta, Azure AD / Entra ID и пользовательские интеграции."
|
||
i18n_source_hash: bbd50119ec12
|
||
i18n_provenance: human
|
||
i18n_output_hash: f3e5ab3ebe7f
|
||
---
|
||
|
||
# Провижининг SCIM {#scim-provisioning}
|
||
|
||
SnapOtter реализует SCIM 2.0 (System for Cross-domain Identity Management) для автоматического провижининга пользователей и групп. Ваш поставщик идентификации может создавать, обновлять, деактивировать и повторно активировать учётные записи пользователей, а также автоматически синхронизировать членство в группах.
|
||
|
||
::: tip Функция уровня Enterprise
|
||
Провижининг SCIM требует лицензии **enterprise** с функцией `scim`. Он недоступен в плане team. Без этой функции все конечные точки SCIM (кроме discovery) возвращают 403.
|
||
:::
|
||
|
||
## Предварительные требования {#prerequisites}
|
||
|
||
- Работающий экземпляр SnapOtter, доступный по публичному URL
|
||
- Ключ лицензии enterprise с функцией `scim`
|
||
- Административный доступ к SnapOtter (для генерации или отзыва токена SCIM требуется разрешение `users:manage`)
|
||
- Административный доступ к настройкам провижининга вашего поставщика идентификации
|
||
|
||
## Быстрый старт {#quick-start}
|
||
|
||
1. Сгенерируйте bearer-токен SCIM:
|
||
|
||
```bash
|
||
curl -X POST https://photos.example.com/api/v1/enterprise/scim/token \
|
||
-H "Cookie: snapotter-session=YOUR_SESSION" \
|
||
-H "Content-Type: application/json"
|
||
```
|
||
|
||
Ответ содержит токен. Сохраните его немедленно; повторно его получить нельзя.
|
||
|
||
```json
|
||
{
|
||
"token": "a1b2c3d4e5f6...",
|
||
"message": "Save this token - it cannot be retrieved again"
|
||
}
|
||
```
|
||
|
||
2. В вашем поставщике идентификации настройте провижининг SCIM со следующими параметрами:
|
||
- **Base URL**: `https://photos.example.com/api/v1/scim/v2`
|
||
- **Authentication**: Bearer-токен (вставьте токен из шага 1)
|
||
|
||
## Аутентификация {#authentication}
|
||
|
||
Конечные точки SCIM используют выделенный Bearer-токен, отдельный от пользовательских сессий и ключей API.
|
||
|
||
### Генерация токена {#generating-a-token}
|
||
|
||
`POST /api/v1/enterprise/scim/token` генерирует новый токен SCIM. Эта конечная точка требует действующей сессии с разрешением `users:manage`.
|
||
|
||
Токен возвращается в открытом виде ровно один раз. SnapOtter хранит только scrypt-хеш. Если вы потеряете токен, отзовите его и сгенерируйте новый.
|
||
|
||
Одновременно активен только один токен SCIM. Генерация нового токена заменяет предыдущий.
|
||
|
||
### Отзыв токена {#revoking-a-token}
|
||
|
||
`DELETE /api/v1/enterprise/scim/token` отзывает текущий токен SCIM. Эта конечная точка также требует `users:manage`.
|
||
|
||
### Ограничение частоты запросов {#rate-limiting}
|
||
|
||
Конечные точки SCIM ограничены 1000 запросами в минуту на токен. Превышение этого лимита возвращает HTTP 429.
|
||
|
||
## Поддерживаемые ресурсы {#supported-resources}
|
||
|
||
| Ресурс SCIM | Концепция SnapOtter | Создание | Чтение | Обновление | Удаление |
|
||
|---|---|---|---|---|---|
|
||
| User | Учётная запись пользователя | Да | Да | Да | Мягкое удаление |
|
||
| Group | Team | Да | Да | Да | Да |
|
||
|
||
::: warning
|
||
Группы SCIM сопоставляются с **командами** SnapOtter, а не с ролями. SCIM не может задать роль пользователя. Всем пользователям, созданным через SCIM, назначается роль `user`. Чтобы изменить роль пользователя, используйте админ-интерфейс SnapOtter.
|
||
:::
|
||
|
||
## Операции с пользователями {#user-operations}
|
||
|
||
### Создание пользователя {#create-user}
|
||
|
||
`POST /api/v1/scim/v2/Users`
|
||
|
||
Создаёт новую учётную запись пользователя с `authProvider`, установленным в `scim`, и ролью `user`. Пользователь назначается в команду Default. Если `active` равно `false`, роль вместо этого устанавливается в `disabled`.
|
||
|
||
Обязательные атрибуты: `userName`. Необязательные: `externalId`, `emails`, `active` (по умолчанию `true`).
|
||
|
||
### Список и фильтрация пользователей {#list-and-filter-users}
|
||
|
||
`GET /api/v1/scim/v2/Users`
|
||
|
||
Возвращает постраничный список пользователей. Поддерживает параметры запроса `startIndex` и `count` (максимум 200 результатов на страницу).
|
||
|
||
Фильтрация поддерживает только `eq` (равно) по следующим атрибутам:
|
||
|
||
- `userName eq "jane"`
|
||
- `externalId eq "ext-12345"`
|
||
|
||
Другие операторы фильтрации и атрибуты возвращают HTTP 400.
|
||
|
||
### Получение пользователя {#get-user}
|
||
|
||
`GET /api/v1/scim/v2/Users/:id`
|
||
|
||
Возвращает одного пользователя по его идентификатору пользователя SnapOtter.
|
||
|
||
### Замена пользователя {#replace-user}
|
||
|
||
`PUT /api/v1/scim/v2/Users/:id`
|
||
|
||
Заменяет атрибуты пользователя. Поддерживает `userName`, `externalId`, `emails` и `active`. Изменения имени пользователя проверяются на конфликты (409, если новое имя пользователя уже занято другим пользователем).
|
||
|
||
### Частичное обновление пользователя {#patch-user}
|
||
|
||
`PATCH /api/v1/scim/v2/Users/:id`
|
||
|
||
Частичное обновление с использованием SCIM PatchOp. Поддерживаемые операции:
|
||
|
||
| Операция | Пути |
|
||
|---|---|
|
||
| `replace` | `active`, `userName`, `externalId`, `emails`, `emails[type eq "work"].value`, `name.formatted`, `displayName` |
|
||
| `add` | То же, что и `replace` |
|
||
| `remove` | `externalId`, `emails` |
|
||
|
||
Пути `name.formatted` и `displayName` принимаются для совместимости, но не имеют постоянного эффекта (SnapOtter не хранит отдельное отображаемое имя).
|
||
|
||
Операции `replace` без значения (где значение является объектом без `path`) также поддерживаются, с ключами `userName`, `externalId`, `emails` и `active`.
|
||
|
||
### Деактивация пользователя (мягкое удаление) {#deactivate-user-soft-delete}
|
||
|
||
`DELETE /api/v1/scim/v2/Users/:id`
|
||
|
||
SnapOtter не удаляет пользователей окончательно через SCIM. Вместо этого DELETE выполняет мягкую деактивацию:
|
||
|
||
1. Роль пользователя меняется с текущего значения (например, `editor`) на `disabled:editor`, сохраняя исходную роль.
|
||
2. Пароль пользователя очищается.
|
||
3. Все активные сессии отзываются.
|
||
4. Все ключи API отзываются.
|
||
|
||
Пользователь больше не может входить в систему или использовать какие-либо ключи API. Его данные (файлы, история) сохраняются.
|
||
|
||
### Повторная активация пользователя {#reactivate-user}
|
||
|
||
Чтобы повторно активировать ранее деактивированного пользователя, отправьте запрос `PUT` или `PATCH` с `active: true`. SnapOtter восстанавливает исходную роль, существовавшую до деактивации (например, `disabled:editor` снова становится `editor`). Если исходную роль определить не удаётся, она возвращается к `user`.
|
||
|
||
::: details Пример: деактивация и повторная активация через PATCH
|
||
```json
|
||
// Deactivate
|
||
{
|
||
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
||
"Operations": [
|
||
{ "op": "replace", "path": "active", "value": false }
|
||
]
|
||
}
|
||
|
||
// Reactivate
|
||
{
|
||
"schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
|
||
"Operations": [
|
||
{ "op": "replace", "path": "active", "value": true }
|
||
]
|
||
}
|
||
```
|
||
:::
|
||
|
||
## Операции с группами {#group-operations}
|
||
|
||
Группы SCIM сопоставляются с командами SnapOtter. Создание группы создаёт команду. Членство в группе определяет, к какой команде принадлежит пользователь.
|
||
|
||
### Создание группы {#create-group}
|
||
|
||
`POST /api/v1/scim/v2/Groups`
|
||
|
||
Обязательно: `displayName`. Необязательно: `members` (массив `{ value: userId }`).
|
||
|
||
### Список и фильтрация групп {#list-and-filter-groups}
|
||
|
||
`GET /api/v1/scim/v2/Groups`
|
||
|
||
Фильтрация поддерживает только `displayName eq "..."`. Постраничный вывод с `startIndex` и `count` (максимум 200 результатов на страницу).
|
||
|
||
### Получение группы {#get-group}
|
||
|
||
`GET /api/v1/scim/v2/Groups/:id`
|
||
|
||
### Замена группы {#replace-group}
|
||
|
||
`PUT /api/v1/scim/v2/Groups/:id`
|
||
|
||
Заменяет имя группы и полный список членства. Существующие члены, отсутствующие в новом списке, перемещаются в команду Default.
|
||
|
||
### Частичное обновление группы {#patch-group}
|
||
|
||
`PATCH /api/v1/scim/v2/Groups/:id`
|
||
|
||
Поддерживает следующие операции:
|
||
|
||
| Операция | Путь | Эффект |
|
||
|---|---|---|
|
||
| `add` | `members` | Добавляет пользователей в команду |
|
||
| `remove` | `members[value eq "userId"]` | Перемещает пользователя в команду Default |
|
||
| `replace` | `displayName` | Переименовывает команду |
|
||
| `replace` | `members` | Заменяет всех членов (удалённые члены перемещаются в команду Default) |
|
||
|
||
### Удаление группы {#delete-group}
|
||
|
||
`DELETE /api/v1/scim/v2/Groups/:id`
|
||
|
||
Удаляет команду. Все члены удалённой команды перемещаются в команду Default. Пользователи не деактивируются и не удаляются.
|
||
|
||
## Настройка IdP {#idp-setup}
|
||
|
||
### Okta {#okta}
|
||
|
||
1. В консоли администратора Okta откройте своё приложение SnapOtter (или создайте новое).
|
||
2. Перейдите на вкладку **Provisioning** и нажмите **Configure API Integration**.
|
||
3. Отметьте **Enable API Integration** и введите:
|
||
- **Base URL**: `https://photos.example.com/api/v1/scim/v2`
|
||
- **API Token**: bearer-токен SCIM, сгенерированный выше
|
||
4. Нажмите **Test API Credentials**, затем **Save**.
|
||
5. В разделе **Provisioning > To App** включите:
|
||
- **Create Users**
|
||
- **Update User Attributes**
|
||
- **Deactivate Users**
|
||
6. В разделе **Push Groups** настройте, какие группы Okta синхронизировать как команды SnapOtter.
|
||
|
||
### Azure AD / Entra ID {#azure-ad-entra-id}
|
||
|
||
1. В портале Azure перейдите к вашему корпоративному приложению SnapOtter.
|
||
2. Перейдите в **Provisioning** и установите **Provisioning Mode** в **Automatic**.
|
||
3. В разделе **Admin Credentials** введите:
|
||
- **Tenant URL**: `https://photos.example.com/api/v1/scim/v2`
|
||
- **Secret Token**: bearer-токен SCIM, сгенерированный выше
|
||
4. Нажмите **Test Connection**, затем **Save**.
|
||
5. В разделе **Mappings** настройте сопоставления атрибутов пользователей и групп. Значения по умолчанию обычно работают, но убедитесь, что `userName` сопоставляется с `userPrincipalName` или `mail` по вашему усмотрению.
|
||
6. Установите **Provisioning Status** в **On** и сохраните.
|
||
|
||
Azure выполняет провижининг пользователей и групп по фиксированному циклу синхронизации (обычно каждые 40 минут).
|
||
|
||
## Конечные точки discovery {#discovery-endpoints}
|
||
|
||
Эти три конечные точки доступны без аутентификации и описывают возможности сервера SCIM:
|
||
|
||
| Конечная точка | Описание |
|
||
|---|---|
|
||
| `GET /api/v1/scim/v2/ServiceProviderConfig` | Возможности сервера и поддерживаемые функции |
|
||
| `GET /api/v1/scim/v2/Schemas` | Определения схем User и Group |
|
||
| `GET /api/v1/scim/v2/ResourceTypes` | Доступные типы ресурсов (User, Group) |
|
||
|
||
`ServiceProviderConfig` объявляет следующие возможности:
|
||
|
||
| Функция | Поддерживается |
|
||
|---|---|
|
||
| Patch | Да |
|
||
| Bulk | Нет |
|
||
| Filter | Да (максимум 200 результатов, только оператор `eq`) |
|
||
| Change password | Нет |
|
||
| Sort | Нет |
|
||
| ETag | Нет |
|
||
|
||
## Ограничения {#limitations}
|
||
|
||
- **Фильтрация**: Поддерживается только оператор `eq`. Сложные фильтры, операторы `and`/`or`, `co` (содержит) и `sw` (начинается с) не реализованы.
|
||
- **Массовые операции**: Не поддерживаются.
|
||
- **Sort и ETag**: Не поддерживаются.
|
||
- **Роли**: SCIM не может назначать роли SnapOtter. Все провизионированные пользователи получают роль `user`.
|
||
- **MAX_USERS**: Лимит переменной окружения `MAX_USERS` не применяется при создании пользователей через SCIM. Если вам нужно ограничить количество пользователей, управляйте назначениями в вашем IdP.
|
||
- **Один токен**: Одновременно может быть активен только один токен SCIM. Если нескольким IdP нужен доступ к SCIM, они должны использовать общий токен.
|
||
- **Группы соответствуют командам**: Группы SCIM соответствуют командам, а не ролям или группам разрешений.
|
||
|
||
## Устранение неполадок {#troubleshooting}
|
||
|
||
### 403 "SCIM provisioning requires an enterprise license with the scim feature" {#_403-scim-provisioning-requires-an-enterprise-license-with-the-scim-feature}
|
||
|
||
Ваша лицензия не включает функцию `scim` или лицензия не настроена. SCIM требует лицензию плана enterprise. Убедитесь, что `SNAPOTTER_LICENSE_KEY` установлена и лицензия включает функцию `scim`.
|
||
|
||
### 401 "Bearer token required" {#_401-bearer-token-required}
|
||
|
||
Запрос SCIM не содержал заголовка `Authorization: Bearer <token>`. Проверьте конфигурацию провижининга вашего IdP.
|
||
|
||
### 401 "Invalid token" {#_401-invalid-token}
|
||
|
||
Токен не совпадает с сохранённым хешем. Это происходит, если токен был отозван и перегенерирован. Обновите токен в настройках провижининга вашего IdP.
|
||
|
||
### 401 "SCIM not configured" {#_401-scim-not-configured}
|
||
|
||
Токен SCIM ещё не был сгенерирован. Используйте конечную точку `POST /api/v1/enterprise/scim/token` для его создания.
|
||
|
||
### 409 "User already exists" / "userName already taken" {#_409-user-already-exists-username-already-taken}
|
||
|
||
Пользователь с таким же именем пользователя уже существует. Это может произойти, когда IdP повторяет неудавшуюся операцию создания. Проверьте наличие дубликатов имён пользователей в панели администратора SnapOtter.
|
||
|
||
### 429 "SCIM rate limit exceeded" {#_429-scim-rate-limit-exceeded}
|
||
|
||
IdP отправляет более 1000 запросов в минуту. Обычно это происходит во время большой первоначальной синхронизации. Большинство IdP автоматически повторяют запросы после сброса окна ограничения частоты. Если проблема сохраняется, проверьте интервал синхронизации провижининга вашего IdP.
|
||
|
||
### Пользователи деповизионированы, но не удалены из интерфейса {#users-deprovisioned-but-not-removed-from-the-ui}
|
||
|
||
DELETE в SCIM выполняет мягкую деактивацию. Деактивированные пользователи по-прежнему отображаются в списке пользователей администратора со статусом «отключён». Это сделано намеренно, чтобы их данные сохранялись. Их роль отображается как `disabled:<original-role>`.
|