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));
            }
        }
Exemple #2
0
        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());
        }