예제 #1
0
        private async Task <IActionResult> LogoutAsync <T>(SamlUpParty party, Saml2Binding <T> binding, LogoutRequest logoutRequest)
        {
            var samlConfig = saml2ConfigurationLogic.GetSamlUpConfig(party, includeSigningCertificate: true);
            await formActionLogic.AddFormActionByUrlAsync(samlConfig.SingleLogoutDestination.OriginalString);

            binding.RelayState = SequenceString;

            var saml2LogoutRequest = new Saml2LogoutRequest(samlConfig);

            saml2LogoutRequest.SessionIndex = logoutRequest.SessionId;

            var nameID       = logoutRequest.Claims?.Where(c => c.Type == Saml2ClaimTypes.NameId).Select(c => c.Value).FirstOrDefault();
            var nameIdFormat = logoutRequest.Claims?.Where(c => c.Type == Saml2ClaimTypes.NameIdFormat).Select(c => c.Value).FirstOrDefault();

            if (!nameID.IsNullOrEmpty())
            {
                if (nameIdFormat.IsNullOrEmpty())
                {
                    saml2LogoutRequest.NameId = new Saml2NameIdentifier(nameID);
                }
                else
                {
                    saml2LogoutRequest.NameId = new Saml2NameIdentifier(nameID, new Uri(nameIdFormat));
                }
            }

            binding.Bind(saml2LogoutRequest);
            logger.ScopeTrace($"SAML Logout request '{saml2LogoutRequest.XmlDocument.OuterXml}'.");
            logger.ScopeTrace($"Logout url '{samlConfig.SingleLogoutDestination?.OriginalString}'.");
            logger.ScopeTrace("Up, SAML Logout request.", triggerEvent: true);

            if (binding is Saml2Binding <Saml2RedirectBinding> )
            {
                return(await Task.FromResult((binding as Saml2RedirectBinding).ToActionResult()));
            }
            if (binding is Saml2Binding <Saml2PostBinding> )
            {
                return(await Task.FromResult((binding as Saml2PostBinding).ToActionResult()));
            }
            else
            {
                throw new NotSupportedException();
            }
        }
예제 #2
0
        private async Task <IActionResult> AuthnRequestAsync <T>(SamlUpParty party, Saml2Binding <T> binding, SamlUpSequenceData samlUpSequenceData)
        {
            var samlConfig = saml2ConfigurationLogic.GetSamlUpConfig(party);

            binding.RelayState = SequenceString;
            var saml2AuthnRequest = new Saml2AuthnRequest(samlConfig);

            switch (samlUpSequenceData.LoginAction)
            {
            case LoginAction.ReadSession:
                saml2AuthnRequest.IsPassive = true;
                break;

            case LoginAction.RequireLogin:
                saml2AuthnRequest.ForceAuthn = true;
                break;

            default:
                break;
            }

            binding.Bind(saml2AuthnRequest);
            logger.ScopeTrace($"SAML Authn request '{saml2AuthnRequest.XmlDocument.OuterXml}'.");
            logger.ScopeTrace($"Authn URL '{samlConfig.SingleSignOnDestination?.OriginalString}'.");
            logger.ScopeTrace("Up, Sending SAML Authn request.", triggerEvent: true);

            securityHeaderLogic.AddFormActionAllowAll();

            if (binding is Saml2Binding <Saml2RedirectBinding> )
            {
                return(await(binding as Saml2RedirectBinding).ToActionFormResultAsync());
            }
            else if (binding is Saml2Binding <Saml2PostBinding> )
            {
                return(await(binding as Saml2PostBinding).ToActionFormResultAsync());
            }
            else
            {
                throw new NotSupportedException();
            }
        }
예제 #3
0
        public async Task <IActionResult> SpMetadataAsync(string partyId)
        {
            logger.ScopeTrace("Up, SP Metadata request.");
            logger.SetScopeProperty("upPartyId", partyId);
            var party = await tenantRepository.GetAsync <SamlUpParty>(partyId);

            var samlConfig = saml2ConfigurationLogic.GetSamlUpConfig(party, true);

            var acsDestination                  = new Uri(UrlCombine.Combine(HttpContext.GetHost(), RouteBinding.TenantName, RouteBinding.TrackName, RouteBinding.PartyNameAndBinding, Constants.Routes.SamlController, Constants.Endpoints.SamlAcs));
            var singleLogoutDestination         = new Uri(UrlCombine.Combine(HttpContext.GetHost(), RouteBinding.TenantName, RouteBinding.TrackName, RouteBinding.PartyNameAndBinding, Constants.Routes.SamlController, Constants.Endpoints.SamlSingleLogout));
            var singleLogoutResponseDestination = new Uri(UrlCombine.Combine(HttpContext.GetHost(), RouteBinding.TenantName, RouteBinding.TrackName, RouteBinding.PartyNameAndBinding, Constants.Routes.SamlController, Constants.Endpoints.SamlLoggedOut));

            var entityDescriptor = new EntityDescriptor(samlConfig);

            entityDescriptor.ValidUntil      = new TimeSpan(0, 0, party.MetadataLifetime).Days;
            entityDescriptor.SPSsoDescriptor = new SPSsoDescriptor
            {
                //AuthnRequestsSigned = true,
                //WantAssertionsSigned = true,
                SigningCertificates = new X509Certificate2[]
                {
                    samlConfig.SigningCertificate
                },
                //EncryptionCertificates = new X509Certificate2[]
                //{
                //    config.DecryptionCertificate
                //},
                AssertionConsumerServices = new AssertionConsumerService[]
                {
                    new AssertionConsumerService {
                        Binding = ToSamleBindingUri(party.AuthnBinding.ResponseBinding), Location = acsDestination,
                    },
                },
            };
            if (party.LogoutBinding != null)
            {
                entityDescriptor.SPSsoDescriptor.SingleLogoutServices = new SingleLogoutService[]
                {
                    new SingleLogoutService {
                        Binding = ToSamleBindingUri(party.LogoutBinding.ResponseBinding), Location = singleLogoutDestination, ResponseLocation = singleLogoutResponseDestination
                    },
                };
            }

            return(new Saml2Metadata(entityDescriptor).CreateMetadata().ToActionResult());
        }
예제 #4
0
        private async Task <IActionResult> LogoutRequestAsync <T>(SamlUpParty party, Saml2Binding <T> binding, SamlUpSequenceData samlUpSequenceData)
        {
            var samlConfig = saml2ConfigurationLogic.GetSamlUpConfig(party, includeSigningCertificate: true);

            binding.RelayState = SequenceString;

            var saml2LogoutRequest = new Saml2LogoutRequest(samlConfig);

            var session = await sessionUpPartyLogic.GetSessionAsync(party);

            if (session != null)
            {
                try
                {
                    if (!samlUpSequenceData.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);
                }

                saml2LogoutRequest.SessionIndex = session.ExternalSessionId;

                samlUpSequenceData.SessionDownPartyLinks = session.DownPartyLinks;
                samlUpSequenceData.SessionClaims         = session.Claims;
                await sequenceLogic.SaveSequenceDataAsync(samlUpSequenceData);
            }

            var claims       = samlUpSequenceData.Claims.ToClaimList();
            var nameID       = claims?.Where(c => c.Type == Saml2ClaimTypes.NameId).Select(c => c.Value).FirstOrDefault();
            var nameIdFormat = claims?.Where(c => c.Type == Saml2ClaimTypes.NameIdFormat).Select(c => c.Value).FirstOrDefault();

            if (!nameID.IsNullOrEmpty())
            {
                var prePartyName = $"{party.Name}|";
                if (nameID.StartsWith(prePartyName, StringComparison.Ordinal))
                {
                    nameID = nameID.Remove(0, prePartyName.Length);
                }
                if (nameIdFormat.IsNullOrEmpty())
                {
                    saml2LogoutRequest.NameId = new Saml2NameIdentifier(nameID);
                }
                else
                {
                    saml2LogoutRequest.NameId = new Saml2NameIdentifier(nameID, new Uri(nameIdFormat));
                }
            }

            binding.Bind(saml2LogoutRequest);
            logger.ScopeTrace($"SAML Logout request '{saml2LogoutRequest.XmlDocument.OuterXml}'.");
            logger.ScopeTrace($"Logout URL '{samlConfig.SingleLogoutDestination?.OriginalString}'.");
            logger.ScopeTrace("Up, SAML Logout request.", triggerEvent: true);

            _ = await sessionUpPartyLogic.DeleteSessionAsync(session);

            await oauthRefreshTokenGrantLogic.DeleteRefreshTokenGrantsAsync(samlUpSequenceData.SessionId);

            securityHeaderLogic.AddFormActionAllowAll();

            if (binding is Saml2Binding <Saml2RedirectBinding> )
            {
                return(await(binding as Saml2RedirectBinding).ToActionFormResultAsync());
            }
            else if (binding is Saml2Binding <Saml2PostBinding> )
            {
                return(await(binding as Saml2PostBinding).ToActionFormResultAsync());
            }
            else
            {
                throw new NotSupportedException();
            }
        }