public async Task <IActionResult> EndSessionResponseAsync(string partyId) { logger.ScopeTrace($"Up, OIDC End session response."); logger.SetScopeProperty("upPartyId", partyId); var party = await tenantRepository.GetAsync <OidcUpParty>(partyId); logger.SetScopeProperty("upPartyClientId", party.Client.ClientId); var queryDictionary = HttpContext.Request.Query.ToDictionary(); var rpInitiatedLogoutResponse = queryDictionary.ToObject <RpInitiatedLogoutResponse>(); logger.ScopeTrace($"Up, End session response '{rpInitiatedLogoutResponse.ToJsonIndented()}'."); rpInitiatedLogoutResponse.Validate(); if (rpInitiatedLogoutResponse.State.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(rpInitiatedLogoutResponse.State), rpInitiatedLogoutResponse.GetTypeName()); } await sequenceLogic.ValidateSequenceAsync(rpInitiatedLogoutResponse.State); var sequenceData = await sequenceLogic.GetSequenceDataAsync <OidcUpSequenceData>(remove : party.DisableSingleLogout); logger.ScopeTrace("Up, Successful OIDC End session response.", triggerEvent: true); if (party.DisableSingleLogout) { return(await LogoutResponseDownAsync(sequenceData)); } else { (var doSingleLogout, var singleLogoutSequenceData) = await singleLogoutDownLogic.InitializeSingleLogoutAsync(new UpPartyLink { Name = party.Name, Type = party.Type }, sequenceData.DownPartyLink, sequenceData.SessionDownPartyLinks, sequenceData.SessionClaims); if (doSingleLogout) { return(await singleLogoutDownLogic.StartSingleLogoutAsync(singleLogoutSequenceData)); } else { await sequenceLogic.RemoveSequenceDataAsync <OidcUpSequenceData>(); return(await LogoutResponseDownAsync(sequenceData)); } } }
private async Task <IActionResult> EndSessionResponseAsync(OidcUpParty party) { var queryDictionary = HttpContext.Request.Query.ToDictionary(); var rpInitiatedLogoutResponse = queryDictionary.ToObject <RpInitiatedLogoutResponse>(); logger.ScopeTrace(() => $"Up, End session response '{rpInitiatedLogoutResponse.ToJsonIndented()}'.", traceType: TraceTypes.Message); rpInitiatedLogoutResponse.Validate(); if (rpInitiatedLogoutResponse.State.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(rpInitiatedLogoutResponse.State), rpInitiatedLogoutResponse.GetTypeName()); } await sequenceLogic.ValidateExternalSequenceIdAsync(rpInitiatedLogoutResponse.State); var sequenceData = await sequenceLogic.GetSequenceDataAsync <OidcUpSequenceData>(remove : party.DisableSingleLogout); logger.ScopeTrace(() => "Up, Successful OIDC End session response.", triggerEvent: true); if (party.DisableSingleLogout) { return(await LogoutResponseDownAsync(sequenceData)); } else { (var doSingleLogout, var singleLogoutSequenceData) = await singleLogoutDownLogic.InitializeSingleLogoutAsync(new UpPartyLink { Name = party.Name, Type = party.Type }, sequenceData.DownPartyLink, sequenceData.SessionDownPartyLinks, sequenceData.SessionClaims); if (doSingleLogout) { return(await singleLogoutDownLogic.StartSingleLogoutAsync(singleLogoutSequenceData)); } else { await sequenceLogic.RemoveSequenceDataAsync <OidcUpSequenceData>(); return(await LogoutResponseDownAsync(sequenceData)); } } }
private async Task <IActionResult> LogoutResponseAsync <T>(SamlUpParty party, Saml2Binding <T> binding) { var samlConfig = await saml2ConfigurationLogic.GetSamlUpConfigAsync(party); var saml2LogoutResponse = new Saml2LogoutResponse(samlConfig); binding.ReadSamlResponse(HttpContext.Request.ToGenericHttpRequest(), saml2LogoutResponse); await sequenceLogic.ValidateExternalSequenceIdAsync(binding.RelayState); var sequenceData = await sequenceLogic.GetSequenceDataAsync <SamlUpSequenceData>(remove : party.DisableSingleLogout); try { logger.ScopeTrace(() => $"SAML Logout response '{saml2LogoutResponse.XmlDocument.OuterXml}'.", traceType: TraceTypes.Message); logger.SetScopeProperty(Constants.Logs.Status, saml2LogoutResponse.Status.ToString()); logger.ScopeTrace(() => "Up, SAML Logout response.", triggerEvent: true); if (saml2LogoutResponse.Status != Saml2StatusCodes.Success) { throw new SamlRequestException("Unsuccessful Logout response.") { RouteBinding = RouteBinding, Status = saml2LogoutResponse.Status }; } try { binding.Unbind(HttpContext.Request.ToGenericHttpRequest(), saml2LogoutResponse); logger.ScopeTrace(() => "Up, Successful SAML Logout response.", triggerEvent: true); } catch (Exception ex) { var isex = saml2ConfigurationLogic.GetInvalidSignatureValidationCertificateException(samlConfig, ex); if (isex != null) { throw isex; } throw; } if (party.DisableSingleLogout) { return(await LogoutResponseDownAsync(sequenceData)); } else { (var doSingleLogout, var singleLogoutSequenceData) = await singleLogoutDownLogic.InitializeSingleLogoutAsync(new UpPartyLink { Name = party.Name, Type = party.Type }, sequenceData.DownPartyLink, sequenceData.SessionDownPartyLinks, sequenceData.SessionClaims); if (doSingleLogout) { return(await singleLogoutDownLogic.StartSingleLogoutAsync(singleLogoutSequenceData)); } else { await sequenceLogic.RemoveSequenceDataAsync <SamlUpSequenceData>(); return(await LogoutResponseDownAsync(sequenceData)); } } } catch (StopSequenceException) { throw; } catch (SamlRequestException ex) { logger.Error(ex); return(await LogoutResponseDownAsync(sequenceData, status : ex.Status)); } catch (Exception ex) { logger.Error(ex); return(await LogoutResponseDownAsync(sequenceData, status : Saml2StatusCodes.Responder)); } }
public async Task <IActionResult> FrontChannelLogoutAsync(string partyId) { logger.ScopeTrace(() => "Up, OIDC Front channel logout."); logger.SetScopeProperty(Constants.Logs.UpPartyId, partyId); var party = await tenantRepository.GetAsync <OidcUpParty>(partyId); logger.SetScopeProperty(Constants.Logs.UpPartyClientId, party.Client.ClientId); if (party.Client.DisableFrontChannelLogout) { return(new BadRequestResult()); } var queryDictionary = HttpContext.Request.Query.ToDictionary(); var frontChannelLogoutRequest = queryDictionary.ToObject <FrontChannelLogoutRequest>(); logger.ScopeTrace(() => $"Up, Front channel logout request '{frontChannelLogoutRequest.ToJsonIndented()}'.", traceType: TraceTypes.Message); frontChannelLogoutRequest.Validate(); if (party.Client.FrontChannelLogoutSessionRequired) { if (frontChannelLogoutRequest.SessionId.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(frontChannelLogoutRequest.SessionId), frontChannelLogoutRequest.GetTypeName()); } } var session = await sessionUpPartyLogic.GetSessionAsync(party); logger.ScopeTrace(() => "Up, Successful OIDC Front channel logout request.", triggerEvent: true); if (session != null) { if (party.Client.FrontChannelLogoutSessionRequired) { if (!party.Issuers.Where(i => i == frontChannelLogoutRequest.Issuer).Any()) { throw new Exception("Incorrect issuer."); } if (session.ExternalSessionId != frontChannelLogoutRequest.SessionId) { throw new Exception("Incorrect session id."); } } var _ = await sessionUpPartyLogic.DeleteSessionAsync(party, session); await oauthRefreshTokenGrantLogic.DeleteRefreshTokenGrantsAsync(session.SessionId); if (!party.DisableSingleLogout) { var allowIframeOnDomains = new List <string>().ConcatOnce(party.Client.AuthorizeUrl?.UrlToDomain()).ConcatOnce(party.Client.EndSessionUrl?.UrlToDomain()).ConcatOnce(party.Client.TokenUrl?.UrlToDomain()); (var doSingleLogout, var singleLogoutSequenceData) = await singleLogoutDownLogic.InitializeSingleLogoutAsync(new UpPartyLink { Name = party.Name, Type = party.Type }, null, session.DownPartyLinks, session.Claims, allowIframeOnDomains, hostedInIframe : true); if (doSingleLogout) { return(await singleLogoutDownLogic.StartSingleLogoutAsync(singleLogoutSequenceData)); } } } return(new OkResult()); }
public async Task <IActionResult> FrontChannelLogoutAsync(string partyId) { logger.ScopeTrace("Up, OIDC Front channel logout."); logger.SetScopeProperty("upPartyId", partyId); var party = await tenantRepository.GetAsync <OidcUpParty>(partyId); logger.SetScopeProperty("upPartyClientId", party.Client.ClientId); if (party.Client.DisableFrontChannelLogout) { return(new BadRequestResult()); } var queryDictionary = HttpContext.Request.Query.ToDictionary(); var frontChannelLogoutRequest = queryDictionary.ToObject <FrontChannelLogoutRequest>(); logger.ScopeTrace($"Up, Front channel logout request '{frontChannelLogoutRequest.ToJsonIndented()}'."); frontChannelLogoutRequest.Validate(); if (party.Client.FrontChannelLogoutSessionRequired) { if (frontChannelLogoutRequest.SessionId.IsNullOrEmpty()) { throw new ArgumentNullException(nameof(frontChannelLogoutRequest.SessionId), frontChannelLogoutRequest.GetTypeName()); } } var session = await sessionUpPartyLogic.GetSessionAsync(party); logger.ScopeTrace("Up, Successful OIDC Front channel logout request.", triggerEvent: true); if (session != null) { if (party.Client.FrontChannelLogoutSessionRequired) { if (!session.Claims.Where(c => c.Claim == JwtClaimTypes.Issuer && c.Values.Where(v => v == frontChannelLogoutRequest.Issuer).Any()).Any()) { throw new Exception("Incorrect issuer."); } if (session.ExternalSessionId != frontChannelLogoutRequest.SessionId) { throw new Exception("Incorrect session id."); } } var _ = await sessionUpPartyLogic.DeleteSessionAsync(session); await oauthRefreshTokenGrantLogic.DeleteRefreshTokenGrantsAsync(session.SessionId); if (!party.DisableSingleLogout) { (var doSingleLogout, var singleLogoutSequenceData) = await singleLogoutDownLogic.InitializeSingleLogoutAsync(new UpPartyLink { Name = party.Name, Type = party.Type }, null, session.DownPartyLinks, session.Claims, redirectAfterLogout : false); if (doSingleLogout) { securityHeaderLogic.AddAllowIframeOnUrls(new [] { party.Client.AuthorizeUrl, party.Client.EndSessionUrl }); return(await singleLogoutDownLogic.StartSingleLogoutAsync(singleLogoutSequenceData)); } } } return(new OkResult()); }