You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

已配置Airflow UI的Azure AD OAuth,如何适配REST API认证?

Airflow API 集成Azure AD令牌认证方案

核心思路

Airflow的API认证独立于UI的OAuth配置,需基于flask-appbuilder扩展自定义认证后端,实现Azure AD JWT令牌的验证与角色解析。

具体实现步骤

1. 安装依赖

安装令牌解析与密钥集处理工具:

pip install pyjwt python-jose[cryptography]

2. 自定义Azure AD认证类

创建azure_ad_api_auth.py文件,实现令牌验证逻辑:

from flask import request
from jose import jwt
from jose.utils import base64url_decode
import requests

class AzureADAPIAuth:
    def __init__(self, tenant_id, client_id, audience):
        self.tenant_id = tenant_id
        self.client_id = client_id
        self.audience = audience
        self.jwks_url = f"https://login.microsoftonline.com/{tenant_id}/discovery/v2.0/keys"
        self.jwks = requests.get(self.jwks_url).json()

    def authenticate(self):
        auth_header = request.headers.get('Authorization', '')
        if not auth_header.startswith('Bearer '):
            return None
        
        token = auth_header.split(' ')[1]
        try:
            # 解析令牌头获取密钥ID
            headers = jwt.get_unverified_headers(token)
            kid = headers['kid']
            # 匹配对应公钥
            rsa_key = next((key for key in self.jwks['keys'] if key['kid'] == kid), None)
            if not rsa_key:
                return None
            
            # 验证令牌签名、受众、发行方
            payload = jwt.decode(
                token,
                rsa_key,
                algorithms=["RS256"],
                audience=self.audience,
                issuer=f"https://login.microsoftonline.com/{self.tenant_id}/v2.0"
            )
            
            # 提取Azure AD分配的应用角色
            roles = payload.get('roles', [])
            if not roles:
                return None
            
            # 构造Airflow兼容的用户对象
            from flask_appbuilder.security.sqla.models import User
            user = User()
            user.username = payload.get('appid', 'azure-service-principal')
            user.roles = roles
            return user
        except Exception as e:
            print(f"Token validation failed: {str(e)}")
            return None

3. 对接Airflow API认证后端

创建custom_auth.py文件,将自定义认证类接入Airflow的API认证体系:

from airflow.api.auth.backend.base import BaseAuthBackend
from azure_ad_api_auth import AzureADAPIAuth

# 替换为你的Azure AD配置信息
AZURE_TENANT_ID = "你的租户ID"
AZURE_CLIENT_ID = "你的应用注册ID"
AZURE_AUDIENCE = "你的API受众(通常为应用注册ID或自定义标识符)"

auth = AzureADAPIAuth(AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_AUDIENCE)

class CustomAuthBackend(BaseAuthBackend):
    def authenticate(self, request):
        user = auth.authenticate()
        if user:
            return user.username, user.roles
        return None

修改airflow.cfg配置,指定自定义认证后端:

[api]
auth_backend = airflow.api.auth.backend.custom_auth

4. 角色映射配置

将Azure AD的应用角色映射到Airflow内置角色(如Admin/User/Viewer),在AzureADAPIAuth类的authenticate方法中添加映射逻辑:

ROLE_MAPPING = {
    "Airflow.Admin": "Admin",
    "Airflow.User": "User",
    "Airflow.Viewer": "Viewer"
}

# 替换原roles赋值逻辑
mapped_roles = [ROLE_MAPPING.get(role, role) for role in roles]
user.roles = mapped_roles

测试验证

使用服务主体获取Azure AD令牌并调用Airflow API:

# 获取访问令牌
TOKEN=$(curl -X POST "https://login.microsoftonline.com/你的租户ID/oauth2/v2.0/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "client_id=你的应用注册ID" \
  -d "scope=https://你的API受众/.default" \
  -d "client_secret=你的服务主体密钥" \
  -d "grant_type=client_credentials" | jq -r .access_token)

# 触发指定DAG
curl -X POST "http://你的Airflow地址/api/v1/dags/目标DAGID/dagRuns" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"conf": {}}'

注意事项

  • 确保Azure AD应用注册中已配置对应API权限,且服务主体已被分配应用角色。
  • 令牌的aud字段必须与认证类中配置的AZURE_AUDIENCE完全一致,否则验证失败。
  • 生产环境建议添加JWKS密钥集缓存,减少重复请求开销。

内容的提问来源于stack exchange,提问作者Kombajn zbożowy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 19:44:55