private async Task <IActionResult> LogoutRequestAsync <T>(SamlDownParty party, Saml2Binding <T> binding) { var samlConfig = await saml2ConfigurationLogic.GetSamlDownConfigAsync(party); var saml2LogoutRequest = new Saml2LogoutRequest(samlConfig); binding.ReadSamlRequest(HttpContext.Request.ToGenericHttpRequest(), saml2LogoutRequest); logger.ScopeTrace(() => $"SAML Logout request '{saml2LogoutRequest.XmlDocument.OuterXml}'.", traceType: TraceTypes.Message); try { ValidateLogoutRequest(party, saml2LogoutRequest); try { binding.Unbind(HttpContext.Request.ToGenericHttpRequest(), saml2LogoutRequest); logger.ScopeTrace(() => "Down, SAML Logout request accepted.", triggerEvent: true); } catch (Exception ex) { var isex = saml2ConfigurationLogic.GetInvalidSignatureValidationCertificateException(samlConfig, ex); if (isex != null) { throw isex; } throw; } await sequenceLogic.SaveSequenceDataAsync(new SamlDownSequenceData { Id = saml2LogoutRequest.Id.Value, RelayState = binding.RelayState }); var type = RouteBinding.ToUpParties.First().Type; logger.ScopeTrace(() => $"Request, Up type '{type}'."); switch (type) { case PartyTypes.Login: return(await serviceProvider.GetService <LogoutUpLogic>().LogoutRedirect(RouteBinding.ToUpParties.First(), GetLogoutRequest(party, saml2LogoutRequest))); case PartyTypes.OAuth2: throw new NotImplementedException(); case PartyTypes.Oidc: return(await serviceProvider.GetService <OidcRpInitiatedLogoutUpLogic <OidcUpParty, OidcUpClient> >().EndSessionRequestRedirectAsync(RouteBinding.ToUpParties.First(), GetLogoutRequest(party, saml2LogoutRequest))); case PartyTypes.Saml2: return(await serviceProvider.GetService <SamlLogoutUpLogic>().LogoutRequestRedirectAsync(RouteBinding.ToUpParties.First(), GetSamlLogoutRequest(party, saml2LogoutRequest))); default: throw new NotSupportedException($"Party type '{type}' not supported."); } } catch (SamlRequestException ex) { logger.Error(ex); return(await LogoutResponseAsync(party, samlConfig, saml2LogoutRequest.Id.Value, binding.RelayState, ex.Status)); } }
public async Task <IActionResult> IdPMetadataAsync(string partyId) { logger.ScopeTrace(() => "Down, IdP Metadata request."); logger.SetScopeProperty(Constants.Logs.DownPartyId, partyId); var party = RouteBinding.DownParty != null ? await tenantRepository.GetAsync <SamlDownParty>(partyId) : null; var signMetadata = party != null ? party.SignMetadata : false; var samlConfig = await saml2ConfigurationLogic.GetSamlDownConfigAsync(party, includeSigningCertificate : signMetadata, includeSignatureValidationCertificates : false); var authnDestination = new Uri(UrlCombine.Combine(HttpContext.GetHostWithTenantAndTrack(), RouteBinding.PartyNameAndBinding, Constants.Routes.SamlController, Constants.Endpoints.SamlAuthn)); var logoutDestination = new Uri(UrlCombine.Combine(HttpContext.GetHostWithTenantAndTrack(), RouteBinding.PartyNameAndBinding, Constants.Routes.SamlController, Constants.Endpoints.SamlLogout)); var entityDescriptor = new EntityDescriptor(samlConfig, signMetadata); if (party != null) { entityDescriptor.ValidUntil = new TimeSpan(0, 0, settings.SamlMetadataLifetime).Days; } var trackCertificates = GetTrackCertificates(); entityDescriptor.IdPSsoDescriptor = new IdPSsoDescriptor { SigningCertificates = trackCertificates, //EncryptionCertificates = trackCertificates, SingleSignOnServices = new SingleSignOnService[] { new SingleSignOnService { Binding = ToSamleBindingUri(party?.AuthnBinding?.RequestBinding), Location = authnDestination }, }, }; entityDescriptor.IdPSsoDescriptor.SingleLogoutServices = new SingleLogoutService[] { new SingleLogoutService { Binding = ToSamleBindingUri(party?.LogoutBinding?.RequestBinding), Location = logoutDestination }, }; if (party?.MetadataNameIdFormats?.Count > 0) { entityDescriptor.IdPSsoDescriptor.NameIDFormats = party.MetadataNameIdFormats.Select(nf => new Uri(nf)); } if (party?.MetadataContactPersons?.Count() > 0) { entityDescriptor.ContactPersons = GetContactPersons(party.MetadataContactPersons); } return(new Saml2Metadata(entityDescriptor).CreateMetadata().ToActionResult()); }