public async Task LogoutAsync(OpenidConnectPkceSettings openidClientPkceSettings = null)
        {
            try
            {
                openidClientPkceSettings = openidClientPkceSettings ?? globalOpenidClientPkceSettings;

                var logoutCallBackUri = new Uri(new Uri(navigationManager.BaseUri), openidClientPkceSettings.LogoutCallBackPath).OriginalString;
                var state             = await SaveStateAsync(openidClientPkceSettings, logoutCallBackUri, navigationManager.Uri);

                var idTokenHint = await(authenticationStateProvider as OidcAuthenticationStateProvider).GetIdToken(readInvalidSession: true);
                if (idTokenHint.IsNullOrEmpty())
                {
                    navigationManager.NavigateTo(logoutCallBackUri, true);
                }
                var rpInitiatedLogoutRequest = new RpInitiatedLogoutRequest
                {
                    IdTokenHint           = idTokenHint,
                    PostLogoutRedirectUri = logoutCallBackUri,
                    State = state
                };

                var nameValueCollection = rpInitiatedLogoutRequest.ToDictionary();
                var oidcDiscovery       = await GetOidcDiscoveryAsync(openidClientPkceSettings.OidcDiscoveryUri);

                var endSessionEndpointUri = QueryHelpers.AddQueryString(oidcDiscovery.EndSessionEndpoint, nameValueCollection);
                navigationManager.NavigateTo(endSessionEndpointUri, true);
            }
            catch (Exception ex)
            {
                throw new SecurityException($"Failed to end session, Authority '{openidClientPkceSettings.Authority}'.", ex);
            }
        }
Exemplo n.º 2
0
        public async Task <IActionResult> EndSessionRequestAsync(string partyId)
        {
            logger.ScopeTrace("Up, OIDC End session request.");
            var oidcUpSequenceData = await sequenceLogic.GetSequenceDataAsync <OidcUpSequenceData>(remove : false);

            if (!oidcUpSequenceData.UpPartyId.Equals(partyId, StringComparison.Ordinal))
            {
                throw new Exception("Invalid up-party id.");
            }
            logger.SetScopeProperty("upPartyId", oidcUpSequenceData.UpPartyId);

            var party = await tenantRepository.GetAsync <OidcUpParty>(oidcUpSequenceData.UpPartyId);

            logger.SetScopeProperty("upPartyClientId", party.Client.ClientId);
            ValidatePartyLogoutSupport(party);

            var postLogoutRedirectUrl    = HttpContext.GetUpPartyUrl(party.Name, Constants.Routes.OAuthController, Constants.Endpoints.EndSessionResponse, partyBindingPattern: party.PartyBindingPattern);
            var rpInitiatedLogoutRequest = new RpInitiatedLogoutRequest
            {
                PostLogoutRedirectUri = postLogoutRedirectUrl,
                State = SequenceString
            };

            var session = await sessionUpPartyLogic.GetSessionAsync(party);

            if (session != null)
            {
                try
                {
                    if (!oidcUpSequenceData.SessionId.Equals(session.SessionId, StringComparison.Ordinal))
                    {
                        throw new Exception("Requested session ID do not match up-party session ID.");
                    }
                }
                catch (Exception ex)
                {
                    logger.Warning(ex);
                }

                rpInitiatedLogoutRequest.IdTokenHint = session.IdToken;

                oidcUpSequenceData.SessionDownPartyLinks = session.DownPartyLinks;
                oidcUpSequenceData.SessionClaims         = session.Claims;
                await sequenceLogic.SaveSequenceDataAsync(oidcUpSequenceData);
            }
            logger.ScopeTrace($"Up, End session request '{rpInitiatedLogoutRequest.ToJsonIndented()}'.");

            _ = await sessionUpPartyLogic.DeleteSessionAsync(session);

            await oauthRefreshTokenGrantLogic.DeleteRefreshTokenGrantsAsync(oidcUpSequenceData.SessionId);

            securityHeaderLogic.AddFormActionAllowAll();

            var nameValueCollection = rpInitiatedLogoutRequest.ToDictionary();

            logger.ScopeTrace($"Up, End session request URL '{party.Client.EndSessionUrl}'.");
            logger.ScopeTrace("Up, Sending OIDC End session request.", triggerEvent: true);
            return(await nameValueCollection.ToRedirectResultAsync(party.Client.EndSessionUrl));
        }
        private void ValidateEndSessionRequest(TClient client, RpInitiatedLogoutRequest rpInitiatedLogoutRequest)
        {
            rpInitiatedLogoutRequest.Validate();

            if (!rpInitiatedLogoutRequest.PostLogoutRedirectUri.IsNullOrWhiteSpace() &&
                !client.RedirectUris.Any(u => u.Equals(rpInitiatedLogoutRequest.PostLogoutRedirectUri, StringComparison.InvariantCultureIgnoreCase)) &&
                !rpInitiatedLogoutRequest.PostLogoutRedirectUri.Equals(rpInitiatedLogoutRequest.PostLogoutRedirectUri, StringComparison.InvariantCultureIgnoreCase))
            {
                throw new OAuthRequestException($"Invalid post logout redirect Uri '{rpInitiatedLogoutRequest.PostLogoutRedirectUri}'.");
            }
        }