public async Task <IActionResult> OnGetAsync()
        {
            // Get id_token first to seed the iframe logout
            var user = await _signInManager.UserManager.GetUserAsync(User);

            if (user != null)
            {
                // this is the session alternative to storing tokens
                //var openIdConnectSessionDetails = HttpContext.Session.Get<OpenIdConnectSessionDetails>(Wellknown.OIDCSessionKey);

                var queryLoginProviderClaim = (from claim in User.Claims
                                               where claim.Type == "login_provider"
                                               select claim).FirstOrDefault();
                var queryIdTokenClaim = (from claim in User.Claims
                                         where claim.Type == "id_token"
                                         select claim).FirstOrDefault();
                string loginProvider = null;
                string idToken       = null;

                if (queryLoginProviderClaim != null)
                {
                    loginProvider = queryLoginProviderClaim.Value;
                    if (queryIdTokenClaim != null)
                    {
                        idToken = queryIdTokenClaim.Value;
                    }
                    else
                    {
                        idToken = await _userManager.GetAuthenticationTokenAsync(user, loginProvider, "id_token");
                    }
                }

                // no matter what, we are logging out our own app.
                // Do Not trust the provider to keep its end of the bargain to frontchannel sign us out.
                await _signInManager.SignOutAsync();

                _logger.LogInformation("User logged out.");

                HttpContext.Session.Clear();

                if (!string.IsNullOrEmpty(loginProvider) && !string.IsNullOrEmpty(idToken))
                {
                    // we have an external OIDC provider here.
                    var clientSignoutCallback =
                        $"{Request.Scheme}://{Request.Host}/Identity/Account/SignoutCallbackOidc";
                    var discoverCacheContainer = _configuredDiscoverCacheContainerFactory.Get(loginProvider);
                    var discoveryCache         = await discoverCacheContainer.DiscoveryCache.GetAsync();

                    var endSession = discoveryCache.EndSessionEndpoint;
                    EndSessionUrl =
                        $"{endSession}?id_token_hint={idToken}&post_logout_redirect_uri={clientSignoutCallback}";
                    // this redirect is to the provider to log everyone else out.
                    // We will get a double hit here, as our $"{Request.Scheme}://{Request.Host}/Account/SignoutFrontChannel";
                    // will get hit as well.
                    return(new RedirectResult(EndSessionUrl));
                }
            }

            return(new RedirectResult("/"));
        }
Beispiel #2
0
 public IdentityController(ConfiguredDiscoverCacheContainerFactory configuredDiscoverCacheContainerFactory,
                           IMemoryCache memoryCache)
 {
     _configuredDiscoverCacheContainerFactory = configuredDiscoverCacheContainerFactory;
     _discoveryContainer = _configuredDiscoverCacheContainerFactory.Get("p7identityserver4");
     _memoryCache        = memoryCache;
     _providerValidator  = new ProviderValidator(_discoveryContainer, _memoryCache);
 }
Beispiel #3
0
        public async Task <IActionResult> OnGetAsync()
        {
            if (User.Identity.IsAuthenticated)
            {
                string idToken       = null;
                string loginProvider = null;
                var    openIdConnectSessionDetails = HttpContext.Session.Get <OpenIdConnectSessionDetails>(Wellknown.OIDCSessionKey);
                if (openIdConnectSessionDetails != null)
                {
                    idToken       = openIdConnectSessionDetails.OIDC["id_token"];
                    loginProvider = openIdConnectSessionDetails.LoginProider;
                }

                /*
                 * var openIdConnectSessionDetails = HttpContext.Session.Get<OpenIdConnectSessionDetails>(Wellknown.OIDCSessionKey);
                 * if (openIdConnectSessionDetails != null)
                 * {
                 *  idToken = openIdConnectSessionDetails.OIDC["id_token"];
                 *  loginProvider = openIdConnectSessionDetails.LoginProider;
                 * }
                 */
                // no matter what, we are logging out our own app.
                // Do Not trust the provider to keep its end of the bargain to frontchannel sign us out.
                await _signInManager.SignOutAsync();

                _logger.LogInformation("User logged out.");

                HttpContext.Session.Clear();

                if (!string.IsNullOrEmpty(idToken) && !string.IsNullOrEmpty(loginProvider))
                {
                    // we have an external OIDC provider here.
                    var clientSignoutCallback  = $"{Request.Scheme}://{Request.Host}/Identity/Account/SignoutCallbackOidc";
                    var discoverCacheContainer = _configuredDiscoverCacheContainerFactory.Get(loginProvider);
                    var discoveryCache         = await discoverCacheContainer.DiscoveryCache.GetAsync();

                    var endSession = discoveryCache.EndSessionEndpoint;
                    EndSessionUrl = $"{endSession}?id_token_hint={idToken}&post_logout_redirect_uri={clientSignoutCallback}";
                    // this redirect is to the provider to log everyone else out.
                    // We will get a double hit here, as our $"{Request.Scheme}://{Request.Host}/Account/SignoutFrontChannel";
                    // will get hit as well.
                    return(new RedirectResult(EndSessionUrl));
                }
            }

            return(new RedirectResult("/"));
        }
Beispiel #4
0
        public async Task <IActionResult> OnGetAsync()
        {
            var clientSignoutCallback = $"{Request.Scheme}://{Request.Host}/Account/SignoutCallbackOidc";
            // Get id_token first to seed the iframe logout
            var user = await _signInManager.UserManager.GetUserAsync(User);

            if (user != null)
            {
                var info = await _signInManager.GetExternalLoginInfoAsync();

                var query = from item in info.AuthenticationTokens
                            where item.Name == "id_token"
                            select item;
                var idToken = query.FirstOrDefault();
                IdToken = idToken.Value;

                var discoverCacheContainer = _configuredDiscoverCacheContainerFactory.Get(info.LoginProvider);
                var discoveryCache         = await discoverCacheContainer.DiscoveryCache.GetAsync();

                var endSession = discoveryCache.EndSessionEndpoint;
                EndSessionUrl = $"{endSession}?id_token_hint={IdToken}&post_logout_redirect_uri={clientSignoutCallback}";

                // no matter what, we are logging out our own app.
                // Do Not trust the provider to keep its end of the bargain to frontchannel sign us out.
                await _signInManager.SignOutAsync();

                _logger.LogInformation("User logged out.");

                // this redirect is to the provider to log everyone else out.
                // We will get a double hit here, as our $"{Request.Scheme}://{Request.Host}/Account/SignoutFrontChannel";
                // will get hit as well.
                return(new RedirectResult(EndSessionUrl));
                //return Page();  return this is you want iFrame loggout.  Your OIDC provider needs to let this go through though.
            }
            return(new RedirectResult("/"));
        }