IdentityServer4 + WebApi + Angular2 + внешняя аутентификация

Я пытаюсь создать следующую структуру:

  • WEB API, который содержит логику (другой домен)
  • IdentityServer4 API, обеспечивающий аутентификацию (другой домен)
  • Клиент Angular 2 (другой домен)
  • Мобильное приложение.

Клиент Angular 2 должен иметь кнопку Twitter-Sign in. Ниже приведена конфигурация для Twitter:

    public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(LogLevel.Debug);

        app.UseCors("CorsPolicy");

        app.UseIdentity();
        app.UseIdentityServer();

        //after identity before mvc
        app.UseTwitterAuthentication(new TwitterOptions
        {
            AuthenticationScheme = "Twitter",
            DisplayName = "Twitter",
            SignInScheme = "Identity.External",
            ConsumerKey = "key",
            ConsumerSecret = "secret",
            AutomaticAuthenticate = true,
            AutomaticChallenge = true,
            SaveTokens = true,
        });
        app.UseMvc();
    }

Эта конфигурация сохраняет мой токен доступа и секрет, предоставленный твиттером, в моей базе данных.

        bool result = false;
        var info = await signInManager.GetExternalLoginInfoAsync();
        if (info != null)
        {
            var tempUser = info.Principal;
            var claims = tempUser.Claims.ToList();

            var userIdClaim = claims?.FirstOrDefault(x => x.Type == ClaimTypes.NameIdentifier);
            var email = claims?.FirstOrDefault(x => x.Type == ClaimTypes.Email);

            if (userIdClaim != null)
            {
                var isRegistered = await IsUserRegistered(info.LoginProvider, info.ProviderKey);
                if (!isRegistered && email != null)
                {
                    var user = new ApplicationUser { UserName = userIdClaim.Value, Email = email.Value };
                    var userCreated = await userManager.CreateAsync(user);
                    isRegistered = userCreated.Succeeded;

                    if (isRegistered)
                    {
                        var addLoginresult = await userManager.AddLoginAsync(user, info);
                        isRegistered = addLoginresult.Succeeded;
                        if (isRegistered)
                        {
                            await signInManager.SignInAsync(user, isPersistent: false);
                        }
                    }
                }

                if (isRegistered)
                {
                    var succeded = await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
                    if (succeded.Succeeded)
                    {
                        IdentityResult updateResult = await signInManager.UpdateExternalAuthenticationTokensAsync(info);
                        result = updateResult.Succeeded;



                    }
                }
            }
        }

        if (!result)
        {
            await signInManager.SignOutAsync();
        }

        return Redirect(System.Net.WebUtility.UrlDecode(returnUrl));

Я пытаюсь выяснить, как мне реализовать мой метод ExternalLoginCallback для возврата токенов клиенту (Angular или любому другому), который позже будет использоваться для аутентификации в WEB API (или нескольких API). На данный момент я вижу в ответ куки-файл Auth.


person Vitaly Bibikov    schedule 24.03.2017    source источник
comment
все это делается в примере клиента Javascript на сервере IdentityServer4. Вы являетесь клиентом Javascript, перенаправляете вас на вход через IdentityServer4, он возвращает вам токен доступа, который вы добавляете в заголовок авторизации в запросе на ваш веб-сайт.   -  person johnny 5    schedule 24.03.2017
comment
Когда я отправляю access_token из twitter от клиента, я получаю в журнале следующее: dentityServer4.AccessTokenValidation.Infrastructure.NopAuthenticationMiddleware:Information: Twitter не прошел аутентификацию. Сообщение об ошибке: Токен не найден. Microsoft.AspNetCore.Authorization.DefaultAuthorizationService:Информация: Ошибка авторизации для пользователя: (null). Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Информация: Ошибка авторизации для запроса в фильтре «Microsoft.AspNetCore.Mvc.Authorization.AuthorizeFilter».   -  person Vitaly Bibikov    schedule 24.03.2017
comment
@VitalyEvilAvenger Ты смог его взломать?   -  person Gopi    schedule 19.07.2019


Ответы (1)


Посмотрите отличный пример этого Damienbod по настройке IdentityServer4 с помощью webapi и Angular2 (уже Angular4!) https://damienbod.com/2016/03/02/angular2-openid-connect-implicit-flow-with-identityserver4/

По сути, нет никакой разницы, используете ли вы внешний вход в Twitter или сам вход в IdentityServer4. Вы можете удалить форму входа на сервер идентификации и оставить только внешнюю ссылку для входа в твиттер. Вкратце, что вы должны сделать:

  1. Настройте сервер идентификации, чтобы он мог войти в систему через Twitter, на странице http://youridetityserver/Account/Login.

  2. Установите ссылку для входа в приложение angular на http://youridetityserver/connect/authorize с соответствующими параметрами. Список параметров можно найти здесь http://docs.identityserver.io/en/release/endpoints/authorize.html

  3. В приложении angular2 извлеките параметр id_token из returnURL

  4. Установите заголовок Bearer в вызовах вашего сервера WebApi из приложения angular2

  5. Настройте WebApi для использования авторизации IdentityServer.

person Gor Rustamyan    schedule 25.03.2017
comment
Я видел этот пример, основное отличие в том, что я пытаюсь реализовать внешний вход в систему. Проблема в том, что я не знаю, как получить доступ к моему контроллеру API, используя access_token, который был предоставлен мне твиттером, или как обменять этот twitter access_token на локальный сервер Id4 access_token. - person Vitaly Bibikov; 27.03.2017
comment
Немного поздно :) Вы можете создать собственную реализацию IExtensionGrantValidator. См. пример здесь. linkedin.com/pulse/ - person Gor Rustamyan; 28.07.2017