Esempio n. 1
0
        public void IdentityProvider_CreateAuthenticateRequest_BasicInfo()
        {
            var options = Options.FromConfiguration;

            var idp = options.IdentityProviders.Default;

            var urls    = StubFactory.CreateSaml2Urls();
            var subject = idp.CreateAuthenticateRequest(urls);

            var expected = new Saml2AuthenticationRequest()
            {
                AssertionConsumerServiceUrl = urls.AssertionConsumerServiceUrl,
                DestinationUrl = idp.SingleSignOnServiceUrl,
                Issuer         = options.SPOptions.EntityId,
                AttributeConsumingServiceIndex = 0,
                NameIdPolicy          = new Saml2NameIdPolicy(true, NameIdFormat.EntityIdentifier),
                RequestedAuthnContext = new Saml2RequestedAuthnContext(
                    new Uri("urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"),
                    AuthnContextComparisonType.Minimum)
            };

            subject.Should().BeEquivalentTo(expected, opt => opt
                                            .Excluding(au => au.Id)
                                            .Excluding(au => au.SigningAlgorithm)
                                            .Excluding(au => au.RelayState));

            subject.RelayState.Should().HaveLength(24);
        }
Esempio n. 2
0
        public void SPOptionsExtensions_CreateMetadata_WithServiceCertificateConfigured()
        {
            var options = StubFactory.CreateOptions();

            options.SPOptions.ServiceCertificates.Add(new ServiceCertificate {
                Certificate = SignedXmlHelper.TestCert2
            });
            var metadata = options.SPOptions.CreateMetadata(StubFactory.CreateSaml2Urls());

            var spMetadata = metadata.RoleDescriptors.OfType <SpSsoDescriptor>().Single();

            spMetadata.Should().NotBeNull();
            spMetadata.Keys.Count.Should().Be(1);
            spMetadata.Keys.Single().Use.Should().Be(KeyType.Unspecified);

            // When there is a service certificate, expose SLO endpoints.
            var sloRedirect = spMetadata.SingleLogoutServices.Single(
                slo => slo.Binding == Saml2Binding.HttpRedirectUri);

            sloRedirect.Location.Should().Be("http://localhost/Saml2/Logout");
            sloRedirect.ResponseLocation.Should().BeNull();
            var sloPost = spMetadata.SingleLogoutServices.Single(
                slo => slo.Binding == Saml2Binding.HttpPostUri);

            sloPost.Location.Should().Be("http://localhost/Saml2/Logout");
            sloPost.ResponseLocation.Should().BeNull();
        }
Esempio n. 3
0
        public void IdentityProvider_MetadataLoadedConfiguredFromCode()
        {
            var spOptions = StubFactory.CreateSPOptions();

            spOptions.ServiceCertificates.Add(new ServiceCertificate()
            {
                Certificate = SignedXmlHelper.TestCert
            });

            var subject = new IdentityProvider(
                new EntityId("http://other.entityid.example.com"), spOptions)
            {
                MetadataLocation = "http://localhost:13428/idpMetadataOtherEntityId",
                AllowUnsolicitedAuthnResponse = true
            };

            subject.AllowUnsolicitedAuthnResponse.Should().BeTrue();
            subject.Binding.Should().Be(Saml2BindingType.HttpRedirect);
            subject.EntityId.Id.Should().Be("http://other.entityid.example.com");
            // If a metadatalocation is set, metadata loading is automatically enabled.
            subject.LoadMetadata.Should().BeTrue();
            subject.MetadataLocation.Should().Be("http://localhost:13428/idpMetadataOtherEntityId");
            subject.MetadataValidUntil.Should().BeCloseTo(
                DateTime.UtcNow.Add(MetadataRefreshScheduler.DefaultMetadataCacheDuration.ToTimeSpan()), precision: 100);
            subject.SingleSignOnServiceUrl.Should().Be("http://wrong.entityid.example.com/acs");
            subject.WantAuthnRequestsSigned.Should().Be(true, "WantAuthnRequestsSigned should have been loaded from metadata");

            Action a = () => subject.CreateAuthenticateRequest(StubFactory.CreateSaml2Urls());

            a.Should().NotThrow();
        }
Esempio n. 4
0
        public void SPOptionsExtensions_CreateMetadata_IncludesContactPersons()
        {
            var spOptions = StubFactory.CreateSPOptions();

            var subject = spOptions.CreateMetadata(StubFactory.CreateSaml2Urls()).Contacts;

            subject.Should().Contain(spOptions.Contacts);
        }
Esempio n. 5
0
        public void SPOptionsExtensions_CreateMetadata_IncludesOrganization()
        {
            var subject = StubFactory
                          .CreateSPOptions()
                          .CreateMetadata(StubFactory.CreateSaml2Urls())
                          .Organization;

            subject.Should().NotBeNull();
            subject.Names.First().Name.Should().Be("Sustainsys.Saml2");
        }
Esempio n. 6
0
        public void IdentityProvider_CreateAuthenticateRequest_IncludesSigningCertificate_IfIdpWants()
        {
            var options   = Options.FromConfiguration;
            var spOptions = options.SPOptions;

            var subject = options.IdentityProviders[new EntityId("https://idp2.example.com")];
            var urls    = StubFactory.CreateSaml2Urls();

            var actual = subject.CreateAuthenticateRequest(urls).SigningCertificate;

            (actual?.Thumbprint).Should().Be(SignedXmlHelper.TestCert2.Thumbprint);
        }
Esempio n. 7
0
        public void IdentityProvider_CreateAuthenticateRequest_ThrowsOnMissingSigningCertificate()
        {
            var options   = StubFactory.CreateOptions();
            var spOptions = options.SPOptions;

            spOptions.AuthenticateRequestSigningBehavior = SigningBehavior.Always;

            var idp  = options.IdentityProviders.Default;
            var urls = StubFactory.CreateSaml2Urls();

            idp.Invoking(i => i.CreateAuthenticateRequest(urls))
            .Should().Throw <ConfigurationErrorsException>()
            .WithMessage($"Idp \"https://idp.example.com\" is configured for signed AuthenticateRequests*");
        }
Esempio n. 8
0
        public void IdentityProvider_CreateAuthenticateRequest_DestinationInXml()
        {
            string idpUri = "https://idp.example.com:443/";

            var subject = new IdentityProvider(
                new EntityId(idpUri),
                Options.FromConfiguration.SPOptions)
            {
                SingleSignOnServiceUrl = new Uri(idpUri)
            };

            var r = subject.CreateAuthenticateRequest(StubFactory.CreateSaml2Urls());

            r.ToXElement().Attribute("Destination").Should().NotBeNull()
            .And.Subject.Value.Should().Be(idpUri);
        }
Esempio n. 9
0
        public void IdentityProvider_CreateAuthenticateRequest_DestinationInXml()
        {
            // %41 is A, which doesn't need to be encoded. Ensure it is kept in original format.
            string idpUri = "http://idp.example.com/x=%41";

            var subject = new IdentityProvider(
                new EntityId(idpUri),
                Options.FromConfiguration.SPOptions)
            {
                SingleSignOnServiceUrl = new Uri(idpUri)
            };

            var r = subject.CreateAuthenticateRequest(StubFactory.CreateSaml2Urls());

            r.ToXElement().Attribute("Destination").Should().NotBeNull()
            .And.Subject.Value.Should().Be(idpUri);
        }
Esempio n. 10
0
        public void IdentityProvider_CreateAuthenticateRequest_IncludesSigningCertificate_ForConfigAlways()
        {
            var options   = StubFactory.CreateOptions();
            var spOptions = options.SPOptions;

            spOptions.AuthenticateRequestSigningBehavior = SigningBehavior.Always;
            spOptions.ServiceCertificates.Add(new ServiceCertificate
            {
                Certificate = SignedXmlHelper.TestCert
            });

            var idp  = options.IdentityProviders.Default;
            var urls = StubFactory.CreateSaml2Urls();

            var subject = idp.CreateAuthenticateRequest(urls);

            subject.SigningCertificate.Thumbprint.Should().Be(SignedXmlHelper.TestCert.Thumbprint);
        }
Esempio n. 11
0
        public void SPOptionsExtensions_CreateMetadata_WithServiceCertificateConfiguredAndPostLogoutEnabled()
        {
            var options = StubFactory.CreateOptions();

            options.SPOptions.ServiceCertificates.Add(new ServiceCertificate {
                Certificate = SignedXmlHelper.TestCert2
            });
            options.SPOptions.Compatibility.EnableLogoutOverPost = true;

            var metadata   = options.SPOptions.CreateMetadata(StubFactory.CreateSaml2Urls());
            var spMetadata = metadata.RoleDescriptors.OfType <SpSsoDescriptor>().Single();

            var sloPost = spMetadata.SingleLogoutServices.Single(
                slo => slo.Binding == Saml2Binding.HttpPostUri);

            sloPost.Location.Should().Be("http://localhost/Saml2/Logout");
            sloPost.ResponseLocation.Should().BeNull();
        }
Esempio n. 12
0
        public void SPOptionsExtensions_CreateMetadata_MultipleServiceCertificate()
        {
            var options = StubFactory.CreateOptions();

            options.SPOptions.ServiceCertificates.Add(new ServiceCertificate {
                Certificate = SignedXmlHelper.TestCert2, Use = CertificateUse.Encryption
            });
            options.SPOptions.ServiceCertificates.Add(new ServiceCertificate {
                Certificate = SignedXmlHelper.TestCert2, Use = CertificateUse.Signing
            });
            var metadata = options.SPOptions.CreateMetadata(StubFactory.CreateSaml2Urls());

            var spMetadata = metadata.RoleDescriptors.OfType <SpSsoDescriptor>().Single();

            spMetadata.Should().NotBeNull();
            spMetadata.Keys.Count.Should().Be(2);
            spMetadata.Keys.Where(k => k.Use == KeyType.Encryption).Count().Should().Be(1);
            spMetadata.Keys.Where(k => k.Use == KeyType.Signing).Count().Should().Be(1);
        }
        public void SPOptionsExtensions_CreateMetadata_IncludeAttributeConsumingService()
        {
            var spOptions = StubFactory.CreateSPOptions();
            var urls      = StubFactory.CreateSaml2Urls();

            var attributeConsumingService = new AttributeConsumingService("Name");

            spOptions.AttributeConsumingServices.Clear();
            spOptions.AttributeConsumingServices.Add(attributeConsumingService);
            attributeConsumingService.RequestedAttributes.Add(new RequestedAttribute("AttributeName"));

            var subject = spOptions
                          .CreateMetadata(urls)
                          .RoleDescriptors
                          .Cast <ExtendedServiceProviderSingleSignOnDescriptor>()
                          .First();

            subject.AttributeConsumingServices.First().Should().BeSameAs(attributeConsumingService);
        }
Esempio n. 14
0
        public void SPOptionsExtensions_CreateMetadata_IncludeDiscoveryServiceResponse()
        {
            var spOptions = StubFactory.CreateSPOptions();
            var urls      = StubFactory.CreateSaml2Urls();

            spOptions.DiscoveryServiceUrl = new Uri("http://ds.example.com");

            var subject = spOptions.CreateMetadata(urls).RoleDescriptors
                          .Single().As <SpSsoDescriptor>()
                          .DiscoveryResponses.Values.Single();

            var expected = new DiscoveryResponse
            {
                Binding   = Saml2Binding.DiscoveryResponseUri,
                Index     = 0,
                IsDefault = true,
                Location  = urls.SignInUrl
            };

            subject.Should().BeEquivalentTo(expected);
        }
Esempio n. 15
0
        public void IdentityProvider_CreateAuthenticateRequest_SigningBehaviorNever_OverridesIdpWantsRequestsSigned()
        {
            var options   = StubFactory.CreateOptions();
            var spOptions = options.SPOptions;

            spOptions.AuthenticateRequestSigningBehavior = SigningBehavior.Never;
            spOptions.ServiceCertificates.Add(new ServiceCertificate
            {
                Certificate = SignedXmlHelper.TestCert
            });

            var subject = new IdentityProvider(new EntityId("http://idp.example.com"), spOptions)
            {
                WantAuthnRequestsSigned = true
            };
            var urls = StubFactory.CreateSaml2Urls();

            var actual = subject.CreateAuthenticateRequest(urls).SigningCertificate;

            actual.Should().BeNull();
        }
Esempio n. 16
0
        public void SPOptionsExtensions_CreateMetadata_IncludeAttributeConsumingService()
        {
            var spOptions = StubFactory.CreateSPOptions();
            var urls      = StubFactory.CreateSaml2Urls();

            var attributeConsumingService = new AttributeConsumingService();

            attributeConsumingService.ServiceNames.Add(
                new LocalizedName("Name", "en"));

            spOptions.AttributeConsumingServices.Clear();
            spOptions.AttributeConsumingServices.Add(attributeConsumingService);
            attributeConsumingService.RequestedAttributes.Add(new RequestedAttribute("AttributeName"));

            var subject = spOptions
                          .CreateMetadata(urls)
                          .RoleDescriptors
                          .Cast <SpSsoDescriptor>()
                          .First();

            subject.AttributeConsumingServices.Values.First().Should().BeSameAs(attributeConsumingService);
        }
Esempio n. 17
0
        public void IdentityProvider_CreateAuthenticateRequest_NoAttributeIndex()
        {
            var options = StubFactory.CreateOptions();
            var idp     = options.IdentityProviders.Default;
            var urls    = StubFactory.CreateSaml2Urls();

            options.SPOptions.AttributeConsumingServices.Clear();

            var subject = idp.CreateAuthenticateRequest(urls);

            var expected = new Saml2AuthenticationRequest()
            {
                AssertionConsumerServiceUrl = urls.AssertionConsumerServiceUrl,
                DestinationUrl = idp.SingleSignOnServiceUrl,
                Issuer         = options.SPOptions.EntityId,
                AttributeConsumingServiceIndex = null
            };

            subject.Should().BeEquivalentTo(expected, opt => opt
                                            .Excluding(au => au.Id)
                                            .Excluding(au => au.SigningAlgorithm)
                                            .Excluding(au => au.RelayState));
        }
Esempio n. 18
0
        public void SPOPtionsExtensions_CreateMetadata_RequiredFields()
        {
            var metadata = StubFactory.CreateSPOptions().CreateMetadata(StubFactory.CreateSaml2Urls());

            metadata.CacheDuration.Should().Be(new XsdDuration(seconds: 42));
            metadata.EntityId.Id.Should().Be("https://github.com/Sustainsys/Saml2");

            var spMetadata = metadata.RoleDescriptors.OfType <SpSsoDescriptor>().Single();

            spMetadata.Should().NotBeNull();
            spMetadata.Keys.Count.Should().Be(0);

            var acs = spMetadata.AssertionConsumerServices.First().Value;

            acs.Index.Should().Be(0);
            acs.IsDefault.Should().HaveValue();
            acs.Binding.ToString().Should().Be("urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST");
            acs.Location.ToString().Should().Be("http://localhost/Saml2/Acs");

            // No service certificate configured, so no SLO endpoint should be
            // exposed in metadata.
            spMetadata.SingleLogoutServices.Should().BeEmpty();
        }