TL; DR
Вопрос: как реализовать социальный вход в систему (поток авторизации OAuth2) с существующим приложением SPA / Web API, основанным на идентификации, пользователе / пароле, аутентификации токена на предъявителя?
У меня есть приложение, которое имеет:
Серверная часть: .Net Core 2 Web API с настроенными службами Identity и OpenIddict, с работающим процессом аутентификации на основе запроса пользователя / пароля для токена на предъявителя.
Пользователи хранятся с удостоверением (AspNetUsers).
Часть кода Startup.cs
// Register the OpenIddict services.
services.AddOpenIddict()
.AddCore(options =>
{
options.UseEntityFrameworkCore().UseDbContext<ApplicationDbContext>();
})
.AddServer(options =>
{
options.UseMvc();
options.EnableTokenEndpoint("/connect/token");
options.AllowPasswordFlow();
options.AllowRefreshTokenFlow();
options.AcceptAnonymousClients();
options.RegisterScopes(
OpenIdConnectConstants.Scopes.OpenId,
OpenIdConnectConstants.Scopes.Email,
OpenIdConnectConstants.Scopes.Phone,
OpenIdConnectConstants.Scopes.Profile,
OpenIdConnectConstants.Scopes.OfflineAccess,
OpenIddictConstants.Scopes.Roles);
})
.AddValidation();
.
Внешний интерфейс: Приложение SPA Angular 7, которое использует этот внутренний API и авторизацию токена
Таким образом, текущая настройка в основном заключается в том, что пользователь вводит имя пользователя / пароль в SPA, который вызывает конечную точку бэкэнда /connect/token
, которая проверяет учетные данные и генерирует токен для клиента.
А теперь мне нужно интегрировать Social Login (поток авторизации OAuth2), чтобы
- пользователь выбирает логин с провайдером,
- перенаправляется на страницу авторизации провайдеров,
- перенаправляется обратно в мое приложение, которое
- необходимо создать пользователя Identity и сохранить данные Identity UserLoginInfo и
- укажите маркер моего приложения, чтобы пользователь мог войти в систему.
Я понимаю поток авторизации OAuth2, который должен запросить код авторизации, а затем код авторизации Exchange для токена доступа для этого провайдера. Я также знаю, что этот поток должен использовать бэкэнд, если он использует конфиденциальную информацию, такую как client_secret, которая не может быть сохранена на стороне клиента.
Но в какой-то момент пользователю необходимо взаимодействовать с внешним интерфейсом, поэтому подключение этих частей кажется очень сложным, учитывая, что это широко используемые технологии. Все практические примеры, которые я нашел в Google, использовали приложение .Net Core MVC. Я также нашел эту статью ASP.NET Core 3.0 Preview 4 - Аутентификация и авторизация для SPA , которая кажется многообещающей, но все еще находится в Preview 4.
Я уже создал приложения для социальных сетей, и у меня есть client_id, client_secret. Также зарегистрированы мои перенаправления URL.
То, что я пытался безуспешно, было:
- В интерфейсе пользователь выбирает логин с социальным провайдером,
- Пользователь перенаправляется на страницу авторизации провайдера, аутентифицируется и
- перенаправляется от провайдера на мой внешний URL-адрес (
redirect_uri
) с кодом провайдера, тогда
- мой веб-интерфейс вызывает мой бэкэнд
/connect/token
существующей конечной точки, передающей выбранного провайдера и полученный код, конечная точка была запрограммирована на получение провайдера и кода, затем
- мой провайдер внутренних вызовов получает URL-адрес AccessToken
"grant_type", "authorization_code"
"code", code
"redirect_uri", "https://same_frontend_host/same/path"
"client_id", providerClientId
"client_secret", providerSecret
и получает StatusCode: 401, ReasonPhrase: 'Unauthorized'
ответ
Что я делаю не так? Это было действительно трудное время, чтобы заставить это работать.
Что сработало, но это не то, что мне нужно
Неявный двухэтапный процесс авторизации с использованием внешнего интерфейса для вызовов проверки подлинности провайдера и внутреннего вызова для получения моего токена на предъявителя и создания пользователя Identity. С этой настройкой пользователь сделал успешный вход в систему с помощью социального провайдера, к сожалению, это не то, что мне нужно
EDIT:
Составил схему того, что реализовано, на шаге 5/6 происходит сбой с StatusCode: 401, ReasonPhrase: 'Unauthorized'
и дальнейшие шаги не завершены.