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

如何通过PowerShell实现Azure AD OAuth非交互式登录RabbitMQ

问题描述

我们已按照RabbitMQ官方Azure AD OAuth配置指南完成RabbitMQ实例的授权配置,AD用户(已分配应用注册角色)通过交互式方式登录完全正常,但用PowerShell做非交互式OAuth登录时遇到问题:

  • 从Chrome开发者工具获取的交互式登录token能正常完成RabbitMQ授权
  • 但通过PowerShell获取的token无法通过认证,返回“Not Authorized”

RabbitMQ配置(rabbitmq.conf)

listeners.ssl.default = 5671
ssl_options.cacertfile = <Cert Path>
ssl_options.certfile = <Cert Path>
ssl_options.keyfile = <Cert Path>
ssl_options.password = <password>
management.ssl.port       = 15671
management.ssl.cacertfile = <Cert Path>
management.ssl.certfile   = <Cert Path>
management.ssl.keyfile    = <Cert Path>
management.ssl.password = <Password>
log.file.level = debug
auth_backends.1 = rabbit_auth_backend_oauth2
auth_backends.2 = internal
auth_oauth2.https.peer_verification = verify_none
auth_oauth2.resource_server_id = <AppRegistrationID>
auth_oauth2.jwks_url = https://login.microsoftonline.com/<TenantID>/discovery/v2.0/keys
auth_oauth2.additional_scopes_key = roles
auth_oauth2.https.cacertfile = <Cert Path>
management.oauth_enabled = true  
management.oauth_client_id = <AppRegistrationID>
management.oauth_provider_url = https://login.microsoftonline.com/<TenantID>

尝试的PowerShell脚本

获取Token的脚本

$tokenParams = @{
    "grant_type"="client_credentials"
    "scope"="api://<AppRegistrationID>/access-api"
    "client_id"=$clientID
    "client_secret"=$clientSecret
    "redirect_uri"="https://<rabbitserver>:15671/js/oidc-oauth/login-callback.html"
}
$tokenResponse = Invoke-RestMethod -Uri $tokenEndpoint -Method POST -ContentType "application/x-www-form-urlencoded" -Body $tokenParams
$accessToken = $tokenResponse.access_token

用Token请求RabbitMQ API的脚本

$headers = @{
    "Authorization" = "Bearer $accessToken"
}
Invoke-RestMethod -Uri "https://<rabbitserver>:15671/api/whoami" -Method GET -Headers $headers

核心问题

  • PowerShell获取的token不包含角色声明,而RabbitMQ依赖roles字段做权限判断(配置里auth_oauth2.additional_scopes_key = roles)
  • 当前只能用客户端密钥获取token,无法通过AD用户凭据做非交互式登录
  • 不确定带角色声明的用户授权流是否支持非交互式场景,也没找到相关替代配置文档

请问有没有办法通过PowerShell非交互式获取可用于RabbitMQ认证的有效token?


解决方案

方案1:给服务主体分配应用角色(适配客户端凭据流)

你当前用的是客户端凭据流,这个流返回的token角色属于服务主体(应用注册本身),而非用户角色。调整步骤:

  1. 登录Azure AD,找到RabbitMQ对应的应用注册,进入应用角色页面,确认已定义所需权限角色(如rabbitmq-admin、rabbitmq-reader)
  2. 进入该应用注册对应的企业应用,在用户和组页面,给服务主体(即应用注册本身)分配对应的应用角色
  3. 修改PowerShell脚本的scope参数为api://<AppRegistrationID>/.default(客户端凭据流必须用.default作为scope,不能用自定义的access-api),并移除不需要的redirect_uri参数:
$tokenParams = @{
    "grant_type"="client_credentials"
    "scope"="api://<AppRegistrationID>/.default"
    "client_id"=$clientID
    "client_secret"=$clientSecret
}
$tokenEndpoint = "https://login.microsoftonline.com/<TenantID>/oauth2/v2.0/token"
$tokenResponse = Invoke-RestMethod -Uri $tokenEndpoint -Method POST -ContentType "application/x-www-form-urlencoded" -Body $tokenParams
$accessToken = $tokenResponse.access_token

此时获取的token会包含服务主体的角色声明,RabbitMQ可正常识别授权。

方案2:用资源所有者密码凭据流(ROPC)获取用户身份的token

如果必须使用AD用户的角色而非服务主体角色,可采用ROPC流实现非交互式登录(注意:ROPC为遗留流,仅在无法使用其他流的场景下使用):

  1. 在Azure AD应用注册的身份验证页面,开启允许公共客户端流
  2. 调整PowerShell脚本使用ROPC流:
$tokenParams = @{
    "grant_type"="password"
    "scope"="api://<AppRegistrationID>/access-api openid"
    "client_id"=$clientID
    "username"="<AD用户UPN>"
    "password"="<AD用户密码>"
}
$tokenEndpoint = "https://login.microsoftonline.com/<TenantID>/oauth2/v2.0/token"
$tokenResponse = Invoke-RestMethod -Uri $tokenEndpoint -Method POST -ContentType "application/x-www-form-urlencoded" -Body $tokenParams
$accessToken = $tokenResponse.access_token

该流返回的token包含AD用户的角色声明,与交互式登录的token结构一致,可被RabbitMQ正常识别。

关键验证步骤

  • 确认RabbitMQ的auth_oauth2.additional_scopes_key = roles配置正确,Azure AD返回的token中角色声明的键为roles
  • 解析token验证权限:执行Invoke-RestMethod https://jwt.ms -Method POST -Body $accessToken,确认roles字段存在且包含正确权限

内容的提问来源于stack exchange,提问作者Alexander M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:19:57