public override async Task <IActionResult> OnGetAsync()
        {
            await SignInManager.SignOutAsync();

            var logoutId = Request.Query["logoutId"].ToString();

            if (!string.IsNullOrEmpty(logoutId))
            {
                var logoutContext = await Interaction.GetLogoutContextAsync(logoutId);

                await SignInManager.SignOutAsync();

                HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity());

                LoggedOutModel vm = new LoggedOutModel()
                {
                    PostLogoutRedirectUri = logoutContext?.PostLogoutRedirectUri,
                    ClientName            = logoutContext?.ClientName,
                    SignOutIframeUrl      = logoutContext?.SignOutIFrameUrl
                };

                Logger.LogInformation($"Redirecting to LoggedOut Page...");

                return(RedirectToPage("./LoggedOut", vm));
            }

            if (ReturnUrl != null)
            {
                return(LocalRedirect(ReturnUrl));
            }

            Logger.LogInformation(
                $"IdentityServerSupportedLogoutModel couldn't find postLogoutUri... Redirecting to:/Account/Login..");
            return(RedirectToPage("/Account/Login"));
        }
        private async Task <LoggedOutModel> BuildLoggedOutViewModelAsync(string logoutId)
        {
            // get context information (client name, post logout redirect URI and iframe for federated signout)
            var logout = await this.interaction.GetLogoutContextAsync(logoutId);

            var model = new LoggedOutModel
            {
                AutomaticRedirectAfterSignOut = AccountOptions.AutomaticRedirectAfterSignOut,
                PostLogoutRedirectUri         = logout?.PostLogoutRedirectUri,
                ClientName       = logout?.ClientId,
                SignOutIframeUrl = logout?.SignOutIFrameUrl,
                LogoutId         = logoutId
            };

            var user = this.HttpContext.User;

            if (user?.Identity.IsAuthenticated == true)
            {
                var idp = user.FindFirst(JwtClaimTypes.IdentityProvider)?.Value;
                if (idp != null && idp != IdentityServer4.IdentityServerConstants.LocalIdentityProvider)
                {
                    var providerSupportsSignout = await this.HttpContext.GetSchemeSupportsSignOutAsync(idp);

                    if (providerSupportsSignout)
                    {
                        if (model.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
                            model.LogoutId = await this.interaction.CreateLogoutContextAsync();
                        }

                        model.ExternalAuthenticationScheme = idp;
                    }
                }
            }

            return(model);
        }
        public override async Task <IActionResult> OnGetAsync()
        {
            await SignInManager.SignOutAsync();

            var logoutId = Request.Query["logoutId"].ToString();

            if (!string.IsNullOrEmpty(logoutId))
            {
                var logoutContext = await Interaction.GetLogoutContextAsync(logoutId);

                await SaveSecurityLogAsync(logoutContext?.ClientId);

                HttpContext.User = new ClaimsPrincipal(new ClaimsIdentity());
                var vm = new LoggedOutModel
                {
                    PostLogoutRedirectUri = logoutContext?.PostLogoutRedirectUri,
                    ClientName            = logoutContext?.ClientName,
                    SignOutIframeUrl      = logoutContext?.SignOutIFrameUrl
                };

                Logger.LogInformation("Redirecting to LoggedOut Page...");

                return(RedirectToPage("./LoggedOut", vm));
            }

            await SaveSecurityLogAsync();

            if (ReturnUrl == null)
            {
                Logger.LogInformation(
                    "{ClassName} couldn't find postLogoutUri... Redirecting to the index page",
                    nameof(IdentityServerSupportedLogoutModel));
            }

            return(RedirectSafely(ReturnUrl, ReturnUrlHash));
        }
        public async Task <IActionResult> Logout(LogoutModel model)
        {
            var logout = await InteractionService.GetLogoutContextAsync(model.LogoutId);

            var automaticRedirect = AuthorizationOptions.AutomaticRedirectionAfterSignOut && logout?.SignOutIFrameUrl != null;
            var signoutCallbacks  = TestStore
                                    .GetClients()
                                    .Where(client => client.LogoutUri != null)
                                    .Select(client => client.LogoutUri)
                                    .Where(logoutUrl =>
            {
                if (logout?.PostLogoutRedirectUri == null)
                {
                    return(true);
                }
                else if (logoutUrl == null)
                {
                    return(false);
                }
                else
                {
                    var logoutUri    = new Uri(logoutUrl);
                    var logoutDomain = logoutUri.IsDefaultPort ? $"{logoutUri.Scheme}://{logoutUri.Host}" : $"{logoutUri.Scheme}://{logoutUri.Host}:{logoutUri.Port}";

                    var postLogoutRedirectUri = new Uri(logout.PostLogoutRedirectUri);
                    var postLogoutDomain      = postLogoutRedirectUri.IsDefaultPort ? $"{postLogoutRedirectUri.Scheme}://{postLogoutRedirectUri.Scheme}" : $"{postLogoutRedirectUri.Scheme}://{postLogoutRedirectUri.Scheme}:{postLogoutRedirectUri.Port}";

                    return(!logoutDomain.Equals(postLogoutDomain, StringComparison.OrdinalIgnoreCase));
                }
            });

            var viewModel = new LoggedOutModel
            {
                AutomaticRedirectAfterSignOut = automaticRedirect,
                PostLogoutRedirectUri         = logout?.PostLogoutRedirectUri,
                ClientName       = logout?.ClientId,
                SignoutCallbacks = signoutCallbacks,
                //SignOutIframeUrl = logout?.SignOutIFrameUrl
            };

            var externalProvider = await GetExternalProviderAsync();

            if (externalProvider != null)
            {
                var logoutId = model.LogoutId ?? await InteractionService.CreateLogoutContextAsync();

                var url = Url.Action(nameof(Logout), new { logotId = model.LogoutId });

                try
                {
                    var logoutProperties = new AuthenticationProperties {
                        RedirectUri = url
                    };
                    await HttpContext.Authentication.SignOutAsync(externalProvider, logoutProperties);
                }
                catch (NotSupportedException)
                {
                    // hacks for external providers which dont have signout.
                }
                catch (InvalidOperationException)
                {
                    //hack for windows negotiate.
                }
            }

            // dlete the local authentication cooie
            await HttpContext.Authentication.SignOutAsync();

            return(View("LoggedOut", viewModel));
        }