yupanzi

应用集成 Authentik OAuth 认证指南

· 4 分钟阅读

本文整合了多个常用应用集成 Authentik OAuth 认证的配置方法,包括 Airflow、Grafana 和 JupyterHub。

通用 Authentik 配置

在 Authentik 中创建 OAuth2/OpenID 应用时,需要配置以下端点:

端点URL 格式
授权https://authentik.example.com/application/o/authorize/
Tokenhttps://authentik.example.com/application/o/token/
UserInfohttps://authentik.example.com/application/o/userinfo/
元数据https://authentik.example.com/application/o/{app}/.well-known/openid-configuration

重要提示userinfo 端点的路径必须带斜杠 /userinfo/,否则会报错。


Airflow 集成

版本信息

  • App Version: 2.8.3
  • Chart Version: 1.13.1

OAuth 认证配置

webserver_config.py:

from flask_appbuilder.security.manager import AUTH_OAUTH
from airflow.auth.managers.fab.security_manager.override import FabAirflowSecurityManagerOverride

AUTH_TYPE = AUTH_OAUTH
AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "User"  # 默认角色

OAUTH_PROVIDERS = [
    {
        "name": "OAuth",
        "icon": "fa-circle-o",
        "token_key": "access_token",
        "remote_app": {
            "client_id": "your-client-id",
            "api_base_url": "https://authentik.example.com/application/o/",
            "client_secret": "your-client-secret",
            "client_kwargs": {"scope": "openid email profile"},
            "server_metadata_url": "https://authentik.example.com/application/o/oauth/.well-known/openid-configuration",
        },
    }
]

PERMANENT_SESSION_LIFETIME = 259200  # 3 天


class CustomSecurityManager(FabAirflowSecurityManagerOverride):
    def get_oauth_user_info(self, provider, resp):
        if provider != "OAuth":
            return {}

        # 关键:必须是 userinfo/ 而不是 userinfo
        me = self.appbuilder.sm.oauth_remotes[provider].get("userinfo/")
        data = me.json()

        return {
            "email": data["email"],
            "username": data.get("name", ""),
            "first_name": data.get("given_name", ""),
            "role_keys": data.get("groups", []),  # 支持组映射
        }


SECURITY_MANAGER_CLASS = CustomSecurityManager

LDAP 认证配置(备选)

from flask_appbuilder.security.manager import AUTH_LDAP

AUTH_TYPE = AUTH_LDAP
AUTH_LDAP_SERVER = "ldap://ldap.example.com"
AUTH_LDAP_USE_TLS = False

AUTH_USER_REGISTRATION = True
AUTH_USER_REGISTRATION_ROLE = "Admin"

AUTH_LDAP_LASTNAME_FIELD = "cn"
AUTH_LDAP_EMAIL_FIELD = "mail"
AUTH_LDAP_SEARCH = "ou=foo,ou=People,dc=example,dc=com"
AUTH_LDAP_UID_FIELD = "uid"
AUTH_LDAP_BIND_USER = "cn=admin,dc=example,dc=com"
AUTH_LDAP_BIND_PASSWORD = "adminPassword"

AUTH_ROLES_MAPPING = {
    "cn=g-admin,ou=Group,dc=example,dc=com": ["Admin"],
}

AUTH_LDAP_GROUP_FIELD = "memberOf"
AUTH_ROLES_SYNC_AT_LOGIN = True
PERMANENT_SESSION_LIFETIME = 86400

API 认证

config:
  api:
    auth_backends: "airflow.api.auth.backend.basic_auth"

Grafana 集成

OAuth 认证配置

grafana.ini:

grafana:
  grafana.ini:
    auth:
      oauth_allow_insecure_email_lookup: true

    auth.generic_oauth:
      enabled: true
      name: "OAuth"
      client_id: "your-client-id"
      client_secret: "your-client-secret"
      scopes: "openid email profile offline_access"
      auth_url: "https://authentik.example.com/application/o/authorize/"
      token_url: "https://authentik.example.com/application/o/token/"
      api_url: "https://authentik.example.com/application/o/userinfo/"
      use_pkce: true
      use_refresh_token: true
      allow_sign_up: false
      allow_assign_grafana_admin: true
      auto_login: true
      skip_org_role_sync: true

    server:
      root_url: "https://grafana.example.com/"  # 必须正确配置

关键配置说明

配置项说明注意事项
root_urlGrafana 访问地址必须与实际域名一致,否则会重定向失败
oauth_allow_insecure_email_lookup邮箱查找使用邮箱匹配用户时需设为 true
use_pkcePKCE 支持增强安全性

LDAP 认证配置(备选)

grafana:
  ldap:
    enabled: true
    config: |
      verbose_logging = true

      [[servers]]
      host = "ldap.example.com"
      port = 389
      use_ssl = false
      bind_dn = "cn=admin,dc=example,dc=com"
      bind_password = "examplePassword"
      search_filter = "(uid=%s)"
      search_base_dns = ["ou=foo,dc=example,dc=com"]

      [servers.attributes]
      name = "cn"
      surname = "sn"
      username = "uid"
      email = "mail"

      [[servers.group_mappings]]
      group_dn = "cn=g-admin,ou=Group,dc=example,dc=com"
      org_role = "Editor"

JupyterHub 集成

OAuth 认证配置

values.yaml:

hub:
  config:
    Authenticator:
      admin_users:
        - "admin"
      allow_all: true
      auto_login: true

    GenericOAuthenticator:
      client_id: "your-client-id"
      client_secret: "your-client-secret"
      login_service: "OAuth"
      authorize_url: "https://authentik.example.com/application/o/authorize/"
      token_url: "https://authentik.example.com/application/o/token/"
      userdata_url: "https://authentik.example.com/application/o/userinfo/"
      oauth_callback_url: "https://jupyter.example.com/hub/oauth_callback"
      scope:
        - "openid"
        - "email"
        - "profile"
      username_claim: "sub"

    JupyterHub:
      authenticator_class: "generic-oauth"
      admin_access: true

配置说明

配置项说明可选值
allow_all是否允许所有用户true / false
username_claim用户名字段sub / email / preferred_username
oauth_callback_url回调地址必须在 Authentik 中配置

LDAP 认证配置(备选)

hub:
  config:
    LDAPAuthenticator:
      server_address: "ldap.example.com"
      use_ssl: true
      bind_dn_template:
        - "uid={username},ou=foo,ou=People,dc=example,dc=com"
      escape_userdn: true

    JupyterHub:
      authenticator_class: "ldapauthenticator.LDAPAuthenticator"

OAuth vs LDAP 对比

特性OAuthLDAP
配置复杂度简单中等
统一登录(SSO)✅ 支持❌ 不支持
离线访问✅ Refresh Token❌ 需在线验证
安全性✅ PKCE 增强一般
适用场景现代 SSO 架构传统 LDAP 环境

常见问题

userinfo 路径问题

Authentik 的 userinfo 端点必须是 /userinfo/(带斜杠),否则会报错:

ERROR - OAUTH userinfo does not have username or email {}

重定向 URI 不匹配

Grafana 报错 redirect_uri_mismatch:确保 root_url 与实际访问域名一致。

回调地址配置

JupyterHub 的 oauth_callback_url 必须在 Authentik 应用的”重定向 URI”中添加。


参考文档

相关文章