使用 Azure Entra ID 集成解决 Airflow 中的授权问题

Temp mail SuperHeros
使用 Azure Entra ID 集成解决 Airflow 中的授权问题
使用 Azure Entra ID 集成解决 Airflow 中的授权问题

使用 Azure Entra ID 和 Airflow 克服 OAuth 挑战

为企业应用程序配置身份验证通常是一个复杂的过程,尤其是在使用诸如 Azure 入口 ID阿帕奇气流。 🎛️ 在当今的云驱动环境中,此类集成提供了安全、集中的用户管理,但也可能带来一些技术障碍,尤其是基于 OAuth 的授权。

想象一下,您已经精心设置了一切(从 OAuth 客户端到 Azure 中的角色),并且初始身份验证无缝运行。然而,当您认为自己已准备好上线时, 授权错误 出现,让你的进度冰冷。这可能是一次令人沮丧的经历,但通过更深入地了解 Azure 的 JSON Web 密钥集 (JWKS) 要求,可以解决这一挑战。

本文解决了一个现实场景,其中设置已完成,但 Airflow 在授权阶段拒绝用户。我们将深入研究错误消息“无效的 JSON Web 密钥集”的潜在原因,并逐步完成故障排除提示以确保 成功的 OAuth 集成 在生产环境中。

通过解决这些常见问题,您将准备好优化安全设置,以获得流畅的授权访问体验。让我们深入研究,将这些错误转化为见解! 🔑

命令 使用示例
azure.authorize(callback=url_for('authorized', _external=True)) 此命令启动 OAuth 授权过程,将用户重定向到 Azure 的登录页面。回调参数指定一个函数,用于在用户通过身份验证后处理授权响应。
jwks_uri 指定 JSON Web 密钥集 (JWKS) URI 来检索 Azure 使用的公钥来验证 JWT 令牌的真实性。此设置对于确保安全令牌验证至关重要。
get_oauth_user_info 重写此方法以从身份验证期间收到的 JWT 令牌中解析和提取用户信息。它自定义授权后处理用户详细信息的方式,将令牌数据映射到 Airflow 用户属性。
authorize_url 此命令定义用于 Azure 用户授权的 URL 端点。这是 OAuth 流程开始的地方,将用户引导至登录界面以允许应用程序访问。
access_token_url 指定用于交换访问令牌的授权代码的 Azure 终结点,该令牌授予对用户配置文件的访问权限以及范围中定义的其他权限。
session.get('azure_token') 从会话存储中检索 Azure OAuth 令牌,通过在 API 请求中提供访问令牌来启用对安全终结点的访问。此命令确保令牌在会话存储中安全地存储和管理。
client_kwargs 包含 OAuth 的其他客户端配置参数。此处,client_kwargs 用于定义 openid、电子邮件和个人资料等范围,以控制应用程序可以代表用户访问的数据类型。
super().get_oauth_user_info 使用Python的super()函数通过自定义解析扩展默认的OAuth用户信息方法。这种方法允许我们处理错误和调试日志,同时维护继承的功能。
request_token_params 为初始 OAuth 请求定义额外参数。在此设置中,它指定用户请求的访问范围,这有助于在身份验证期间仅获取所需的用户数据。
window.location.href 此命令在 JavaScript 前端脚本中使用,将浏览器动态重定向到 OAuth 授权 URL。它使用特定于用户的查询参数构造 URL 以启动登录流程。

使用自定义脚本增强 Airflow 中的 OAuth 安全性

在此解决方案中,我们正在解决如何集成 Azure 入口 ID空气流动 用于基于 OAuth 的身份验证和授权。这种集成提供了一种安全且集中的方式来管理用户访问,非常适合具有复杂安全要求的组织。初始脚本的工作原理是在 Airflow 后端设置必要的 OAuth 配置,定义重要参数,例如 JWKS URI (JSON Web 密钥集 URI)以允许安全验证令牌的真实性。 “jwks_uri”的目的是从 Azure 检索公钥,这确保从 Azure 接收的 JWT(JSON Web 令牌)合法且未被篡改。这是至关重要的一步,因为未经适当验证的令牌可能会导致未经授权的访问。

该脚本还使用“authorize_url”和“access_token_url”参数,它们分别定义 Azure 中用于启动 OAuth 流和交换访问令牌的授权代码的 URL 端点。这些 URL 是引导用户完成 OAuth 流程的关键,从 Azure 登录页面开始,并在经过身份验证后将其返回到 Airflow。例如,登录公司 Airflow 仪表板的员工将被重定向到 Azure,在那里他们输入凭据。成功登录后,Azure 将用户发送回 Airflow 界面,并在后台传递访问令牌,这允许他们根据其 Azure 角色进行授权访问。

此外,脚本中的自定义安全类“AzureCustomSecurity”利用覆盖函数“get_oauth_user_info”,该函数允许 Airflow 直接从 JWT 检索特定于用户的信息。这特别有用,因为它可以自定义 Airflow 从令牌中提取的数据,包括用户名、电子邮件和组角色,这些数据与 Azure 中的角色(例如“管理员”或“查看者”)直接相关。例如,如果用户属于 Azure 中的“airflow_nonprod_admin”组,他们将被映射到 Airflow 中的“Admin”角色,从而获得管理员级别的访问权限。这种方法消除了在 Airflow 中设置额外角色的需要,使其成为组织的可扩展解决方案。

最后,JavaScript 前端脚本通过使用适当的查询参数(包括客户端 ID 和范围)将用户重定向到指定的授权 URL 来启动 OAuth 流程。这可确保只有具有特定权限(例如阅读配置文件和电子邮件)的用户才能继续执行 OAuth 流程。如果授权失败,脚本会通过友好的错误消息提醒用户,即使出现问题也能确保流畅的用户体验。这些后端和前端组件共同创建了一个连贯且安全的设置,既简化了用户访问,又增强了应用程序免受未经授权的尝试的能力——这是保护敏感组织数据的关键措施。 🔒

使用多种脚本方法解决 Airflow 中的 OAuth 授权错误

第一个解决方案 - 用于 OAuth 授权的 Python 后端脚本

# Import required modules and configure OAuth settings
import os
from flask import Flask, redirect, url_for, session
from flask_oauthlib.client import OAuth
# Define environment variables
tenant_id = os.getenv("AAD_TENANT_ID")
client_id = os.getenv("AAD_CLIENT_ID")
client_secret = os.getenv("AAD_CLIENT_SECRET")
app = Flask(__name__)
app.secret_key = 'supersecretkey'
oauth = OAuth(app)
# Define OAuth configuration with Flask-OAuthlib
azure = oauth.remote_app('azure',
    consumer_key=client_id,
    consumer_secret=client_secret,
    request_token_params={'scope': 'openid email profile'},
    base_url=f"https://login.microsoftonline.com/{tenant_id}",
    access_token_url=f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token",
    authorize_url=f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize"
)
@app.route('/login')
def login():
    return azure.authorize(callback=url_for('authorized', _external=True))
# OAuth authorization callback route
@app.route('/oauth-authorized/azure')
def authorized():
    response = azure.authorized_response()
    if response is None or response.get('access_token') is None:
        return 'Access Denied'
    # Handle successful authorization response
    session['azure_token'] = (response['access_token'], '')
    return redirect(url_for('home'))
@azure.tokengetter
def get_azure_oauth_token():
    return session.get('azure_token')
# Run the Flask app
if __name__ == '__main__':
    app.run()

替代后端方法 - 使用 JWKS 和 OpenID 进行气流配置以进行安全令牌验证

另一个后端解决方案,重点关注 Airflow 中的 OpenID Connect 和 JSON Web Key Set 配置

import os
from airflow.www.fab_security.manager import AUTH_OAUTH
# Required Airflow and custom modules for handling Azure OAuth
from airflow.auth.managers.fab.security_manager.override import FabAirflowSecurityManagerOverride
from airflow.utils.log.logging_mixin import LoggingMixin
class AzureAuthConfig:
    AAD_TENANT_ID = os.getenv('AAD_TENANT_ID')
    AAD_CLIENT_ID = os.getenv('AAD_CLIENT_ID')
    AAD_CLIENT_SECRET = os.getenv('AAD_CLIENT_SECRET')
AUTH_TYPE = AUTH_OAUTH
OAUTH_PROVIDERS = [{
    'name': 'azure',
    'remote_app': {
        'client_id': AzureAuthConfig.AAD_CLIENT_ID,
        'client_secret': AzureAuthConfig.AAD_CLIENT_SECRET,
        'authorize_url': f"https://login.microsoftonline.com/{AzureAuthConfig.AAD_TENANT_ID}/oauth2/v2.0/authorize",
        'access_token_url': f"https://login.microsoftonline.com/{AzureAuthConfig.AAD_TENANT_ID}/oauth2/v2.0/token",
        'jwks_uri': 'https://login.microsoftonline.com/common/discovery/v2.0/keys',
        'redirect_uri': 'https://airflow.xyz.com/oauth-authorized/azure'
    }},
# Ensure authentication maps to the correct role group in Azure
AUTH_ROLES_MAPPING = {
    "airflow_nonprod_admin": ["Admin"],
    "airflow_nonprod_op": ["Op"],
    "airflow_nonprod_viewer": ["Viewer"],
}

前端脚本 - 用于 OAuth 授权处理的 JavaScript

用于处理前端 OAuth 重定向和错误的 JavaScript 方法

// JavaScript function to handle authorization redirect
const authorizeUser = () => {
  const oauthUrl = 'https://login.microsoftonline.com/your-tenant-id/oauth2/v2.0/authorize';
  const params = {
    client_id: 'your-client-id',
    redirect_uri: 'https://airflow.xyz.com/oauth-authorized/azure',
    response_type: 'token',
    scope: 'openid email profile'
  };
  const queryString = new URLSearchParams(params).toString();
  window.location.href = \`\${oauthUrl}?\${queryString}\`;
};
// Handle OAuth errors in the frontend
const handleOAuthError = (error) => {
  if (error === 'access_denied') {
    alert('Access Denied. Please contact your admin.');
  } else {
    alert('An unexpected error occurred.');
  }
};
// Bind function to login button
document.getElementById('login-btn').addEventListener('click', authorizeUser);

探索 Airflow 中 Azure Entra ID 的角色映射和权限

配置时 Azure 入口 ID 用于 空气流动 环境中,建立清晰的角色映射对于有效的访问控制至关重要。角色映射可确保通过 Azure Entra ID 登录 Airflow 的用户根据其 Azure 角色分配权限,从而提供安全且可管理的方式来控制访问级别。例如,将 Azure 中的角色分配给类似的组 airflow_nonprod_admin 或者 airflow_nonprod_op 帮助将每个角色映射到特定的 Airflow 访问级别,而无需重复权限。这允许管理员直接处理 Azure 中的访问配置,从而简化了安全管理。

在此设置中, AUTH_ROLES_MAPPING 参数用于将 Azure 角色链接到 Airflow 角色,确保用户在登录时继承适当的权限。如果用户属于 airflow_nonprod_viewer 组中,他们将在 Airflow 中自动分配“查看者”角色,将其操作限制为查看工作流程和日志,而无需编辑权限。这种方法对于拥有多个团队和部门的组织特别有用,因为它可以更精细地控制用户访问,而无需持续更新 Airflow 中的各个权限。

最后,通过使用 Azure Entra ID 的应用程序注册功能,管理员可以配置符合 Airflow 角色要求的 SAML 和 OAuth 设置。例如,定义实体 ID 和回复 URL 可确保在用户身份验证时颁发正确的 OAuth 令牌。这种方法不仅增强了安全性,还优化了团队工作流程,确保只有授权用户才能主动修改 Airflow 中的任务。此类策略在大规模部署中非常有效,其中用户角色与应用程序安全策略的集成对于防止未经授权的访问至关重要。 🔐

有关将 Azure Entra ID 与 Airflow 集成的基本问题

  1. 目的是什么 AUTH_ROLES_MAPPING 气流中的参数?
  2. AUTH_ROLES_MAPPING 参数将 Azure 角色连接到 Airflow 角色,从而根据 Azure 中的组成员身份实现自动角色分配。这通过为通过 Azure Entra ID 登录的用户分配适当的权限来简化访问控制。
  3. 如何 jwks_uri 在 OAuth 设置中工作吗?
  4. jwks_uri 定义可以检索 Azure 公钥以进行 JWT 令牌验证的 URI。此步骤对于验证令牌的真实性、防止未经授权的访问至关重要。
  5. 为什么要设置 redirect_uri 在 OAuth 提供商中重要吗?
  6. redirect_uri 告诉 Azure 在身份验证成功后将用户发送到哪里。这通常设置为处理 OAuth 响应的 Airflow 端点,从而允许 Azure 和 Airflow 之间的平滑集成。
  7. 是否可以将多个角色分配给单个 Azure Entra ID 组?
  8. 是的,多个角色可以映射到单个 Azure 组,从而可以灵活地分配权限。例如,“管理员”和“查看者”角色都可以与一个组关联以实现重叠权限。
  9. 解决“无效 JSON Web 密钥集”错误的最佳方法是什么?
  10. 确保 jwks_uri 已正确配置且可访问。如果终结点无法访问或者 Azure Entra ID 密钥错误地缓存在 Airflow 中,通常会发生错误。
  11. 如何 client_kwargs 范围增强安全性?
  12. client_kwargs 范围限制了 Airflow 可以从用户配置文件访问的数据,从而强制限制对敏感信息的访问,这对于企业环境中的合规性至关重要。
  13. 是否启用 WTF_CSRF_ENABLED 提高安全性?
  14. 是的, WTF_CSRF_ENABLED 为 Airflow 提供跨站点请求伪造保护,防止未经授权的请求。强烈建议在生产环境中使用此标志以提高安全性。
  15. 如何处理被拒绝的登录请求?
  16. 检查 Azure 中的用户角色以确认它们已正确分配。另外,验证 authorize_url 和组映射是正确的,因为这些设置会影响身份验证的成功。
  17. 我可以使用与 Azure 不同的 OAuth 提供商吗?
  18. 是的,Airflow 通过调整特定于提供商的参数来支持其他 OAuth 提供商,例如 Google 或 Okta OAUTH_PROVIDERS。每个提供商可能有独特的 URL 和配置要求。

关于使用 Azure Entra ID 保护气流的最终想法

将 Azure Entra ID 与 Airflow 集成可以简化跨组织的身份验证。通过仔细配置 OAuth 参数,例如 jwks_uri 和访问令牌 URL,您正在建立安全连接,以最大限度地减少未经授权的访问风险。这种安全级别对于任何数据驱动的组织都是至关重要的。

Azure 中的角色映射允许在 Airflow 中采用可扩展的、基于角色的访问策略。通过这些映射,管理用户和分配权限变得更加高效,尤其是在较大的团队中。清楚地了解这些配置可以使您的授权设置更能适应未来的安全需求。 🔒

Azure 和 Airflow 集成的主要来源和参考
  1. 有关集成的 Microsoft 文档 Azure 活动目录 用于企业身份验证和访问管理的 OAuth。
  2. Apache Airflow 的官方指南 OAuth 和安全配置 ,以及有关配置外部授权方法的见解。
  3. Helm 的详细部署图表文档 气流头盔图 ,专注于 Kubernetes 环境中的安全部署实践。
  4. 来自用于集成的 Python Flask-OAuth 库的见解 Flask OAuthlib 使用 Azure Entra ID,这是用于管理基于 Python 的应用程序中的令牌流和用户授权的关键资源。
  5. 有关处理的 Azure AD 故障排除资源 OAuth 相关错误 ,特别关注与 JSON Web 密钥集和令牌验证相关的问题。