Рабочий сценарий
У меня есть веб-приложение Azure (https://www.contoso.com), для которого я хочу пройти аутентификацию и выполнить веб-вызов.
Я хочу аутентифицироваться, используя Connect-AzAccount
, и звонить ему, используя свою личность.
Я успешно использую следующий код, чтобы получить действительный токен и вызвать приложение.
#Authenticate as myself or a sevice principal
Connect-AzAccount -Tenant 'a736bac3-c259-450f-90a4-f7d5bd7c4c78'
# App registration ID for Contoso
$ResourceUri = '24114488-8c26-4e87-8f71-90de62f5a8aa'
$Context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
$token = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, $ResourceUri).AccessToken
$Headers = @{Headers = @{Authorization = "Bearer $token" } }
Invoke-RestMethod -Method Get -uri 'https://Contoso.com/module/Something' @Headers
При этом само приложение не реализует принудительное назначение пользователей и групп. Вместо этого каждый может подключиться к нему (по дизайну).
Проблема c
Решение, представленное выше, требует от меня добавления Powershell Azure (1950a258- 227b-4e31-a9cf-717495945fc2) в списке Авторизованное клиентское приложение , чтобы включить этот сценарий. Выполнив эту операцию, любой в моем каталоге теперь может технически совершать звонки на веб-сайт, что нежелательно.

Desired Scenario
Because user assignment is not enforced, I removed the Powershell Azure client from the main app and instead created a second App Registration for which I authorized the PS AZ client and added an API permission so it had access to the main App. The idea is that I can require user assignement for the second app registration and therefore limit the user that can make these kind of calls.
Initial (working) flow:
- Connect-AzAccount authenticate the user
- Code sample above is ran to obtain the token and call the app.
Desired flow
- Connect-AzAccount authenticate the user
- User connect through the client app registraion (new app) that has api permission to the main app.
- User make calls to the main app.
Now, if I try to use my initial code sample with the Application Id of the second registration acting as a client ID, I get the following error
Invoke-RestMethod : {"code":401,"message":"IDX10214: Audience validation failed. Audiences: '[PII is hidden]'. Did not
match: validationParameters.ValidAudience: '[PII is hidden]' or validationParameters.ValidAudiences: '[PII is hidden]'."}
At line:1 char:12
+ $result2 = Invoke-RestMethod -Method Get -uri 'https://Contoso.com/so...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExcept
ion
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
I believe that this is because I am obtaining a token for the second app registration and trying to call the main app URL, which is not authorized through the token.
A "working" alternative to this problem would be to connect using Client_credentials as grant_type such as this:
function get-Bearer([string]$TenantID, [string]$ClientID, [string]$ClientSecret) {
$TokenEndpoint = "https://login.windows.net/{0}/oauth2/token" -f $TenantID
$Body = @{
'resource' = '24114488-8c26-4e87-8f71-90de62f5a8aa'
'client_id' = $ClientID
'grant_type' = 'client_credentials'
'client_secret' = $ClientSecret
}
$params = @{
ContentType = 'application/x-www-form-urlencoded'
Headers = @{'accept' = 'application/json' }
Body = $Body
Method = 'Post'
URI = $TokenEndpoint
}
$token = Invoke-RestMethod @params
Return "Bearer " + ($token.access_token).ToString()
}
If I do that, even though I can make calls to the main app. again but it is connected with the actual client app. and not using the user identity obtained through Connect-AzAccount
(for which tokens can be generated through the initial sample)
I was also able to make it work with a password grant_type but this is not making use of my bearer token and is also invalidated by MFA enabled users.
All insights are welcome.
References
Документация по платформе Microsoft Identity - v2-oauth2-on-name-of- поток (копаемся в потоке приложения, чтобы попытаться заставить что-нибудь работать)