Выйти IdentityServer4 + ASP.NET Core MVC + Угловое приложение - PullRequest
1 голос
/ 14 мая 2019

У меня проблема с правильным возвратом в клиентское приложение после успешного выхода из системы.Сначала я хотел бы описать мои настройки.

  • IdentityServer4 как IDP
  • 2x ASP.NET Core MVC-приложение (клиент с точки зрения IS4).В приложениях MVC используются две схемы аутентификации (схема на основе oidc-cookie для аутентификации и схема токенов на предъявителя JWT для вызовов остальных API)
  • 2x Angular 7 SPA (который размещается в вышеупомянутом приложении MVC)

Поскольку мой проект предъявляет высокие требования к безопасности, я использую Гибридный поток для авторизации. Итак, процесс входа в систему выглядит следующим образом:

  1. Пользователь не прошел проверку подлинности и посещает приложение SPA, где он нажимает кнопку входа
  2. Приложение Angular делает перенаправление наконечная точка MVC, которая находится под атрибутом [Authorize], который инициирует вызов OIDC.
  3. Пользователь перенаправляется (OidcMiddleware) на IS4, где он может ввести имя пользователя и пароль
  4. Пользователь находится в процессеперенаправляется (после успешного входа в систему) обратно в логику конечной точки входа MVC (которая была вызвана в п. 2), которая отвечает за перенаправление пользователя обратно в Angular SPA.
  5. Angular делает вызов http для конечной точки MVC,находится под [Авторизация] и отвечает за возврат сгенерированного токеном JWT IS4 клиенту.
  6. Поскольку пользователь вошел в клиент MVC (файлы cookie присутствуют), бэкэнд MVC извлекает токен JWT (access_token) изфайл cookie и вернуть его клиенту
  7. В этот момент поток входа в систему завершен (угловое использование для REST APЯ вызываю токен JWT) - из-за этого я использую на бэкенде две схемы аутентификации.

Так что теперь я столкнулся с некоторыми проблемами с функциональностью выхода из системы.Сначала хотелось бы описать поток для выхода из системы:

  1. При входе пользователь нажимает кнопку «Выйти» в угловом приложении
  2. Приложение Spa очищает записи localalstorage (гдеТокен JWT сохраняется) и перенаправляет пользователя к действию выхода из системы в приложении MVC.Код ниже:

    [AllowAnonymous] публичная асинхронная задача Выход из системы (string returnUrl) {await HttpContext.SignOutAsync ("Cookies");await HttpContext.SignOutAsync ("oidc");}

  3. SignoutAsync на схеме "oidc" запускает поток выхода OIDC (который перенаправляет на конечную точку выхода IS4)

  4. Конечная точка выхода из IS4загрузка контекста выхода из системы (код из быстрого запуска IS4)

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Logout(LogoutDto dto)
    {
        // build a model so the logged out page knows what to display
        var vm = await BuildLoggedOutViewModelAsync(dto.LogoutId);
    
        if (User?.Identity.IsAuthenticated == true)
        {
            // delete local authentication cookie
            await HttpContext.SignOutAsync();
    
            // raise the logout event
            await _events.RaiseAsync(new UserLogoutSuccessEvent(User.GetSubjectId(), User.GetDisplayName()));
        }
    
        // check if we need to trigger sign-out at an upstream identity provider
        if (vm.TriggerExternalSignout)
        {
            // build a return URL so the upstream provider will redirect back
            // to us after the user has logged out. this allows us to then
            // complete our single sign-out processing.
            string url = Url.Action("Logout", new { logoutId = vm.LogoutId });
    
            // this triggers a redirect to the external provider for sign-out
            return SignOut(new AuthenticationProperties { RedirectUri = url }, vm.ExternalAuthenticationScheme);
        }
    
        return View("LoggedOut", vm);
    }
    
  5. Важным является метод BuildLoggedOutViewModelAsync, который загружает контекст выхода из системы:

    частная асинхронная задача BuildLoggedOutViewModelAsync (строка logoutId)) {// получить контекстную информацию (имя клиента, URI перенаправления после выхода из системы и iframe для федеративного выхода) var context = await _interaction.GetLogoutContextAsync (logoutId);

        var vm = new LoggedOutViewModel
        {
            AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,
            PostLogoutRedirectUri = context?.PostLogoutRedirectUri,
            ClientName = string.IsNullOrEmpty(context?.ClientName) ? context?.ClientId : context?.ClientName,
            SignOutIframeUrl = context?.SignOutIFrameUrl,
            LogoutId = logoutId
        };
    
        if (User?.Identity.IsAuthenticated == true)
        {
            var idp = User.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;
            if (idp != null && idp != IdentityServerConstants.LocalIdentityProvider)
            {
                var providerSupportsSignout = await HttpContext.GetSchemeSupportsSignOutAsync(idp);
                if (providerSupportsSignout)
                {
                    if (vm.LogoutId == null)
                    {
                        // if there's no current logout context, we need to create one
                        // this captures necessary info from the current logged in user
                        // before we signout and redirect away to the external IdP for signout
                        vm.LogoutId = await _interaction.CreateLogoutContextAsync();
                    }
    
                    vm.ExternalAuthenticationScheme = idp;
                }
            }
        }
    
        return vm;
    }
    
  6. И вотпроблема.В случае, если срок действия моего cookie-файла mvc истек, в большинстве контекстных свойств установлено значение null, как, например, PostLogoutRedirectUrl.И из-за этого я не могу отобразить ссылку возврата к клиенту в представлении IS4 LoggedOut.cshtml.

В случае, если мой cookie-файл клиента mvc не являетсяистек (действителен) все работает нормально.У меня есть PostLogoutRedirectUrl, который позволяет мне вернуться из IS4 обратно к клиенту, который вызвал выход.

Ребята, у вас есть какие-нибудь идеи, как я могу решить эту проблему?Большое спасибо заранее!

1 Ответ

0 голосов
/ 17 мая 2019
" Приложение Spa очищает записи локального хранилища (где хранится токен JWT) и перенаправляет пользователя на действие выхода из приложения MVC. "

^^ IНе думаю, что вы должны сделать вышеуказанный шаг.Об этом позаботится IDS.

...