获取AAD令牌调用Yammer API遇AADSTS900144错误,求授权码获取方法
尝试获取AAD令牌后调用Yammer API获取消息时,遇到以下错误:
Invoke-RestMethod : {"error":"invalid_request","error_description":"AADSTS900144: The request body must contain the following parameter: 'code'.\r\nTrace ID: b4f13dec-5b00-446d-b6b0-9b03e1de2700\r\nCorrelation ID:61ff7b84-22eb-4176-a7e9-eec721c73d60\r\nTimestamp: 2023-07-26 14:59:00Z","error_codes":[900144],"timestamp":"2023-07-2614:59:00Z","trace_id":"b4f13dec-5b00-446d-b6b0-9b03e1de2700","correlation_id":"61ff7b84-22eb-4176-a7e9-eec721c73d60","error_uri":"https://login.microsoftonline.com/error?code=900144"}At line:18 char:15
已在请求体中添加code字段,但不知道如何获取$authorizationCode,相关PowerShell代码如下:
$ClientId = "" $SecretID = "" $tenantid = "" $params = @{ Uri = "https://login.microsoftonline.com/$($tenantid)/oauth2/v2.0/token" Method = "POST" Body = @{ "client_id" = $ClientId "client_secret" = $SecretID "grant_type" = 'authorization_code' "code" = $authorizationCode "scope" = "https://api.yammer.com/user_impersonation" "username" = ""; "password" = ""; } } $connection = Invoke-RestMethod @params $headers = @{ Authorization=("Bearer " + $connection.access_token) } $webRequest = Invoke-WebRequest –Uri "https://www.yammer.com/api/v1/messages.json" –Method Get -Headers $headers if ($webRequest.StatusCode -eq 200) { $results = $webRequest.Content | ConvertFrom-Json $results.messages | ForEach-Object { $message = $_ Write-Host $message.sender_id $message.body } }else { Write-Host "An error has occurred: " + $webRequest.StatusCode }
1. 理清授权模式逻辑
你当前混淆了授权码模式和密码模式的参数:授权码(authorization_code)模式需要用户手动登录获取授权码,不需要username和password;而密码(password)模式直接用账号密码换令牌,不需要code。
2. 如何获取授权码(授权码模式)
构造授权URL:
把以下参数拼接成完整URL,在浏览器中打开:https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/authorize?client_id={ClientId}&response_type=code&redirect_uri=http://localhost&scope=https://api.yammer.com/user_impersonation&response_mode=query注意:
redirect_uri必须和你在Azure AD应用注册里配置的重定向URI完全一致,测试阶段可以用http://localhost。提取授权码:
用户完成登录并授权后,页面会跳转到redirect_uri,此时URL中的code参数就是你需要的$authorizationCode。比如跳转后的URL类似http://localhost/?code=ABC123&state=xxx,复制code后面的值即可。修正请求参数:
移除多余的username和password,添加redirect_uri参数,修正后的请求体如下:Body = @{ "client_id" = $ClientId "client_secret" = $SecretID "grant_type" = 'authorization_code' "code" = "从浏览器获取的授权码" "scope" = "https://api.yammer.com/user_impersonation" "redirect_uri" = "http://localhost" # 必须和授权URL中的一致 }
3. 非交互式场景:改用密码模式
如果不需要用户手动操作,可切换到密码模式,直接用账号密码换取令牌:
$params = @{ Uri = "https://login.microsoftonline.com/$($tenantid)/oauth2/v2.0/token" Method = "POST" Body = @{ "client_id" = $ClientId "client_secret" = $SecretID "grant_type" = 'password' "scope" = "https://api.yammer.com/user_impersonation" "username" = "你的用户账号" "password" = "你的用户密码" } }
注意:使用密码模式需要在Azure AD应用注册中开启"允许公共客户端流",该模式安全性较低,仅适合测试或内部非敏感场景。
内容的提问来源于stack exchange,提问作者aasenomad

