Exemplo n.º 1
0
        private async Task <IActionResult> AuthnRequestAsync <T>(SamlUpParty party, Saml2Binding <T> binding, SamlUpSequenceData samlUpSequenceData)
        {
            var samlConfig = await saml2ConfigurationLogic.GetSamlUpConfigAsync(party, includeSigningAndDecryptionCertificate : true);

            binding.RelayState = await sequenceLogic.CreateExternalSequenceIdAsync();

            var saml2AuthnRequest = new Saml2AuthnRequest(samlConfig);

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

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

            default:
                break;
            }

            if (party.AuthnContextClassReferences?.Count() > 0)
            {
                saml2AuthnRequest.RequestedAuthnContext = new RequestedAuthnContext
                {
                    Comparison           = party.AuthnContextComparison.HasValue ? (AuthnContextComparisonTypes)Enum.Parse(typeof(AuthnContextComparisonTypes), party.AuthnContextComparison.Value.ToString()) : null,
                    AuthnContextClassRef = party.AuthnContextClassReferences,
                };
            }

            binding.Bind(saml2AuthnRequest);
            logger.ScopeTrace(() => $"SAML Authn request '{saml2AuthnRequest.XmlDocument.OuterXml}'.", traceType: TraceTypes.Message);
            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();
            }
        }
Exemplo n.º 2
0
        private async Task <IActionResult> LogoutRequestAsync <T>(SamlUpParty party, Saml2Binding <T> binding, SamlUpSequenceData samlUpSequenceData)
        {
            var samlConfig = await saml2ConfigurationLogic.GetSamlUpConfigAsync(party, includeSigningAndDecryptionCertificate : true);

            binding.RelayState = await sequenceLogic.CreateExternalSequenceIdAsync();

            var saml2LogoutRequest = new Saml2LogoutRequest(samlConfig);

            var session = await sessionUpPartyLogic.GetSessionAsync(party);

            if (session == null)
            {
                return(await LogoutResponseDownAsync(samlUpSequenceData));
            }

            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 jwtClaims    = samlUpSequenceData.SessionClaims.ToClaimList();
            var nameID       = jwtClaims?.Where(c => c.Type == JwtClaimTypes.Subject).Select(c => c.Value).FirstOrDefault();
            var nameIdFormat = jwtClaims?.Where(c => c.Type == Constants.JwtClaimTypes.SubFormat).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}'.", traceType: TraceTypes.Message);
            logger.ScopeTrace(() => $"Logout URL '{samlConfig.SingleLogoutDestination?.OriginalString}'.");
            logger.ScopeTrace(() => "Up, SAML Logout request.", triggerEvent: true);

            _ = await sessionUpPartyLogic.DeleteSessionAsync(party, 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();
            }
        }
Exemplo n.º 3
0
        public async Task <IActionResult> SpMetadataAsync(string partyId)
        {
            logger.ScopeTrace(() => "Up, SP Metadata request.");
            logger.SetScopeProperty(Constants.Logs.UpPartyId, partyId);
            var party = RouteBinding.UpParty != null ? await tenantRepository.GetAsync <SamlUpParty>(partyId) : null;

            var signMetadata = party != null ? party.SignMetadata : false;

            var samlConfig = await saml2ConfigurationLogic.GetSamlUpConfigAsync(party, includeSigningAndDecryptionCertificate : signMetadata, includeSignatureValidationCertificates : false);

            var acsDestination          = new Uri(UrlCombine.Combine(HttpContext.GetHostWithTenantAndTrack(), RouteBinding.PartyNameAndBinding, Constants.Routes.SamlController, Constants.Endpoints.SamlAcs));
            var singleLogoutDestination = new Uri(UrlCombine.Combine(HttpContext.GetHostWithTenantAndTrack(), RouteBinding.PartyNameAndBinding, Constants.Routes.SamlController, Constants.Endpoints.SamlSingleLogout));

            var entityDescriptor = new EntityDescriptor(samlConfig, signMetadata);

            if (party != null)
            {
                entityDescriptor.ValidUntil = new TimeSpan(0, 0, settings.SamlMetadataLifetime).Days;
            }

            var trackCertificates = GetTrackCertificates();

            entityDescriptor.SPSsoDescriptor = new SPSsoDescriptor
            {
                //AuthnRequestsSigned = true,
                //WantAssertionsSigned = true,
                SigningCertificates       = trackCertificates,
                AssertionConsumerServices = new AssertionConsumerService[]
                {
                    new AssertionConsumerService {
                        Binding = ToSamleBindingUri(party?.AuthnBinding?.ResponseBinding), Location = acsDestination
                    },
                },
            };
            entityDescriptor.SPSsoDescriptor.SingleLogoutServices = new SingleLogoutService[]
            {
                new SingleLogoutService {
                    Binding = ToSamleBindingUri(party?.LogoutBinding?.ResponseBinding), Location = singleLogoutDestination
                },
            };

            if (party?.MetadataIncludeEncryptionCertificates == true)
            {
                entityDescriptor.SPSsoDescriptor.EncryptionCertificates = trackCertificates;
                entityDescriptor.SPSsoDescriptor.SetDefaultEncryptionMethods();
            }

            if (party?.MetadataNameIdFormats?.Count > 0)
            {
                entityDescriptor.SPSsoDescriptor.NameIDFormats = party.MetadataNameIdFormats.Select(nf => new Uri(nf));
            }

            if (party?.MetadataAttributeConsumingServices?.Count() > 0)
            {
                var attributeConsumingServices = new List <AttributeConsumingService>();
                foreach (var aItem in party.MetadataAttributeConsumingServices)
                {
                    var attributeConsumingService = new AttributeConsumingService {
                        ServiceName = new ServiceName(aItem.ServiceName.Name, aItem.ServiceName.Lang)
                    };
                    attributeConsumingService.RequestedAttributes = aItem.RequestedAttributes.Select(ra => string.IsNullOrEmpty(ra.NameFormat) ? new RequestedAttribute(ra.Name, ra.IsRequired) : new RequestedAttribute(ra.Name, ra.IsRequired, ra.NameFormat));
                    attributeConsumingServices.Add(attributeConsumingService);
                }
                entityDescriptor.SPSsoDescriptor.AttributeConsumingServices = attributeConsumingServices;
            }

            if (party?.MetadataContactPersons?.Count() > 0)
            {
                entityDescriptor.ContactPersons = GetContactPersons(party.MetadataContactPersons);
            }

            return(new Saml2Metadata(entityDescriptor).CreateMetadata().ToActionResult());
        }