#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 и выдает токены для вас.