Как проверить запрос с помощью токена в .net core 2.2 api с помощью Open Id Connect

#azure #asp.net-core-2.0 #openid-connect

#azure #asp.net-core-2.0 #OpenID-connect

Вопрос:

У меня настроен и развернут API .net core 2.2 в Azure. Я использовал OpenID Connect для обработки аутентификации с помощью azure active directory single tenenat, используя приведенный ниже код. И авторизовать декоратор на моем контроллере. Все работает, и когда я перехожу к своему развернутому API azure (myappname.azurewebsites.net ) Я получаю приглашение для входа в Microsoft. Затем я могу войти в систему и просмотреть данные своего маршрута.

         services.AddAuthentication(auth =>
        {
            auth.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            auth.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
            auth.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
        })
        .AddCookie()
        .AddOpenIdConnect(opts =>
        {
            Configuration.GetSection("OpenIdConnect").Bind(opts);
            opts.Events = new OpenIdConnectEvents
            {
                OnAuthorizationCodeReceived = ctx =>
                {
                    return Task.CompletedTask;
                }
            };
            opts.Scope.Add("openid");
            opts.Scope.Add("profile");
            opts.Scope.Add("access_as_user");
        });
  

Проблема в том, что когда у меня включена авторизация для моего контроллера, я не могу вызвать его из своего клиентского приложения angular SPA. Я успешно настроил MSAL, и мои вызовы api передают токен. Однако я получаю следующую ошибку:

https://login.microsoftonline.com/bit4f574-5968-4a40-049d-1c0dc2ca0513/oauth2/authorize?client_id=caor847f-dd19-4489-bef7-684803728c665amp;redirect_uri=https://myapi.azurewebsites.net/signin-oidcamp;response_type=code id_tokenamp;scope=openid profile user_accessamp;response_mode=form_postamp;nonce=637373859487758409.MzhhYTAoeiudtMTdlNS00NzgxLWJjMTQtNzM1YWE3NsdlkelasdNGYxMmQtMjZmYS00YmI2LTgwY2UtNDEwMTNhMWNkN2Ziamp;state=CfDJ8KCu3Hr4UOhLjOspjLNEh0VtJd4GNXqwdibjSiZf7FpUJOL0EDlFso0g0s_iOZHDNbP2aiHVfdzqJSmHkesd-bMjP6ThYva6AfZBa8UZcnGcwgo2ldlg4Fx9vmNVDuSlvHyTlHkd8yNndslkgoyHtfM4RMXamq1wny1J39BZRRATn1RdAsgaLgKP_QkxLaDCwgvdzjp3dKls5UVQE1j7MD6bcKR__1-VmfVKhROn1coQh7OJrea6Jni4jdV7e0wv70TVprGtseJFg8fyHg3KKW14xeX2orlkgls5aLe1uG0c5ehlapFXBirBSgFU3uqOWw0_iLeJUbTL8-HPooixynQRWe1WoiLnQuFYUu7Lx-usdlglvM4WvLfAyTZ5uQY_KsOtr08MxWRlQ5HHVk8Moe1k_N_3BCz8sdkgowwZEKsGiKd_iwcXgzxmggamp;x-client-SKU=ID_NETSTANDARD2_0amp;x-client-ver=5.3.0.0

Как я могу это исправить? Похоже, что мой api перенаправляет запрос клиента на логин Microsoft, но я думаю, что это должно работать так: мой api должен проверять токен в запросе или областях и предоставлять доступ без перенаправления запроса на логин.

Ответ №1:

Ключевым моментом здесь является полное отделение SPA OAuth от API OAuth со следующим поведением:

  • SPA выполняет обработку перенаправления и получает токен с сервера авторизации — этот код основан на Javascript и не нуждается в веб-интерфейсе C #
  • API проверяет токены с помощью открытого ключа подписи токена сервера авторизации — этот код основан на C #, который является хорошим языком для разработки API
  • Сервер авторизации — это готовый компонент, такой как Azure AD, и вы никогда не кодируете выдачу JWT самостоятельно (рад видеть, что вы уже это делаете)

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

КОД OAUTH API

По умолчанию вашему коду на C # требуется всего несколько строк, начиная с добавления такого пакета, как этот:

 <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.8" />
  

Код для настройки безопасности API будет выглядеть примерно так. Обратите внимание, что здесь нет ничего о поведении OpenIdConnect / web.

 private void ConfigureOAuthTokenValidation(IServiceCollection services)
{
    services
        .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options => {
                    options.Authority = "https://login.microsoftonline.com/mytenantid";
                    options.Audience = "api://default";
                });
  

ПРИМЕР ИЗ РЕАЛЬНОГО МИРА

В моем решении .Net Core API есть некоторые вещи, которые могут представлять интерес. Эти примеры довольно сложны, но позволяют запускать локальный API и SPA, которые работают вместе.

Цель состоит в том, чтобы получить наилучший конечный результат как для API, так и для SPA, поэтому, возможно, приведенные выше ссылки помогут вам подумать о том, что это такое в вашем случае.

Комментарии:

1. Итак, код, который у меня уже был, обработал процесс аутентификации в api «app». Я удалил его и вместо этого добавил предложенный вами фрагмент аутентификации Jwt. Теперь при нажатии на мой API отображается 401 несанкционированный доступ. И теперь моя ошибка клиента только: GET https://myapiappname.azurewebsites.net/api/items 401 (Unauthorized) . Это хорошо, потому что он больше не перенаправляется на логин. Но как предоставленный вами фрагмент разрешает доступ на основе токенов? Это что-то, что еще нужно добавить?

2. Я предполагаю, что мне все еще нужно добавить код авторизации при запуске, аналогичный тому, что у вас есть в ссылке Код конфигурации безопасности API?

3. Я бы рекомендовал сначала ознакомиться с утверждениями о токенах и тем, как процесс проверки работает с точки зрения сообщений OAuth. На моей странице проверки токена в памяти есть несколько заметок о том, как вы можете проверить свои токены доступа Azure с помощью инструментов. Как только вы это поймете, вам нужно будет заставить свой код выполнять аналогичную функцию. UseJwtBearer — самый стандартный вариант, и я бы опустил проверку аудитории, пока у вас что-то не заработает. Возможно также, что вам может потребоваться google / установить некоторые дополнительные параметры.

4. Еще один вопрос, просто для моего личного назидания. Может ли вся эта авторизация api и область действия обрабатываться строго в Azure после развертывания базового приложения api в службе приложений Azure? Я просто любопытен и хочу использовать эту опцию, если она существует, как способ более глубокого изучения Azure.

5. Нет — роль API заключается в обеспечении авторизации, поэтому он должен проверять эти вещи. Azure просто предоставляет конечные точки OAuth и выдает токены для вас.