Friday, December 27, 2019

Several problems when use Set-AzureADApplication cmdlet with AzureAD app with allowPublicClient = true

In order to be able to use username/password credentials authentication flow with AzureAD app it should have allowPublicClient property set to true. As described in documentation this property won’t affect those OAuth flows which use reply urls:

Specifies the fallback application type. Azure AD infers the application type from the replyUrlsWithType by default. There are certain scenarios where Azure AD cannot determine the client app type (e.g. ROPC flow where HTTP request happens without a URL redirection). In those cases Azure AD will interpret the application type based on the value of this property. If this value is set to true the fallback application type is set as public client, such as an installed app running on a mobile device. The default value is false which means the fallback application type is confidential client such as web app.

However setting it true has several side effects. One of them is that you can’t set this property via Set-AzureADApplication cmdlet as there is no such property (Update 2021-04-22: it is possible to change it using another cmdlets - see Change "Allow public client flows" property of Azure AD apps via PowerShell). There is another property “publicClient” and based on this discussion on github when you set it to true/false it also set to true/false “allowPublicClient”. But if you will try to run Set-AzureADApplication and try to specify API permissions via RequiredResourceAccess

Set-AzureADApplication -ObjectId … –RequiredResourceAccess $permissions -PublicClient $true

you will get error:

Property requiredResourceAccess.resourceAccess is invalid.

It is possible to set allowPublicClient to true from UI in Azure portal > Azure active directory > App registrations > app > Authentication > Default client type > Treat application as a public client = Yes:

But after that it won’t be possible to change API permissions via Set-AzureADApplication cmdlet. The following code:

$tokensApp = Get-AzureADApplication | Where-Object { $_.AppId -eq "..." }
$requiredResourceAccess = $tokensApp.RequiredResourceAccess
$graphPermissions = $requiredResourceAccess | Where-Object { $_.ResourceAppId -eq "00000003-0000-0000-c000-000000000000" }
# add Sites.Read.All delegated permission
$perm = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess"-ArgumentList "205e70e5-aba6-4c52-a976-6d2d46c48043","Scope"
$graphPermissions.ResourceAccess.Add($perm)

Set-AzureADApplication -ObjectId $tokensApp.ObjectId -RequiredResourceAccess $requiredResourceAccess

will thrown the same exception:

Set-AzureADApplication : Error occurred while executing SetApplication
Code: Request_BadRequest
Message: Property requiredResourceAccess.resourceAccess is invalid.
Details: PropertyName - requiredResourceAccess.resourceAccess, PropertyErrorCode - GenericError
HttpStatusCode: BadRequest
HttpStatusDescription: Bad Request
HttpResponseStatus: Completed

Note that the same code works properly if allowPublicClient property is set to false. For now I posted this problem in github here. If you know any workarounds for this problem please share it in comments.

No comments:

Post a Comment