4

I'm creating an Azure AD application using AzureAD module to call Microsoft Graph API. I can successfully generate the access token. But, when I try to call the API I have an error "message": "Invalid scope claims/roles.".

When I click on "Grant Permissions" button in my created application in Azure Portal and retry the call to API, the call is working.

I don't find anywhere how to do this "Grant Permissions" actions with Powershell. Is there a way to do that ?

Thanks

Damien

CHEEKATLAPRADEEP
  • 12,191
  • 1
  • 19
  • 42
Damien Celle
  • 41
  • 1
  • 2
  • https://meta.stackoverflow.com/questions/350392/here-is-x-part-of-any-program-ever-how-do-i-get-change-this-in-powershell/ – Clijsters Nov 17 '17 at 08:48
  • This case may be helpful to you: https://stackoverflow.com/questions/43143075/how-to-grant-permissions-using-azure-active-directory-powershell-v2?rq=1 – Wayne Yang Nov 17 '17 at 08:48
  • Thanks @WayneYang-MSFT for the quick reply. I already added prompt="admin_consent" in authentication request body. It's not enough to "Grant Permissions". – Damien Celle Nov 17 '17 at 15:02
  • You should use `&prompt=admin_consent`, NOT `prompt="admin_consent"`. Also , Ensure the azure account you logged in is an admin account. – Wayne Yang Nov 20 '17 at 01:50
  • Even if i use &prompt=admin_consent in REST URL, the result is still the same. – Damien Celle Jan 05 '18 at 16:25

4 Answers4

7

There is an easy way to do this (as admin), it requires you have the AzureAD and AzureRM modules installed for Powershell and is not supported by Microsoft.

Original post / reference to my blog is here: http://www.lieben.nu/liebensraum/2018/04/how-to-grant-oauth2-permissions-to-an-azure-ad-application-using-powershell-unattended-silently/

The specific code sample that should help you accomplish this:

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
}
Jos
  • 140
  • 1
  • 11
  • 1
    I get the error: `Invoke-RestMethod : {"error":"invalid_grant","error_description":"AADSTS70000: Transmission data parser failure: Refresh Token is malformed or invalid.` – Muhammad Rehan Saeed Apr 10 '18 at 10:19
  • @MuhammadRehanSaeed Same here – Oleg Skripnyak Apr 10 '18 at 12:13
  • hmm @MuhammadRehanSaeed have you tried running login-azurermaccount before on the machine? No other errors? That may be a difference between both of us, either that or your account's permissions (mine have global admin) – Jos Apr 10 '18 at 14:27
  • @Jos The login succeeded and I'm an Azure global admin in our test environment where I tried it. – Muhammad Rehan Saeed Apr 10 '18 at 14:46
  • @MuhammadRehanSaeed I tried it in a different tenant, got a different error from you then added the guid headers as per the updated code above and it worked – Jos Apr 11 '18 at 07:13
  • I got a parsing error but found the solution here (and edited the script): https://stackoverflow.com/a/20706950/9266796 – Johan Maes Nov 08 '18 at 07:18
  • @JohanMaes thanks! Amended in the sample, and also added a clause to get the most recent token – Jos Nov 08 '18 at 11:32
1

I came across the same error 'Refresh token is malformed'. When reading out the refreshtoken the token was twice in the string. Resolved it by adding the line

$refreshtoken = $refreshtoken.Split("`n")[0]
chevybow
  • 9,959
  • 6
  • 24
  • 39
MarcelG
  • 11
  • 1
0

If I am not wrong, then it is using "Admin Consent". In that case, you should be using &prompt=admin_consent in the auth request directly.

If your application requests an app-only permission and a user tries to sign in to the application, an error message is displayed saying the user isn’t able to consent.

Whether or not a permission requires admin consent is determined by the developer that published the resource, and can be found in the documentation for the resource.

Link: Multi-tenant App pattern

List of Available permissions for the Azure AD Graph API and Microsoft Graph API are

Graph API Permission Scopes

Consent Framework

Hope it helps.

Ranadip Dutta
  • 8,857
  • 3
  • 29
  • 45
0

This answer builds on top of Jos's answer.

Active Directory Authentication library doesn't make the refresh tokens publicly available anymore. More information can be found in github/azure-powershell/7525.

The modified snippet below worked for me

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
dr0pdb
  • 83
  • 1
  • 7
  • To complete your answer, in order to get your current access token, there is a cmdlet available from today in the 5.1.0 version of Az PowerShell: Get-AzAccessToken (the documentation will be shortly updated I think), as stated [here](https://github.com/Azure/azure-powershell/issues/7752#issuecomment-727775181) – Michaël Maillot Nov 17 '20 at 10:14