1. 项目背景与核心需求
最近在数据平台升级过程中,我们需要将Airflow从2.x版本迁移到3.1.5版本。新版本最显著的变化之一就是API认证机制的全面重构——从原先的基础认证升级为基于JWT(JSON Web Token)的标准化认证流程。这个改动虽然提升了安全性,但官方文档对具体实现细节的描述比较分散,我在实际配置过程中踩了不少坑。
Airflow 3.1.5的API认证主要解决两个核心问题:
- 替代旧版不安全的Basic Auth认证方式
- 提供可扩展的标准化认证接口,支持与现有SSO系统的集成
2. 环境准备与前置条件
2.1 基础环境要求
在开始配置前,请确保你的环境满足以下条件:
- 已安装Airflow 3.1.5(通过
pip install apache-airflow==3.1.5安装) - 数据库后端使用PostgreSQL/MySQL(SQLite不支持部分认证功能)
- 已配置好Airflow的核心参数如
AIRFLOW_HOME、AIRFLOW__CORE__SQL_ALCHEMY_CONN
重要提示:如果是从旧版升级而来,务必先备份
airflow.cfg和元数据库。我在升级过程中遇到过元数据表结构不兼容导致API服务无法启动的情况。
2.2 关键配置参数说明
在airflow.cfg中需要关注这些参数:
ini复制[api]
auth_backends = airflow.api.auth.backend.basic_auth,airflow.api.auth.backend.session
enable_experimental_api = true
新版本默认启用了实验性API,但认证方式需要显式配置。这里有个坑点:如果同时配置了多个auth_backends,实际生效的顺序是从右往左。
3. JWT认证详细配置
3.1 生成密钥对
JWT认证需要RSA密钥对,建议使用4096位密钥:
bash复制# 生成私钥
openssl genrsa -out jwt_private_key.pem 4096
# 导出公钥
openssl rsa -in jwt_private_key.pem -pubout -out jwt_public_key.pem
将生成的密钥文件放在${AIRFLOW_HOME}/certs目录下,并设置适当权限:
bash复制chmod 600 ${AIRFLOW_HOME}/certs/jwt_*.pem
chown airflow:airflow ${AIRFLOW_HOME}/certs/jwt_*.pem
3.2 配置Airflow参数
在airflow.cfg中添加以下配置:
ini复制[api]
auth_backends = airflow.api.auth.backend.jwt
jwt_secret_key = file://${AIRFLOW_HOME}/certs/jwt_public_key.pem
jwt_private_key = file://${AIRFLOW_HOME}/certs/jwt_private_key.pem
jwt_algorithm = RS256
jwt_issuer = airflow
jwt_audience = airflow
参数说明:
jwt_secret_key:公钥路径,需带file://前缀jwt_private_key:私钥路径,用于签发tokenjwt_algorithm:推荐使用RS256而非HS256(更安全)issuer和audience:用于验证token的发行方和目标受众
4. 认证流程实现
4.1 获取JWT Token
可以通过以下curl命令获取token:
bash复制curl -X POST \
http://localhost:8080/api/v1/auth/login \
-H 'Content-Type: application/json' \
-d '{
"username": "admin",
"password": "your_password"
}'
成功响应示例:
json复制{
"access_token": "eyJhbG...",
"expires_at": "2023-07-20T12:00:00Z",
"refresh_token": "eyJhbG...",
"refresh_expires_at": "2023-07-27T12:00:00Z"
}
4.2 使用Token调用API
获取token后,在请求头中加入Authorization:
bash复制curl -X GET \
http://localhost:8080/api/v1/dags \
-H 'Authorization: Bearer eyJhbG...'
5. 高级配置与优化
5.1 Token有效期调整
默认token有效期为15分钟,可以通过以下配置调整:
ini复制[api]
jwt_access_token_expires = 3600 # 单位:秒
jwt_refresh_token_expires = 86400
5.2 自定义Claims
可以在airflow_local_settings.py中添加自定义claims:
python复制def jwt_extra_claims(actor):
return {
"role": "admin",
"department": "data_engineering"
}
然后在配置中启用:
ini复制[api]
jwt_custom_claims_handler = airflow_local_settings.jwt_extra_claims
6. 常见问题排查
6.1 认证失败错误
问题现象:
code复制HTTP/1.1 401 Unauthorized
{"detail":"Could not validate credentials"}
排查步骤:
- 检查
jwt_public_key和jwt_private_key路径是否正确 - 确认密钥文件权限(airflow用户可读)
- 验证token是否过期(可通过jwt.io解码查看)
6.2 跨域问题处理
如果前端调用API遇到CORS问题,需要添加配置:
ini复制[api]
enable_cors = True
cors_origins = *
7. 安全最佳实践
- 密钥轮换:建议每月轮换一次密钥对,旧密钥保留24小时用于过渡
- HTTPS强制:生产环境必须启用HTTPS,防止token被截获
- IP白名单:结合
[api]下的allow_hosts限制访问源 - 审计日志:开启
[logging]中的remote_logging记录API访问日志
我在实际部署中发现,当API调用频率过高时(>1000次/分钟),JWT验证会成为性能瓶颈。这时可以考虑:
- 使用更高效的算法如RS512
- 在负载均衡层做JWT预验证
- 对高频接口启用本地缓存验证结果
8. 与CI/CD系统集成示例
以下是通过Python脚本获取token并触发DAG的示例:
python复制import requests
from requests.auth import HTTPBasicAuth
# 获取token
auth_url = "http://airflow.example.com/api/v1/auth/login"
resp = requests.post(
auth_url,
json={"username": "ci_cd_user", "password": "s3cr3t"},
headers={"Content-Type": "application/json"}
)
token = resp.json()["access_token"]
# 触发DAG
trigger_url = "http://airflow.example.com/api/v1/dags/example_dag/dagRuns"
requests.post(
trigger_url,
json={"conf": {"env": "production"}},
headers={"Authorization": f"Bearer {token}"}
)
建议为CI/CD系统创建专用账号,并限制其权限:
sql复制-- 在Airflow元数据库中执行
INSERT INTO ab_user (username, password, is_active)
VALUES ('ci_cd_user', 'pbkdf2_sha256$...', true);
INSERT INTO ab_user_role (user_id, role_id)
VALUES (
(SELECT id FROM ab_user WHERE username = 'ci_cd_user'),
(SELECT id FROM ab_role WHERE name = 'User')
);
9. 性能监控建议
配置Prometheus监控API性能指标:
yaml复制# prometheus.yml 配置示例
scrape_configs:
- job_name: 'airflow_api'
metrics_path: '/metrics'
static_configs:
- targets: ['airflow-webserver:8080']
关键监控指标:
airflow_api_request_duration_seconds:API响应时间airflow_api_jwt_validation_time:JWT验证耗时airflow_api_failed_authentications_total:认证失败次数
10. 扩展功能实现
10.1 多因素认证集成
可以在airflow_local_settings.py中扩展认证逻辑:
python复制from airflow.api.auth.backend.jwt import JwtAuthentication
class MFAJwtAuthentication(JwtAuthentication):
def authenticate(self, request):
user = super().authenticate(request)
if not validate_mfa(request.headers.get('X-MFA-Token')):
raise AirflowApiException('MFA validation failed')
return user
然后在配置中替换auth_backend:
ini复制[api]
auth_backends = airflow_local_settings.MFAJwtAuthentication
10.2 速率限制配置
使用Flask-Limiter添加API限流:
python复制# 在airflow_local_settings.py中添加
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address
limiter = Limiter(
key_func=get_remote_address,
default_limits=["200 per minute", "50 per second"]
)
def init_limiter(app):
limiter.init_app(app)
在webserver_config.py中初始化:
python复制from airflow_local_settings import init_limiter
init_limiter(app)