使用Powershell在Azure AD应用程序上执行“授予权限”操作

4
我正在使用AzureAD模块创建一个Azure AD应用程序,以调用Microsoft Graph API。我成功生成了访问令牌。但是,当我尝试调用API时出现错误“message”:“Invalid scope claims/roles.”。
当我在Azure门户中的创建的应用程序中单击“授予权限”按钮并重试对API的调用时,调用将起作用。
我找不到任何有关如何使用PowerShell执行此“授予权限”操作的信息。是否有方法可以做到这一点?
谢谢
达米安

https://meta.stackoverflow.com/questions/350392/here-is-x-part-of-any-program-ever-how-do-i-get-change-this-in-powershell/ - Clijsters
这个案例可能对您有所帮助:https://dev59.com/-FgQ5IYBdhLWcg3wMhHn?rq=1 - Wayne Yang
感谢 @WayneYang-MSFT 的快速回复。我已经在身份验证请求体中添加了 prompt="admin_consent"。这还不足以“授予权限”。 - Damien Celle
你应该使用 &prompt=admin_consent,而不是 prompt="admin_consent"。同时,请确保你登录的 Azure 账户是管理员账户。 - Wayne Yang
即使我在REST URL中使用&prompt=admin_consent,结果仍然相同。 - Damien Celle
4个回答

7

有一种简单的方法可以实现这个(作为管理员),需要您安装Powershell的AzureAD和AzureRM模块,并且这并不是Microsoft支持的。

原帖/我的博客参考链接在这里:http://www.lieben.nu/liebensraum/2018/04/how-to-grant-oauth2-permissions-to-an-azure-ad-application-using-powershell-unattended-silently/

具体代码如下:

Function Grant-OAuth2PermissionsToApp{
Param(
    [Parameter(Mandatory=$true)]$Username, #global administrator username
    [Parameter(Mandatory=$true)]$Password, #global administrator password
    [Parameter(Mandatory=$true)]$azureAppId #application ID of the azure application you wish to admin-consent to
)

$secpasswd = ConvertTo-SecureString $Password -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($Username, $secpasswd)
$res = login-azurermaccount -Credential $mycreds
$context = Get-AzureRmContext
$tenantId = $context.Tenant.Id
$refreshToken = @($context.TokenCache.ReadItems() | where {$_.tenantId -eq $tenantId -and $_.ExpiresOn -gt (Get-Date)})[0].RefreshToken
$body = "grant_type=refresh_token&refresh_token=$($refreshToken)&resource=74658136-14ec-4630-ad9b-26e160ff0fc6"
$apiToken = Invoke-RestMethod "https://login.windows.net/$tenantId/oauth2/token" -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded'
$header = @{
'Authorization' = 'Bearer ' + $apiToken.access_token
'X-Requested-With'= 'XMLHttpRequest'
'x-ms-client-request-id'= [guid]::NewGuid()
'x-ms-correlation-id' = [guid]::NewGuid()}
$url = "https://main.iam.ad.ext.azure.com/api/RegisteredApplications/$azureAppId/Consent?onBehalfOfAll=true"
Invoke-RestMethod -Uri $url -Headers $header -Method POST -ErrorAction Stop
}

1
我收到了错误信息:Invoke-RestMethod : {"error":"invalid_grant","error_description":"AADSTS70000: 传输数据解析器失败:刷新令牌格式不正确或无效。 - Muhammad Rehan Saeed
@MuhammadRehanSaeed 我也是。 - Oleg Skripnyak
嗯,@MuhammadRehanSaeed,你在机器上运行过login-azurermaccount吗?没有其他错误吗?这可能是我们之间的区别,或者是你的帐户权限(我的帐户具有全局管理员权限)。 - Jos
@MuhammadRehanSaeed 我在另一个租户中尝试了一下,遇到了与您不同的错误,然后根据上面更新后的代码添加了 guid 标头,现在它可行了。 - Jos
@JohanMaes 谢谢!在示例中进行了修改,并添加了一个子句以获取最近的令牌。 - Jos
显示剩余2条评论

1
我遇到了同样的错误 'Refresh token is malformed'。当读取刷新令牌时,令牌在字符串中出现了两次。通过添加以下行来解决它:
$refreshtoken = $refreshtoken.Split("`n")[0]

0

如果我没理解错,这里使用的是“管理员同意”功能。在这种情况下,您应该在认证请求中直接使用&prompt=admin_consent

如果您的应用程序请求一个仅限应用程序的权限而用户尝试登录应用程序,则会显示错误消息,提示用户无法同意。

权限是否需要管理员同意由发布资源的开发人员确定,并可在资源文档中找到。

链接:多租户应用程序模式

Azure AD Graph API 和 Microsoft Graph API 的可用权限列表为:

Graph API 权限范围

同意框架

希望能有所帮助。


0
这个答案是在 Jos 的答案基础上构建的。
Active Directory 认证库不再公开刷新令牌。更多信息可以在 github/azure-powershell/7525 找到。
以下修改后的片段对我有用。
Connect-AzAccount
$context = Get-AzContext
$tenantId = $context.Tenant.TenantId
Connect-AzureAD -TenantId $tenantId -AccountId $context.Account.Id

$appId = 'Your Application ID'
$token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $tenantId, $null, "Never", $null, "74658136-14ec-4630-ad9b-26e160ff0fc6")
$headers = @{
    'Authorization' = 'Bearer ' + $token.AccessToken
    'X-Requested-With'= 'XMLHttpRequest'
    'x-ms-client-request-id'= [guid]::NewGuid()
    'x-ms-correlation-id' = [guid]::NewGuid()}
$url = "https://main.iam.ad.ext.azure.com/api/RegisteredApplications/$appId/Consent?onBehalfOfAll=true"
Invoke-RestMethod -Uri $url -Headers $headers -Method POST -ErrorAction Stop

为了完成你的回答,为了获取你当前的访问令牌,从今天开始在 Az PowerShell 的 5.1.0 版本中提供了一个 cmdlet:Get-AzAccessToken(我认为文档很快就会更新),如此所述这里 - Michaël Maillot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接