Получите 401 Несанкционированный вызов WebApi из другого WebAp от имени api (не пользователя)

У нас есть несколько веб-API ASPNET Core в Azure, которые мы вызываем от имени пользователя. Этот пользователь обычно входит на веб-сайт ASPNET, также в Azure.

Мы вводим аудиторскую службу. Похоже, что он должен вызываться от имени вызывающей службы, а не от имени аутентифицированного пользователя.

  • Служба аудита имеет связанную регистрацию приложения в Azure AD.
  • Служба аудита имеет область действия под названием "access_as_application", хотя, просмотрев документацию по области ".default", я не был уверен, что мне нужна область
  • Вызывающее приложение (веб-сайт ASPNET Core) было добавлено в раздел «Авторизованные клиентские приложения» для ранее упомянутой области.

В вызывающем приложении я получаю токен доступа для приложения, а не для пользователя, используя GetAccessTokenForAppAsync.

      var accessToken = await this.tokenAcquisition.GetAccessTokenForAppAsync(this.auditApiScope);
System.Diagnostics.Debug.WriteLine($"access token-{accessToken}");
this.httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
this.httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

В настоящее время я запускаю вызывающее приложение и службу аудита на своей локальной машине разработки.

Когда я звоню в аудиторскую службу, я получаю сообщение 401 Unauthorized

      var response = await this.httpClient.PostAsync($"{this.auditApiBaseAddress}v1/entries", requestContent);

ОБНОВИТЬ

Я добавил идентификатор приложения Azure Ad вызывающего приложения как известное приложение-клиент в службе аудита через манифест приложения. Это не помешало 401

      "knownClientApplications": [
        "7ac7f49d-e9fa-4e1b-95b2-03e0e1981f58"
    ],

ОБНОВЛЕНИЕ 2

Я вижу, что экземпляр службы, работающей в Visual Studio, сообщает о трассировке стека. Это относится к проблеме IDW10201.

      System.UnauthorizedAccessException: IDW10201: Neither scope or roles claim was found in the bearer token. 
   at Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilderExtensions.<>c__DisplayClass3_1.<<AddMicrosoftIdentityWebApiImplementation>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.Identity.Web.MicrosoftIdentityWebApiAuthenticationBuilder.<>c__DisplayClass14_0.<<CallsWebApiImplementation>b__1>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.JwtBearer.JwtBearerHandler.HandleAuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationHandler`1.AuthenticateAsync()
   at Microsoft.AspNetCore.Authentication.AuthenticationService.AuthenticateAsync(HttpContext context, String scheme)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

Есть мысли почему?

2 ответа

В настоящее время вы должны выполнять межсерверное взаимодействие, то есть без участия пользователя. Таким образом, ваше серверное приложение должно создать, а затем предоставить роль приложения в качестве разрешения приложения для клиентского приложения .

Во-первых, вам необходимо предоставить доступ к API- интерфейсу серверного приложения, защищенного Azure, который можно настроить в соответствии со следующим процессом:

Портал Azure> Регистрация приложений> Предоставить API> Добавить область> Добавить клиентское приложение

Затем вам нужно создать appRoleсерверного приложения, а затем предоставьте эту роль как разрешение приложения клиентскому приложению.

Затем перейдите в клиентское приложение > Разрешения API> Добавить разрешение> Мои API > ваше приложение API.

Наконец, вам нужно получить токен доступа, используя поток учетных данных клиента, в котором ни один пользователь не вошел в систему:

Разобрать токен :

Хотя я отметил вклад Карла Чжао как ответ, мне показалось, что за скриншотами немного сложно следить, так что это моя попытка сделать это немного яснее.

В этом сценарии, когда мы хотим, чтобы проверка подлинности между зарегистрированным приложением (клиентом) Azure Ad и другим зарегистрированным приложением Azure Ad (службой аудита) не была решением. Вместо того, чтобы открывать область видимости, нам нужно было раскрыть appRole.

Шаги, необходимые для предоставления и последующего запроса доступа к роли приложения, были

  1. Регистрация приложений -> Служба аудита -> Управление -> Роли приложений -> Создание роли приложения
  2. При создании роли приложения убедитесь, что типом Разрешенного члена является «Приложения».
  3. Теперь перейдите в Регистрация приложений -> YourClientApplication -> Разрешения Api -> Добавить разрешение
  4. Я ожидал, что служба аудита появится в разделе «Мои API» на панели «Запросить разрешения API». Я этого не сделал, единственный способ запросить разрешение на ранее созданное AppRole - это ввести AppId службы аудита в поле поиска в разделе «API-интерфейсы, которые использует моя организация».
  5. Как только мне удалось выбрать службу аудита, я выбрал «Разрешения для приложений», а не «Делегированные разрешения», а затем выбрал конкретную роль.

После того, как клиентскому приложению был предоставлен доступ, нам нужно было написать код, чтобы получить токен доступа. Использование библиотеки Mictosoft.Identity.Web

      var accessToken = await this.tokenAcquisition.GetAccessTokenForAppAsync(this.auditApiScope);
System.Diagnostics.Debug.WriteLine($"access token-{accessToken}");
this.httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
this.httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

Обратите внимание на вызов GetAccessTokenForApp Async, а не GetAccessTokenForUserAsync. GetAccessTokenForAppAsyncпо-прежнему требуется область действия, однако, как уже было сказано, настраиваемая область не требуется. Область видимости - ".default", поэтому строка, переданная этому вызову в нашем случае, была https://ourdomain/audit-service/.default", которая является нашим URI идентификатора приложения плюс".default"

Другие вопросы по тегам