Настройка аутентификации JWT

Вы можете настроить Grafana так, чтобы она принимала токен JWT, предоставленный в заголовке HTTP. Токен проверяется с помощью любого из следующих средств:

  • Файл ключа в кодировке PEM
  • JSON Web Key Set (JWKS) в локальном файле
  • JWKS, предоставленный настроенной конечной точкой JWKS

Этот метод аутентификации полезен для интеграции с другими системами, которые используют JWKS, но не могут напрямую интегрироваться с Grafana, или если вы хотите использовать сквозную аутентификацию (pass-through) в приложении, встраивающем Grafana.

Note

Grafana в настоящее время не поддерживает refresh-токены.

Включение JWT

Чтобы использовать аутентификацию JWT:

  1. Включите JWT в основном файле конфигурации.
  2. Укажите имя заголовка, который содержит токен.
ini
[auth.jwt]
# By default, auth.jwt is disabled.
enabled = true

# HTTP header to look into to get a JWT token.
header_name = X-JWT-Assertion

Настройка утверждения логина

Чтобы идентифицировать пользователя, некоторые из утверждений должны быть выбраны в качестве информации для входа. Утверждение subject под названием "sub" является обязательным и должно идентифицировать субъект (principal), который является субъектом JWT.

Обычно утверждение subject под названием "sub" используется в качестве логина, но оно также может быть установлено как какое-либо специфичное для приложения утверждение.

ini
# [auth.jwt]
# ...

# Specify a claim to use as a username to sign in.
username_claim = sub

# Specify a claim to use as an email to sign in.
email_claim = sub

# auto-create users if they are not already matched
# auto_sign_up = true

Если auto_sign_up включён, то утверждение sub используется как “external Auth ID”. Утверждение name используется как полное имя пользователя, если оно присутствует.

Кроме того, если логин пользователя или утверждения email вложены внутрь структуры JWT, вы можете указать путь к атрибутам с помощью параметров конфигурации username_attribute_path и email_attribute_path, используя синтаксис JMESPath.

Пример структуры JWT.

JSON
{
  "user": {
    "UID": "1234567890",
    "name": "John Doe",
    "username": "johndoe",
    "emails": ["personal@example.com", "professional@example.com"]
  }
}
ini
# [auth.jwt]
# ...

# Specify a nested attribute to use as a username to sign in.
username_attribute_path = user.username # user's login is johndoe

# Specify a nested attribute to use as an email to sign in.
email_attribute_path = user.emails[1] # user's email is professional@example.com

Встраивание в iframe

Если вы хотите встроить Grafana в iframe, сохраняя при этом проверки идентичности и ролей пользователя, вы можете использовать аутентификацию JWT для аутентификации iframe.

Note

Для Grafana Cloud или в сценариях, где проверка идентичности зрителя не требуется, встраивайте общие дашборды.

В этом сценарии вам нужно будет настроить Grafana на приём JWT, предоставленного в заголовке HTTP, а обратный прокси должен переписывать запросы к экземпляру Grafana так, чтобы включать JWT в заголовки запроса.

Note

Чтобы встраивание работало, вы должны включить allow_embedding в разделе безопасности. Этот параметр недоступен в Grafana Cloud.

В сценарии, где невозможно переписать заголовки запроса, вы можете вместо этого использовать вход по URL.

Вход по URL

url_login позволяет Grafana искать JWT в параметре запроса URL auth_token и использовать его как токен аутентификации.

Note

Вам нужно включить JWT перед установкой этого параметра. См. Включение JWT.

Warning

Это может привести к раскрытию JWT в логах и возможному перехвату сессии, если сервер не использует HTTP поверх TLS.

ini
# [auth.jwt]
# ...
url_login = true # enable JWT authentication in the URL

Пример URL для доступа к Grafana с аутентификацией JWT по URL:

http://env.grafana.local/d/RciOKLR4z/board-identifier?orgId=1&kiosk&auth_token=eyJhbxxxxxxxxxxxxx

Образец репозитория, использующего этот метод аутентификации, доступен по адресу grafana-iframe-oauth-sample.

Проверка подписи

Целостность JSON web token должна быть проверена, для этой цели используется криптографическая подпись. Поэтому мы ожидаем, что каждый токен должен быть подписан некоторым известным криптографическим ключом.

У вас есть множество вариантов того, как указать, где расположены ключи.

Проверка токена с помощью JSON Web Key Set, загруженного с конечной точки https

Дополнительную информацию о конечных точках JWKS см. в документации Auth0.

ini
# [auth.jwt]
# ...

jwk_set_url = https://your-auth-provider.example.com/.well-known/jwks.json

# When the JWKS url requires an 'Authorization: Bearer <TOKEN>' header
# jwk_set_bearer_token_file = /path/to/bearer_token

# Cache duration for https endpoint response.
cache_ttl = 60m

# Path to file containing one or more custom PEM-encoded CA certificates.
# Used with jwk_set_url when the JWKS endpoint uses a certificate that is not
# trusted by the default CA bundle (e.g. self-signed certificates).
# tls_client_ca = /path/to/ca.crt

# Skip CA Verification entirely
# tls_skip_verify_insecure = false

Note

Если конечная точка JWKS включает заголовки управления кэшем и значение меньше настроенного cache_ttl, то вместо этого используется значение заголовка управления кэшем. Если cache_ttl не задан, используется значение по умолчанию 60m. Заголовки управления кэшем no-store и no-cache игнорируются. Чтобы отключить кэширование JWKS, установите cache_ttl = 0s

Проверка токена с помощью JSON Web Key Set, загруженного из JSON-файла

Набор ключей в том же формате, что и в конечной точке JWKS, но расположенный на диске.

ini
jwk_set_file = /path/to/jwks.json

Проверка токена с помощью одного ключа, загруженного из файла в кодировке PEM

Файл публичного ключа в кодировке PEM в формате PKIX или PKCS #1. Приватные ключи не принимаются.

ini
key_file = /path/to/key.pem

Если заголовок токена JWT указывает kid (Key ID), то Key ID должен быть установлен с помощью параметра конфигурации key_id.

ini
key_id = my-key-id

Проверка токена с помощью встроенного ключа или набора ключей

Если вы не можете разместить файл на диске, поместите материал ключа непосредственно в конфигурацию. Это полезно, когда вы провижините конфигурацию управляемому экземпляру. Оба варианта используют то же содержимое, что и их файловые аналоги, в кодировке base64, чтобы оно помещалось в одну строку.

Встройте один публичный ключ в кодировке PEM вместо key_file:

ini
key_value = <base64-encoded PEM key>

Встройте документ JWKS вместо jwk_set_file:

ini
jwk_set_value = <base64-encoded JWKS JSON>

Чтобы сгенерировать значение из существующего файла, выполните base64 < key.pem | tr -d '\n'. Параметр key_id применяется к key_value так же, как и к key_file.

Note

Настройте набор ключей ровно с помощью одного из: key_file, key_value, jwk_set_file, jwk_set_value или jwk_set_url. Установка более одного является ошибкой.

Валидация утверждений

По умолчанию проверяются только утверждения "exp", "nbf" и "iat".

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

ini
# This can be seen as a required "subset" of a JWT Claims Set.
expect_claims = {"iss": "https://your-token-issuer", "your-custom-claim": "foo"}

Роли

Grafana проверяет наличие роли, используя JMESPath, заданный через параметр конфигурации role_attribute_path. JMESPath применяется к утверждениям токена JWT. Результат после вычисления выражения JMESPath role_attribute_path должен быть допустимой ролью Grafana, например None, Viewer, Editor или Admin.

Чтобы назначить роль конкретной организации, включите заголовок X-Grafana-Org-Id вместе с вашим JWT при выполнении запросов API к Grafana. Чтобы узнать больше о заголовке, см. документацию.

Настройка сопоставления ролей

Если только не включён параметр skip_org_role_sync, роль пользователя будет установлена в роль, полученную из JWT.

Роль пользователя извлекается с помощью выражения JMESPath из параметра конфигурации role_attribute_path. Чтобы сопоставить роль администратора сервера, используйте параметр конфигурации allow_assign_grafana_admin.

Если допустимая роль не найдена, пользователю назначается роль, указанная параметром auto_assign_org_role. Вы можете отключить это назначение роли по умолчанию, установив role_attribute_strict = true. Этот параметр запрещает доступ пользователю, если не возвращена роль или возвращена недопустимая роль после вычисления выражений role_attribute_path и org_mapping.

Вы можете использовать параметры конфигурации org_attribute_path и org_mapping для назначения пользователя организациям и указания его роли. Дополнительную информацию см. в разделе Пример сопоставления ролей организации. Если указаны и сопоставление роли организации (org_mapping), и обычное сопоставление роли (role_attribute_path), то пользователь получит более высокую из двух сопоставленных ролей.

Чтобы упростить настройку правильного выражения JMESPath, перейдите на JMESPath, чтобы протестировать и оценить выражения с пользовательскими полезными нагрузками.

Базовый пример:

В следующем примере пользователь получит Editor в качестве роли при аутентификации. Значение свойства role будет результирующей ролью, если роль является правильной ролью Grafana, то есть None, Viewer, Editor или Admin.

Полезная нагрузка:

JSON
{
    ...
    "role": "Editor",
    ...
}

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

ini
role_attribute_path = role

Расширенный пример:

В следующем примере пользователь получит Admin в качестве роли при аутентификации, поскольку у него есть роль admin. Если у пользователя есть роль editor, он получит Editor в качестве роли, в противном случае Viewer.

Полезная нагрузка:

JSON
{
    ...
    "info": {
        ...
        "roles": [
            "engineer",
            "admin",
        ],
        ...
    },
    ...
}

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

ini
role_attribute_path = contains(info.roles[*], 'admin') && 'Admin' || contains(info.roles[*], 'editor') && 'Editor' || 'Viewer'

Пример сопоставления ролей организации

В следующем примере пользователю предоставлена роль Viewer в организации org_foo и роль Editor в организациях org_bar и org_baz.

Полезная нагрузка:

JSON
{
    ...
    "info": {
        ...
        "orgs": [
            "engineer",
            "admin",
        ],
        ...
    },
    ...
}

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

ini
org_attribute_path = info.orgs
org_mapping = engineer:org_foo:Viewer admin:org_bar:Editor *:org_baz:Editor

Роль администратора Grafana

Если свойство role_attribute_path возвращает роль GrafanaAdmin, администратор Grafana не назначается по умолчанию, вместо этого назначается роль Admin. Чтобы разрешить назначение роли Grafana Admin, установите allow_assign_grafana_admin = true.

Пропуск сопоставления ролей организации

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

ini
[auth.jwt]
# ...

skip_org_role_sync = true