Пример #1
0
        public void SPOPtions_ModulePath_Default()
        {
            var subject = new SPOptions();

            subject.ModulePath.Should().Be("/Saml2");
        }
Пример #2
0
        public void SPOptions_Contacts_IsntNull()
        {
            var subject = new SPOptions();

            subject.Contacts.Should().NotBeNull();
        }
Пример #3
0
        public static Saml2AuthResponse Create(string samlResponse,
                                               Saml2Id responseToId,
                                               EntityId issuer,
                                               X509Certificate2 idpCert,
                                               X509Certificate2 serviceCertificate,
                                               EntityId serviceId)
        {
            var decoded = DecodeBase64(samlResponse);
            var xmlDoc  = new XmlDocument();

            xmlDoc.PreserveWhitespace = true;
            xmlDoc.LoadXml(decoded);

            var response = new Saml2Response(xmlDoc.DocumentElement, responseToId);

            if (response.Status != Saml2StatusCode.Success)
            {
                log.LogWarning("SAML authentication error: " + response.Status + " (" + response.StatusMessage + ")");
                return(new Saml2AuthResponse(false)
                {
                    Status = response.Status
                });
            }

            var spOptions = new SPOptions();

            spOptions.EntityId = serviceId;
            spOptions.ServiceCertificates.Add(serviceCertificate);
            var options = new Options(spOptions);
            var idp     = new IdentityProvider(issuer, spOptions);

            idp.SigningKeys.AddConfiguredKey(idpCert);
            options.IdentityProviders.Add(idp);

            System.Security.Claims.ClaimsIdentity[] identities = null;
            try
            {
                identities = response.GetClaims(options)?.ToArray();
            }
            catch (Sustainsys.Saml2.Exceptions.Saml2ResponseFailedValidationException ex)
            {
                if (ex.Message.Contains("could not be decrypted") && decoded.Contains("http://www.w3.org/2009/xmlenc11#aes128-gcm"))
                {
                    DecryptAesGcmHybrid(xmlDoc, serviceCertificate);
                    return(ParseResponseFromXml(xmlDoc));
                }
                else
                {
                    throw;
                }
            }


            if (identities == null || identities.Length == 0)
            {
                return(new Saml2AuthResponse(false));
            }

            var identity  = identities.First();
            var firstName = identity.FindFirstValue(AttributeNames.GivenName) ?? identity.FindFirstValue(AttributeNames.EidasCurrentGivenName);
            var lastName  = identity.FindFirstValue(AttributeNames.Sn);
            var ssn       = identity.FindFirstValue(AttributeNames.NationalIdentificationNumber);
            var foreignPersonIdentifier = identity.FindFirstValue(AttributeNames.ForeignPersonIdentifier);
            var nameId    = identity.FindFirstValue(AttributeNames.NameIdentifier);
            var sessionId = identity.FindFirstValue(AttributeNames.SessionIndex);

            return(new Saml2AuthResponse(true)
            {
                FirstName = firstName, LastName = lastName, SSN = ssn, RelayState = response.RelayState, NameIdentifier = nameId, SessionIndex = sessionId, ForeignPersonIdentifier = foreignPersonIdentifier
            });
        }
Пример #4
0
        public static EntityDescriptor CreateMetadata(this SPOptions spOptions, Saml2Urls urls)
        {
            var ed = new EntityDescriptor
            {
                EntityId      = spOptions.EntityId,
                Organization  = spOptions.Organization,
                CacheDuration = spOptions.MetadataCacheDuration,
            };

            if (spOptions.MetadataValidDuration.HasValue)
            {
                ed.ValidUntil = DateTime.UtcNow.Add(spOptions.MetadataValidDuration.Value);
            }

            foreach (var contact in spOptions.Contacts)
            {
                ed.Contacts.Add(contact);
            }

            var spsso = new SpSsoDescriptor()
            {
                WantAssertionsSigned = spOptions.WantAssertionsSigned,
                AuthnRequestsSigned  = spOptions.AuthenticateRequestSigningBehavior == SigningBehavior.Always
            };

            spsso.ProtocolsSupported.Add(new Uri("urn:oasis:names:tc:SAML:2.0:protocol"));

            spsso.AssertionConsumerServices.Add(0, new AssertionConsumerService()
            {
                Index     = 0,
                IsDefault = true,
                Binding   = Saml2Binding.HttpPostUri,
                Location  = urls.AssertionConsumerServiceUrl
            });

            spsso.AssertionConsumerServices.Add(1, new AssertionConsumerService()
            {
                Index     = 1,
                IsDefault = false,
                Binding   = Saml2Binding.HttpArtifactUri,
                Location  = urls.AssertionConsumerServiceUrl
            });

            foreach (var attributeService in spOptions.AttributeConsumingServices)
            {
                spsso.AttributeConsumingServices.Add(attributeService.Index, attributeService);
            }

            if (spOptions.ServiceCertificates != null)
            {
                var publishCertificates = spOptions.MetadataCertificates;
                foreach (var serviceCert in publishCertificates)
                {
                    var x509Data = new X509Data();
                    x509Data.Certificates.Add(serviceCert.Certificate);
                    var keyInfo = new DSigKeyInfo();
                    keyInfo.Data.Add(x509Data);

                    spsso.Keys.Add(
                        new KeyDescriptor
                    {
                        Use     = (KeyType)(byte)serviceCert.Use,
                        KeyInfo = keyInfo
                    }
                        );
                }
            }

            if (spOptions.SigningServiceCertificate != null)
            {
                spsso.SingleLogoutServices.Add(new SingleLogoutService(
                                                   Saml2Binding.HttpRedirectUri, urls.LogoutUrl));

                if (spOptions.Compatibility.EnableLogoutOverPost)
                {
                    spsso.SingleLogoutServices.Add(new SingleLogoutService(
                                                       Saml2Binding.HttpPostUri, urls.LogoutUrl));
                }
            }

            if (spOptions.DiscoveryServiceUrl != null &&
                !string.IsNullOrEmpty(spOptions.DiscoveryServiceUrl.OriginalString))
            {
                spsso.DiscoveryResponses.Add(0, new DiscoveryResponse
                {
                    Binding   = Saml2Binding.DiscoveryResponseUri,
                    Index     = 0,
                    IsDefault = true,
                    Location  = urls.SignInUrl
                });
            }

            ed.RoleDescriptors.Add(spsso);

            return(ed);
        }
Пример #5
0
        public void SPOptions_MetadataCertificates_EmptyWhenNoneAdded()
        {
            var subject = new SPOptions();

            subject.MetadataCertificates.Count.Should().Be(0);
        }
Пример #6
0
        public void SPOPtions_ModulePath_Default()
        {
            var subject = new SPOptions();

            subject.ModulePath.Should().Be("/AuthServices");
        }
Пример #7
0
        public static string SetIdpConfiguration(Context context, int tenantId, bool startup = false)
        {
            var contractSettings = TenantUtilities.GetContractSettings(context, tenantId);

            if (contractSettings == null ||
                contractSettings.SamlCompanyCode.IsNullOrEmpty() ||
                contractSettings.SamlLoginUrl.IsNullOrEmpty() ||
                contractSettings.SamlThumbprint.IsNullOrEmpty())
            {
                return(null);
            }
            if (!FindCert(context, contractSettings.SamlThumbprint))
            {
                return(null);
            }
            try
            {
                var section  = (SustainsysSaml2Section)ConfigurationManager.GetSection("sustainsys.saml2");
                var loginUrl = contractSettings.SamlLoginUrl;
                var idp      = loginUrl.TrimEnd(new[] { '/' }).Substring(0, loginUrl.LastIndexOf('/') + 1);
                if (processing)
                {
                    System.Threading.Thread.Sleep(300);
                }
                if (processing == false)
                {
                    processing = true;
                    try
                    {
                        IdentityProviderElement newProvider = null;
                        CertificateElement      newCert     = null;
                        var provider = section.IdentityProviders.FirstOrDefault(p => p.EntityId == idp);
                        if (provider != null)
                        {
                            string signOnUrl = provider.SignOnUrl.ToString();
                            string findValue = provider.SigningCertificate.FindValue;
                            if (signOnUrl == contractSettings.SamlLoginUrl &&
                                findValue == contractSettings.SamlThumbprint)
                            {
                                return($"~/Saml2/SignIn?idp={idp}");
                            }
                            else
                            {
                                newProvider = provider;
                                newCert     = provider.SigningCertificate;
                                WriteIdPSettings(contractSettings?.SamlLoginUrl, contractSettings?.SamlThumbprint, idp, newProvider, newCert);
                                try
                                {
                                    var spOptions = new SPOptions(SustainsysSaml2Section.Current);
                                    var options   = new Options(spOptions);
                                    SustainsysSaml2Section.Current.IdentityProviders.RegisterIdentityProviders(options);
                                    SustainsysSaml2Section.Current.Federations.RegisterFederations(options);
                                    var optionsFromConfiguration = typeof(Options).GetField("optionsFromConfiguration",
                                                                                            System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
                                    optionsFromConfiguration.SetValue(null, new Lazy <Options>(() => options, true));
                                    Sustainsys.Saml2.Mvc.Saml2Controller.Options = Options.FromConfiguration;
                                }
                                catch
                                {
                                    WriteIdPSettings(signOnUrl, findValue, idp, newProvider, newCert);
                                    throw;
                                }
                            }
                        }
                        else
                        {
                            newProvider = new IdentityProviderElement();
                            newCert     = new CertificateElement();
                            WriteIdPSettings(contractSettings?.SamlLoginUrl, contractSettings?.SamlThumbprint, idp, newProvider, newCert);
                            AddIdP(section, newProvider);
                            if (startup == false)
                            {
                                var spOptions = new SPOptions(SustainsysSaml2Section.Current);
                                var options   = new Options(spOptions);
                                SustainsysSaml2Section.Current.IdentityProviders.RegisterIdentityProviders(options);
                                SustainsysSaml2Section.Current.Federations.RegisterFederations(options);
                                var optionsFromConfiguration = typeof(Options).GetField("optionsFromConfiguration",
                                                                                        System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
                                optionsFromConfiguration.SetValue(null, new Lazy <Options>(() => options, true));
                                Sustainsys.Saml2.Mvc.Saml2Controller.Options = Options.FromConfiguration;
                            }
                        }
                    }
                    finally
                    {
                        processing = false;
                    }
                }
                return($"~/Saml2/SignIn?idp={idp}");
            }
            catch (System.Exception e)
            {
                new SysLogModel(context, e);
                return(null);
            }
        }
Пример #8
0
 public Saml2PSerializer(SPOptions spOptions)
 {
     this.spOptions = spOptions;
 }
Пример #9
0
 public IdentityProvider(EntityId entityId, SPOptions spOptions)
 {
     EntityId       = entityId;
     this.spOptions = spOptions;
 }
Пример #10
0
 public Saml2PSecurityTokenHandler(SPOptions spOptions)
 {
     Serializer = new Saml2PSerializer(spOptions);
 }
Пример #11
0
        public void SPOptions_MinIncomingSigningAlgorithm_DefaultValue()
        {
            var subject = new SPOptions();

            subject.MinIncomingSigningAlgorithm.Should().Be(SignedXml.XmlDsigRSASHA256Url);
        }
Пример #12
0
        void Init(Uri applicationUrl, SPOptions spOptions)
        {
            var publicOrigin = spOptions.PublicOrigin ?? applicationUrl;

            Init(publicOrigin, spOptions.ModulePath);
        }
Пример #13
0
        public static ExtendedEntityDescriptor CreateMetadata(this SPOptions spOptions, Saml2Urls urls)
        {
            var ed = new ExtendedEntityDescriptor
            {
                EntityId      = spOptions.EntityId,
                Organization  = spOptions.Organization,
                CacheDuration = spOptions.MetadataCacheDuration,
            };

            if (spOptions.MetadataValidDuration.HasValue)
            {
                ed.ValidUntil = DateTime.UtcNow.Add(spOptions.MetadataValidDuration.Value);
            }

            foreach (var contact in spOptions.Contacts)
            {
                ed.Contacts.Add(contact);
            }

            var spsso = new ExtendedServiceProviderSingleSignOnDescriptor()
            {
                WantAssertionsSigned         = spOptions.WantAssertionsSigned,
                AuthenticationRequestsSigned = spOptions.AuthenticateRequestSigningBehavior == SigningBehavior.Always
            };

            spsso.ProtocolsSupported.Add(new Uri("urn:oasis:names:tc:SAML:2.0:protocol"));

            spsso.AssertionConsumerServices.Add(0, new IndexedProtocolEndpoint()
            {
                Index     = 0,
                IsDefault = true,
                Binding   = Saml2Binding.HttpPostUri,
                Location  = urls.AssertionConsumerServiceUrl
            });

            spsso.AssertionConsumerServices.Add(1, new IndexedProtocolEndpoint()
            {
                Index     = 1,
                IsDefault = false,
                Binding   = Saml2Binding.HttpArtifactUri,
                Location  = urls.AssertionConsumerServiceUrl
            });

            foreach (var attributeService in spOptions.AttributeConsumingServices)
            {
                spsso.AttributeConsumingServices.Add(attributeService);
            }

            if (spOptions.ServiceCertificates != null)
            {
                var publishCertificates = spOptions.MetadataCertificates;
                foreach (var serviceCert in publishCertificates)
                {
                    using (var securityToken = new X509SecurityToken(serviceCert.Certificate))
                    {
                        spsso.Keys.Add(
                            new KeyDescriptor
                        {
                            Use     = (KeyType)(byte)serviceCert.Use,
                            KeyInfo = new SecurityKeyIdentifier(securityToken.CreateKeyIdentifierClause <X509RawDataKeyIdentifierClause>())
                        }
                            );
                    }
                }
            }

            if (spOptions.SigningServiceCertificate != null)
            {
                spsso.SingleLogoutServices.Add(new ProtocolEndpoint(
                                                   Saml2Binding.HttpRedirectUri, urls.LogoutUrl));
                spsso.SingleLogoutServices.Add(new ProtocolEndpoint(
                                                   Saml2Binding.HttpPostUri, urls.LogoutUrl));
            }

            if (spOptions.DiscoveryServiceUrl != null &&
                !string.IsNullOrEmpty(spOptions.DiscoveryServiceUrl.OriginalString))
            {
                spsso.Extensions.DiscoveryResponse = new IndexedProtocolEndpoint
                {
                    Binding   = Saml2Binding.DiscoveryResponseUri,
                    Index     = 0,
                    IsDefault = true,
                    Location  = urls.SignInUrl
                };
            }

            ed.RoleDescriptors.Add(spsso);

            return(ed);
        }
Пример #14
0
        public void SPOptions_MinIncomingSigningAlgorithm_DefaultValue()
        {
            var subject = new SPOptions();

            subject.MinIncomingSigningAlgorithm.Should().Be(SecurityAlgorithms.RsaSha256Signature);
        }
Пример #15
0
        public void SPOptions_DecryptionCertificate_EmptyWhenNoneAdded()
        {
            var subject = new SPOptions();

            subject.DecryptionServiceCertificates.Count.Should().Be(0);
        }
Пример #16
0
        public void SPOptions_SigningCertificate_NullWhenEmpty()
        {
            var subject = new SPOptions();

            subject.SigningServiceCertificate.Should().Be(null);
        }
Пример #17
0
        public void SPOptions_MetadataCacheDuration_DefaultValue()
        {
            var subject = new SPOptions();

            subject.MetadataCacheDuration.Should().Be(new TimeSpan(1, 0, 0));
        }