oauth2-proxy 对接 Azure AD(azure 遗留 Provider):应用注册全流程、V1/V2 端点配置与源码实现解析
2026/9/14 6:04:38 网站建设 项目流程

oauth2-proxy 对接 Azure AD(azure 遗留 Provider):应用注册全流程、V1/V2 端点配置与源码实现解析

【免费下载链接】oauth2-proxyA reverse proxy that provides authentication with Google, Azure, OpenID Connect and many more identity providers.项目地址: https://gitcode.com/GitHub_Trending/oa/oauth2-proxy

oauth2-proxy 内置了名为azure的身份提供商,用于对接 Azure Active Directory(Azure AD)完成反向代理层的单点登录认证。本篇基于 7.10.x 版本文档,完整还原从 Azure 门户注册应用、配置 Microsoft Graph 权限、创建客户端密钥,到使用--provider=azure配合 V1 或 V2.0 端点配置代理的全部实操步骤,并结合 providers/azure.go 的源码实现,解释--azure-tenant--resource两个专属参数在登录、换票、会话校验各环节的真实行为。读完本文,你可以独立完成该 Provider 的部署配置,并理解 V1 与 V2 端点在 scope、resource 参数处理上的源码级差异。

定位说明:一个已进入弃用路径的遗留 Provider

7.10.x 版本文档在 ms_azure_ad.md 开头明确标注:azure是 Azure 的 legacy(遗留)且已弃用(deprecated)的提供商,文档建议尽可能改用功能更完整的 Microsoft Entra ID Provider。两者在代码层都是独立的实现:providers/azure.go 中的AzureProvider基于 Azure AD 端点(V1/V2 OAuth 端点)直接工作,而 Entra ID Provider 则是完全遵循 OIDC 规范、支持组超额(group overage)与多租户应用的新一代实现。对于存量仍在使用--provider=azure的部署,本文的内容即为权威的运维参考。

Provider 专属配置项

azureProvider 在通用 OAuth 配置(--provider--client-id--client-secret等)之外,只有两个专属配置项:

FlagToml 字段类型说明默认值
--azure-tenantazure_tenantstring指定租户专属(tenant-specific)或通用(common,租户无关)端点"common"
--resourceresourcestring受保护的资源(仅限 Azure AD)(空)

从源码结构可以确认这两个参数的定义位置:

  • 命令行标志在 pkg/apis/options/legacy_options.go 中注册,azure-tenant的默认值即"common",帮助文案与文档表格完全一致;resource的帮助文案为 "The resource that is protected (Azure AD only)"。
  • V2 配置结构体AzureOptions定义在 pkg/apis/options/providers.go,其中包含Tenant(默认'common')与GraphGroupField(默认'id',用于从 Microsoft Graph 构建组列表时取用的字段)。
  • Provider 实例化入口在 providers/providers.go,当--provider=azure时调用NewAzureProvider并传入上述AzureConfig

第一步:在 Azure 门户注册应用

  1. 登录 Azure 门户,选择Azure Active Directory,进入App registrations,点击New registration
  2. 填写应用名称,选择支持的账户类型(single-tenant、multi-tenant 等)。在Redirect URI部分,为每个受 oauth2-proxy 保护的应用创建一条Web平台回调地址,例如https://internal.yourcompany.com/oauth2/callback,然后点击Register

回调地址由 oauth2-proxy 的--redirect-url决定,默认即<外部访问地址>/oauth2/callback,需与门户中登记的 URI 精确一致,否则换票时redirect_uri校验会失败——这一点可以从 providers/azure.go 的prepareRedeem中得到印证:换票请求会把redirect_uriclient_idclient_secretcodegrant_type=authorization_code以表单方式提交到 Redeem URL。

第二步:授予 Microsoft Graph 组读取权限

在应用的API Permissions页面,点击Add a permission,选择Microsoft Graph,再选择Application permissions,点击Group并选择Group.Read.All,点击Add permissions,最后点击Grant admin consent(这一步可能必须由租户管理员执行)。

文档在此处特别强调了一条生产环境常见坑位:

即使该权限在界面上显示 "Admin consent required=No",实际仍可能需要管理员同意——由于 AAD 中你无法看到的策略,这种要求不会显式呈现。如果你登录时遇到 "Need admin approval" 报错,最可能就是缺少这一步的权限授予。

从源码看,组信息正是依赖 Microsoft Graph 拉取的:AzureProvider的 V2 端点路径会调用GET /v1.0/me/transitiveMemberOf(见 providers/azure.go 的getMicrosoftGraphGroupsURL),携带$count=true&$filter=securityEnabled+eq+true过滤条件只选取安全组,并以ConsistencyLevel: eventual请求头 + Bearer 访问令牌分页读取(@odata.nextLink)全部组,取组名时使用的字段由GraphGroupField决定(默认id,可选displayName)。没有 Group.Read.All 权限,这条链路在组超过 ID token 携带能力时就会取不到数据。

第三步(仅 V2.0 端点):设置 accessTokenAcceptedVersion

如果计划使用 v2.0 Azure Auth 端点(Microsoft Identity Platform 端点),需进入应用的Manifest页面,在应用清单中设置"accessTokenAcceptedVersion": 2。该设置控制 AAD 签发的访问令牌版本,与 V2.0 端点的 JWT 校验体系配套。

第四步:创建客户端密钥

在应用的Certificates & secrets页面添加一条新的 client secret,并在点击Add之后立即记下密钥值(此后只能看到掩码,无法再次完整查看)。该值将填入--client-secret

oauth2-proxy 代理配置:V1 与 V2 端点

V1 Azure Auth 端点

对应 Azure Active Directory 端点https://login.microsoftonline.com/common/oauth2/authorize,配置示例:

--provider=azure --client-id=<应用注册时的 application ID> --client-secret=<第四步创建的客户端密钥值> --azure-tenant={tenant-id} --oidc-issuer-url=https://sts.windows.net/{tenant-id}/

注意这里--oidc-issuer-url指向的是sts.windows.net/{tenant-id}/——启用该选项后,oauth2-proxy 会通过 OIDC verifier 校验令牌签名与签发方,这正是--resource参数生效的前提之一。

V2 Azure Auth 端点

对应 Microsoft Identity Platform 端点https://login.microsoftonline.com/common/oauth2/v2.0/authorize,配置示例:

--provider=azure --client-id=<应用注册时的 application ID> --client-secret=<第四步创建的客户端密钥值> --azure-tenant={tenant-id} --oidc-issuer-url=https://login.microsoftonline.com/{tenant-id}/v2.0

两个示例中,--client-id对应 Azure 门户应用注册信息里的Application (client) ID--azure-tenant填入租户 ID 或域名以将端点从common切换为租户专属端点。

源码解读:两个端点为何行为不同

providers/azure.go 的NewAzureProvider揭示了 V1/V2 的分野机制:

  1. 端点默认值:未显式指定时,Login URL 为https://login.microsoftonline.com/common/oauth2/authorize、Redeem URL 为https://login.microsoftonline.com/common/oauth2/token、Profile URL 为https://graph.microsoft.com/v1.0/me(providers/azure.go)。
  2. 租户替换:当--azure-tenant非空且未被其他设置覆盖时,overrideTenantURL会把路径重写为/{tenant}/oauth2/authorize/{tenant}/oauth2/token,即从common端点切到租户专属端点。
  3. V2 判定:只要最终 Login URL 中包含字符串v2.0isV2Endpoint即被置为true,并触发一串针对 V2 协议的适配:
    • 自动向 scope 追加https://graph.microsoft.com/.default(V2 中访问 Microsoft Graph 必须使用该默认 scope,V1 的groupsscope 在 V2 下不被接受,源码会检测并自动剔除,同时打印 WARNING);
    • 若同时配置了--resource,直接打印警告:--resourceoption has no effect when using the Azure OAuth V2 endpoint。
  4. 登录 URL 构造GetLoginURL(providers/azure.go)中,只有当resource非空不是 V2 端点时,才会把resource作为额外参数加入授权请求;prepareRedeem换票逻辑与此完全一致。这与 V1 "resources" 与 V2 "scopes" 的模型差异相符。

providers/azure_test.go 中的TestAzureProviderProtectedResourceConfiguredOAuthV1TestAzureProviderProtectedResourceConfiguredOAuthV2两个用例分别固化了上述两种行为,可作为回归验证依据。

--resource参数的实操注意事项

  1. V2 端点 +--resource时的/.default写法:文档 Notes 指出,当把 v2.0 端点(https://login.microsoftonline.com/{tenant-id}/v2.0)用作--oidc-issuer-url并同时使用--resource时,务必在资源名末尾追加/.default(可参考微软官方 v2-permissions-and-consent 文档中 "The default scope" 一节的说明)。
  2. 源码层面的更严格事实:从 providers/azure.go 的实现看,只要登录 URL 命中 V2 端点,--resource根本不会出现在登录请求或换票参数中,仅产生 WARNING 日志。也就是说,--resource的实质作用域是V1 端点(在授权请求与 token 请求中以resource参数传递,见GetLoginURLprepareRedeem),与 V2 端点混用时应以上述/.default写法或改用 scope 表达为准。

实用提示:nginx 下 Cookie 过大的问题

文档 Notes 的第二条记录了与 Azure 提供商相关的经典运维问题:当 oauth2-proxy 与 nginx 配合、使用 cookie 会话存储时,可能发现会话 cookie 过大而无法被正确透传。文档给出的两种解决途径:

  1. 调大 nginx 的proxy_buffer_size
  2. 改用 Redis 会话存储——即 sessions.md 中的 Redis Storage 方案,通过--session-store-type=redis--redis-connection-url将会话以加密形式存入 Redis,cookie 中只保留 ticket 句柄,从根本上解决体积问题。

认证主链路的源码验证

理解上述配置为何有效,需要看到azureProvider 的完整调用链(均位于 providers/azure.go):

  • 换票(Redeem)Redeemapplication/x-www-form-urlencodedPOST 到 Redeem URL,解析access_tokenrefresh_tokenid_tokenexpires_on(按字符串解析后转为 Unix 时间戳作为会话过期时间),随后进入 claim 提取。
  • 令牌校验与 claim 提取extractClaimsIntoSession先通过verifySessionToken校验令牌——若配置了 OIDC verifier(即设置了--oidc-issuer-url),优先校验id_token,失败则回退校验access_token;claim 解析同样采用 "先 id_token、失败回退 access_token" 的容错策略(源码注释指出这是针对 AAD 在某些情况下未对 id_token 签名的已知问题)。
  • 会话增强(EnrichSession):令牌中取不到邮箱时,回落到 Profile API(/v1.0/me),依次尝试mailotherMailsuserPrincipalName三个字段提取邮箱;V2 端点下还会调用 Microsoft GraphtransitiveMemberOf补齐组列表并去重。
  • 会话校验(ValidateSession):每次请求时用validateToken以 Bearer 头携带访问令牌访问 Validate URL(默认复用 Profile URL),确认令牌仍然有效。
  • 刷新(RefreshSession):凭refresh_token再次调用 Redeem URL 换取新的 access/id 令牌,并重新提取 claims。

小结

azureProvider 提供了接入 Azure AD 的最短路径:门户侧完成应用注册、Group.Read.All管理员同意(必要时配合accessTokenAcceptedVersion=2),代理侧只需--provider=azure+ client 凭据 +--azure-tenant,再按 V1(sts.windows.net发行方)或 V2(login.microsoftonline.com/{tenant-id}/v2.0发行方)选择对应的--oidc-issuer-url即可。--resource仅对 V1 端点有效,--azure-tenant控制端点是租户专属还是common。需要再次强调:该 Provider 已被标记为 deprecated,新部署建议直接使用 Microsoft Entra ID Provider;存量azure部署在进行版本升级或排障时,本文的源码行为说明(scope 自动改写、resource忽略警告、Graph 组拉取链路)均可作为定位依据。

【免费下载链接】oauth2-proxyA reverse proxy that provides authentication with Google, Azure, OpenID Connect and many more identity providers.项目地址: https://gitcode.com/GitHub_Trending/oa/oauth2-proxy

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询