Search code examples
azurepowershellazure-active-directory

How do I add the "offline_access" permission to a new app registration in Azure AD?


See my code for adding permissions to a new app registration:

# Define variables
$AppName = "Test Application 5"
$CertSubject = "CN=$AppName"
$StartDate = Get-Date
$EndDate = $StartDate.AddMonths(3) # Adjust certificate validity period as needed

# Create a new Azure AD application
$App = New-AzureADApplication -DisplayName $AppName -IdentifierUris "test9" -HomePage "https://yourapphomepage"

# Generate a new self-signed certificate
$Cert = New-SelfSignedCertificate -Subject $CertSubject -CertStoreLocation "Cert:\CurrentUser\My" -NotBefore $StartDate -NotAfter $EndDate

# Convert the certificate to a base64-encoded string
$CertBytes = [System.Convert]::ToBase64String($Cert.RawData)
$CertValue = [System.Text.Encoding]::UTF8.GetString([System.Text.Encoding]::ASCII.GetBytes($CertBytes))

# Create a new certificate credential for the application
New-AzureADApplicationKeyCredential -ObjectId $App.ObjectId -CustomKeyIdentifier "CertKey" -Type AsymmetricX509Cert -Usage Verify -Value $CertValue -StartDate $StartDate -EndDate $EndDate

# Create a new password credential for the application (secret)
$PasswordCredential = New-AzureADApplicationPasswordCredential -ObjectId $App.ObjectId -CustomKeyIdentifier "PasswordKey" -StartDate $StartDate -EndDate $EndDate


#-------------------------------------------------------------
# Add Permissions


$spForApp = New-AzureADServicePrincipal -AppId $App.AppId -PasswordCredentials @($PasswordCredential)


$appPermissionsRequired = @('offline_access','User.Read.All','Group.Read.All','GroupMember.ReadWrite.All','Directory.Read.All','AuditLog.Read.All')
$targetServicePrincipalName = 'Microsoft Graph'

$targetSp = Get-AzureADServicePrincipal -Filter "DisplayName eq '$($targetServicePrincipalName)'"


$RoleAssignments = @()

Foreach ($AppPermission in $appPermissionsRequired) {
    $RoleAssignment = $targetSp.AppRoles | Where-Object { $_.Value -eq $AppPermission}
    $RoleAssignments += $RoleAssignment
}

$ResourceAccessObjects = New-Object 'System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.ResourceAccess]'

foreach ($RoleAssignment in $RoleAssignments) {
    $resourceAccess = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess"
    $resourceAccess.Id = $RoleAssignment.Id
    $resourceAccess.Type = 'Role'
    $ResourceAccessObjects.Add($resourceAccess)
}
    
$requiredResourceAccess = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"
$requiredResourceAccess.ResourceAppId = $targetSp.AppId
$requiredResourceAccess.ResourceAccess = $ResourceAccessObjects

# set the required resource access
Set-AzureADApplication -ObjectId $App.ObjectId -RequiredResourceAccess $requiredResourceAccess
Start-Sleep -s 1

# grant the required resource access
foreach ($RoleAssignment in $RoleAssignments) {
    Write-Output -InputObject ('Granting admin consent for App Role: {0}' -f $($RoleAssignment.Value))
    New-AzureADServiceAppRoleAssignment -ObjectId $spForApp.ObjectId -Id $RoleAssignment.Id -PrincipalId $spForApp.ObjectId -ResourceId $targetSp.ObjectId
    Start-Sleep -s 1
}

All the permissions were successfully added except for "offline_access".

When I look for the app roles in the command line using:

$targetSp = Get-AzureADServicePrincipal -Filter "DisplayName eq 'Microsoft Graph'"
$targetSp.AppRoles

I get a large list of the App Roles in Microsoft Graph. I'm able to find all the app roles except "offline_access". It's like it doesn't exist. But I can add it manually in the azure portal.

Does anyone know how I can target "offline_access"? I tried using the permission ID with no success, but maybe someone knows how to use that. Thank you!


Solution

  • Note that: Offline_access is a delegated API permission not application API permission. Hence you have to list it using Oauth2Permissions not AppRoles.

    To list the delegated API permissions, use the below command:

    $targetSp = Get-AzureADServicePrincipal -Filter "DisplayName eq 'Microsoft Graph'"
    $targetSp.Oauth2Permissions
    

    enter image description here

    To get only the required delegated API permission, execute the below command:

    $targetSp = Get-AzureADServicePrincipal -Filter "DisplayName eq 'Microsoft Graph'"
    $offlineAccessId = $targetSp.Oauth2Permissions | Where-Object { $_.Value -eq 'offline_access' } 
    

    enter image description here

    You can add offline_access API permission by using the below code:

    # Create a new Azure AD application
    $myapp = New-AzureADApplication -DisplayName "RukApptest" 
    $myappId = $myapp.ObjectId
    $MSGraph = Get-AzureADServicePrincipal -All $true | Where-Object { $_.DisplayName -eq "Microsoft Graph" }
    
    # Retrieve the ID of the 'offline_access' permission from Microsoft Graph
    $offlineAccessPermission = $MSGraph.Oauth2Permissions | Where-Object { $_.Value -eq 'offline_access' }
    $Graph = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"
    $Graph.ResourceAppId = $MSGraph.AppId
    $Per1 = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess" -ArgumentList $offlineAccessPermission.Id,"Scope"
    $Graph.ResourceAccess = $Per1
    Set-AzureADApplication -ObjectId $myappId -RequiredResourceAccess $Graph
    

    enter image description here

    enter image description here