Авторизация

Двухуровневая модель прав в DataLens

Система прав в DataLens состоит из двух уровней, которые работают вместе и определяют доступные действия для пользователя.

Первый уровень. Глобальные роли в системе

Каждому пользователю в системе назначается одна из трех глобальных ролей. Она определяет его поведение по умолчанию в системе. У администратора есть доступ к этим настройкам в разделе Service settingsUsers.

image

  • Adminадминистратор. По умолчанию может все: управлять пользователями, настройками, видеть и редактировать любые объекты в системе.

  • Creatorсоздатель. Основная роль для аналитиков. По умолчанию может создавать подключения, датасеты и любые другие объекты в корневой папке или там, где ему дадут права.

  • Viewer/Visitorчитатель. Роль для потребителей отчетов. По умолчанию может только просматривать дашборды, к которым ему дали доступ. Не может ничего создавать.

Второй уровень. Права доступа к объектам

На любой объект в DataLens можно выдавать отдельные права:

  • Admin: полные права на данный объект и все, что внутри него, включая управление доступом к нему.

  • Editor: права на редактирование и создание объектов внутри, например в папке или воркбуке.

  • Viewer: права только на просмотр.

  • Limited Viewer: более строгая версия Viewer, без возможности навигации и просмотра структуры. Идеально для встраивания.

Как это работает вместе?

Права на объекты могут расширять возможности, заданные глобальной ролью, но только в пределах этого объекта.

Пример

Если у пользователя глобальная роль Viewer, по умолчанию он не может ничего создавать. Представьте, что ему дают права Editor на конкретный воркбук Отчеты по продажам.

Что теперь может этот пользователь

  • Создавать и редактировать дашборды и чарты внутри воркбука Отчеты по продажам.

  • Просматривать другие доступные объекты в системе.

Что НЕ может пользователь

  • Создать новый воркбук Мои отчеты, так как его глобальная роль Viewer запрещает создание объектов на верхнем уровне.

  • Создать новое подключение к базе данных, так как это глобальное действие, требующее глобальной роли Creator или Admin.

Эта модель позволяет гибко управлять доступом: давать пользователям права на создание контента только в их «песочницах» без засорения глобального пространства и выдачи лишних прав доступа.

Кейс

Пользователю назначена глобальная роль Viewer. Ему дали права Editor на воркбук Маркетинг. Какие из следующих действий он сможет выполнить?

  • Создать новый дашборд в воркбуке Маркетинг
  • Создать новое подключение к базе данных
  • Создать новый воркбук Мои личные отчеты
  • Просматривать дашборды в воркбуке Продажи при наличии доступа на просмотр
  • Создать новый дашборд в воркбуке Маркетинг

    Верно. Права Editor на воркбук позволяют создавать и редактировать объекты внутри него, расширяя глобальную роль Viewer.

  • Создать новое подключение к базе данных

    Неверно. Создание подключений — это глобальное действие, которое требует глобальной роли Creator или Admin. Его глобальная роль Viewer это запрещает, а права на воркбук здесь не действуют.

  • Создать новый воркбук Мои личные отчеты

    Неверно. Его глобальная роль Viewer запрещает создание объектов на верхнем уровне. Права Editor действуют только внутри воркбука Маркетинг.

  • Просматривать дашборды в воркбуке Продажи при наличии доступа на просмотр

    Верно. Его основная глобальная роль — Viewer, поэтому он может смотреть все, к чему ему открыт доступ.

Настройка провайдеров аутентификации

Интеграция с внешними системами настраивается через JSON-файл, который передается в init.sh с помощью флага --auth-providers-config.

./init.sh --auth-providers-config ./my-auth-providers.json

Структуру этого файла можно посмотреть в примере ./help/auth-provider-config.example.json.

Интеграция с LDAP на примере Active Directory

Рассмотрите самый частый сценарий для корпоративных сред.

В JSON-файле нужно описать, как DataLens должен находить и аутентифицировать пользователей в LDAP-каталоге.

Пример фрагмента конфигурации:

{
  "ldap-main": {
    "title": "Корпоративный вход",
    "type": "ldap",
    "params": {
      "host": "ad.mycompany.com",
      "port": 389,
      "bind-dn": "CN=svc-datalens,OU=Service,DC=mycompany,DC=com",
      "bind-pw": "SUPER-SECRET-PASSWORD",
      "user-search-base": "OU=Users,DC=mycompany,DC=com",
      "user-dn-filter": "(&(objectClass=user)(sAMAccountName=%s))",
      "user-name-attr": "sAMAccountName",
      "user-email-attr": "mail"
    }
  }
}

Отладка с ldapsearch

Прежде чем применять конфигурацию, проверьте ее параметры с помощью утилиты ldapsearch.

# Проверить, что пользователь с логином testuser находится
ldapsearch -x -H ldap://ad.mycompany.com -D "CN=svc-datalens,..." -w "SUPER-SECRET-PASSWORD" \
-b "OU=Users,DC=mycompany,DC=com" '(&(objectClass=user)(sAMAccountName=testuser))'

Если команда возвращает данные пользователя — ваши параметры верны, можно применять конфигурацию.

Интеграция по протоколу OpenID Connect (OIDC)

OIDC — это современный стандарт, используемый Keycloak, ADFS и другими IdP. Настройка проще, чем у LDAP.

{
  "oidc-main": {
    "type": "oidc",
    "title": "Войти через Keycloak",
    "params": {
      "issuer": "https://keycloak.mycompany.com/realms/master",
      "client_id": "datalens",
      "client_secret": "ANOTHER-SECRET-KEY"
    }
  }
}

issuer — это базовый URL вашего OIDC-провайдера, откуда DataLens сможет автоматически получить всю информацию (адреса эндпоинтов авторизации, токенов и так далее).

Важность UI_APP_ENDPOINT (ingress.domain)

При использовании OIDC или SAML ваш провайдер аутентификации должен знать, куда перенаправить пользователя после успешного входа. Этот адрес и есть публичный URL вашего DataLens. Система берет его из параметра ingress.domain в values.yaml.

Если ingress.domain не совпадает с реальным адресом, по которому пользователи заходят на DataLens, авторизация не будет работать — ошибка redirect_uri_mismatch.

Совет

Рекомендуется чистить куки при изменении домена, на котором развернут DataLens.

Автоматическая синхронизация групп

Вы можете настроить DataLens так, чтобы он автоматически добавлял пользователя в определенные группы на основе его атрибутов в системе LDAP. Это можно реализовать с помощью скрипта idp-sync.js, который есть в директории help.

Это позволяет централизованно управлять правами доступа через группы Active Directory, а не назначать права каждому пользователю в DataLens вручную.

Для более сложных сценариев используется отдельный Node.js-скрипт, который работает с API DataLens. Это продвинутый уровень, выходящий за рамки базовой настройки.

Скрипт синхронизации с внешним IdP

О скрипте

Для запуска необходима Node.js версии 20 и выше. У вас должен быть настроен AUTH_PROVIDERS_CONFIG — конфиг для Auth-сервиса. Рекомендуем отключить syncUserGroups в AUTH_PROVIDERS_CONFIG для IdP, если вы настроили периодическую синхронизацию с помощью данного скрипта.

Текущая версия скрипта:

  • создает новых IdP-пользователей;
  • создает новые IdP-группы;
  • обновляет членство пользователей в IdP-группах;
  • обновляет title групп;
  • обновляет роли пользователей;
  • обновляет данные профиля пользователей.

Пример запуска скрипта

node ./idp-sync.js \
    usEndpoint=https://us.domain.org \
    authEndpoint=https://auth.domain.org \
    usMasterToken=usmastertoken \
    authMasterToken=authmastertoken \
    idpSlug=someidpslug \
    idpData=./idp-data.json
  • idpSlug — slug из конфигурации IdP в Auth-сервисе;
  • usEndpoint — эндпоинт до сервиса United Storage;
  • authEndpoint — эндпоинт до Auth-сервиса;
  • usMasterTokenUS_MASTER_TOKEN, мастер-токен для сервиса United Storage;
  • authMasterTokenAUTH_MASTER_TOKEN, мастер-токен для Auth-сервиса;
  • idpData — путь до данных из IdP в формате JSON.

IdP data из источника

Подготовьте данные из IdP в формате JSON согласно AUTH_PROVIDERS_CONFIG для Auth-сервиса:

type JsonData = {
    users: {
        idpUserId: string, // внутренний ID пользователя из IdP
        login: string,
        email : string | null,
        firstName: string | null,
        lastName: string | null,
        roles: string[], // datalens.admin, datalens.creator, datalens.visitor
    }[];
    groups: {
        groupId: string, // внутренний ID группы из IdP
        title: string,
        memberIds: string[], // внутренние ID пользователей из IdP - idpUserId
    }[];
}

Пример idp-data.json для OpenLDAP:

{
  "users": [
    {
      "idpUserId": "id-bob",
      "login": "bob",
      "email" : "bob@example.org",
      "firstName": "Bob",
      "lastName": "Smith",
      "roles": ["datalens.visitor"]
    },
    {
      "idpUserId": "id-carl",
      "login": "carl",
      "email" : "carl@example.com",
      "firstName": "Carl",
      "lastName": "Snow",
      "roles": ["datalens.creator"]
    }
    ...
  ],
  "groups": [
    {
      "groupId": "id-datalensadmins",
      "title": "DataLens admins",
      "memberIds": ["id-bob", "id-carl"]
    },
    ...
  ]
}

Практика: создание конфигурации для LDAP

Подготовьте JSON-файл на основе вымышленных данных.

Дано:

  • Хост LDAP: ldap.corp.net
  • Порт: 389
  • Bind DN (сервисная учетная запись): cn=reader,dc=corp,dc=net
  • Пароль сервисной учетной записи: Read123
  • База для поиска пользователей: ou=people,dc=corp,dc=net
  • Атрибут с логином: uid

Цель: создать файл ldap-config.json с конфигурацией LDAP-провайдера.

Ответ
{
  "corporate-ldap": {
    "title": "Вход для сотрудников",
    "type": "ldap",
    "params": {
      "host": "ldap.corp.net",
      "port": 389,
      "bind-dn": "cn=reader,dc=corp,dc=net",
      "bind-pw": "Read123",
      "user-search-base": "ou=people,dc=corp,dc=net",
      "user-dn-filter": "(&(objectClass=inetOrgPerson)(uid=%s))",
      "user-name-attr": "uid",
      "user-email-attr": "mail"
    }
  }
}

Примечание: user-dn-filter может отличаться, но (uid=%s) является ключевой частью.

Итоги

Вы освоили ответственную задачу администратора — настройку авторизации. Теперь вы можете подключить DataLens к корпоративному каталогу пользователей, понимаете разницу между ролями и знаете, где искать проблему.

Предыдущая