public void MetadatabaseExtensions_ToXmlString_IncludesKeyInfo() { var metadata = new ExtendedEntityDescriptor { EntityId = new EntityId("http://idp.example.com/metadata"), CacheDuration = new TimeSpan(1, 0, 0) }; var idpSsoDescriptor = new IdentityProviderSingleSignOnDescriptor(); idpSsoDescriptor.ProtocolsSupported.Add(new Uri("urn:oasis:names:tc:SAML:2.0:protocol")); metadata.RoleDescriptors.Add(idpSsoDescriptor); idpSsoDescriptor.SingleSignOnServices.Add(new ProtocolEndpoint { Binding = Saml2Binding.HttpRedirectUri, Location = new Uri("http://idp.example.com/sso") }); idpSsoDescriptor.Keys.Add(SignedXmlHelper.TestKeyDescriptor); var subject = XDocument.Parse((metadata.ToXmlString())); var ds = XNamespace.Get(SignedXml.XmlDsigNamespaceUrl); subject.Element(Saml2Namespaces.Saml2Metadata + "EntityDescriptor") .Element(Saml2Namespaces.Saml2Metadata + "IDPSSODescriptor") .Element(Saml2Namespaces.Saml2Metadata + "KeyDescriptor") .Element(ds + "KeyInfo") .Element(ds + "X509Data") .Element(ds + "X509Certificate") .Value.Should().StartWith("MIIDIzCCAg+gAwIBAgIQg7mOjTf994NAVxZu4jqXpzAJBgUrDgM"); }
public static ExtendedEntityDescriptor CreateIdpMetadata(bool includeCacheDuration = true) { var metadata = new ExtendedEntityDescriptor() { EntityId = new EntityId(UrlResolver.MetadataUrl.ToString()) }; if (includeCacheDuration) { metadata.CacheDuration = new TimeSpan(0, 15, 0); } var idpSsoDescriptor = new IdentityProviderSingleSignOnDescriptor(); idpSsoDescriptor.ProtocolsSupported.Add(new Uri("urn:oasis:names:tc:SAML:2.0:protocol")); metadata.RoleDescriptors.Add(idpSsoDescriptor); idpSsoDescriptor.SingleSignOnServices.Add(new ProtocolEndpoint() { Binding = Saml2Binding.HttpRedirectUri, Location = UrlResolver.SsoServiceUrl }); idpSsoDescriptor.ArtifactResolutionServices.Add(0, new IndexedProtocolEndpoint() { Index = 0, IsDefault = true, Binding = Saml2Binding.SoapUri, Location = UrlResolver.ArtifactServiceUrl }); idpSsoDescriptor.Keys.Add(CertificateHelper.SigningKey); return metadata; }
public static ExtendedEntityDescriptor CreateMetadata(this ISPOptions spOptions, AuthServicesUrls urls) { var ed = new ExtendedEntityDescriptor { EntityId = spOptions.EntityId, Organization = spOptions.Organization, CacheDuration = spOptions.MetadataCacheDuration }; foreach (var contact in spOptions.Contacts) { ed.Contacts.Add(contact); } var spsso = new ExtendedServiceProviderSingleSignOnDescriptor(); 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 }); foreach (var attributeService in spOptions.AttributeConsumingServices) { spsso.AttributeConsumingServices.Add(attributeService); } ed.RoleDescriptors.Add(spsso); if (spOptions.DiscoveryServiceUrl != null && !string.IsNullOrEmpty(spOptions.DiscoveryServiceUrl.OriginalString)) { ed.Extensions.DiscoveryResponse = new IndexedProtocolEndpoint { Binding = Saml2Binding.DiscoveryResponseUri, Index = 0, IsDefault = true, Location = urls.SignInUrl }; } return(ed); }
public static ExtendedEntityDescriptor CreateMetadata(this ISPOptions spOptions, AuthServicesUrls urls) { var ed = new ExtendedEntityDescriptor { EntityId = spOptions.EntityId, Organization = spOptions.Organization, CacheDuration = spOptions.MetadataCacheDuration }; foreach (var contact in spOptions.Contacts) { ed.Contacts.Add(contact); } var spsso = new ExtendedServiceProviderSingleSignOnDescriptor(); 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 }); foreach(var attributeService in spOptions.AttributeConsumingServices) { spsso.AttributeConsumingServices.Add(attributeService); } ed.RoleDescriptors.Add(spsso); if(spOptions.DiscoveryServiceUrl != null && !string.IsNullOrEmpty(spOptions.DiscoveryServiceUrl.OriginalString)) { ed.Extensions.DiscoveryResponse = new IndexedProtocolEndpoint { Binding = Saml2Binding.DiscoveryResponseUri, Index = 0, IsDefault = true, Location = urls.SignInUrl }; } return ed; }
public static ExtendedEntityDescriptor CreateMetadata(this ISPOptions spOptions, AuthServicesUrls urls) { var ed = new ExtendedEntityDescriptor { EntityId = spOptions.EntityId, Organization = spOptions.Organization, CacheDuration = spOptions.MetadataCacheDuration }; foreach (var contact in spOptions.Contacts) { ed.Contacts.Add(contact); } var spsso = new ExtendedServiceProviderSingleSignOnDescriptor(); 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.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); }
public void IdentityProvider_ConstructedFromEntityDescriptor_DoesntScheduleMedataRefresh() { MetadataRefreshScheduler.minInterval = new TimeSpan(0, 0, 0, 0, 1); var ed = new ExtendedEntityDescriptor { ValidUntil = DateTime.UtcNow.AddYears(-1), EntityId = new EntityId("http://localhost:13428/idpMetadata") }; var idpSsoDescriptor = new IdentityProviderSingleSignOnDescriptor(); idpSsoDescriptor.ProtocolsSupported.Add(new Uri("urn:oasis:names:tc:SAML:2.0:protocol")); ed.RoleDescriptors.Add(idpSsoDescriptor); var pe = new ProtocolEndpoint() { Binding = Saml2Binding.HttpRedirectUri, Location = new Uri("http://idp.example.com/sso") }; idpSsoDescriptor.SingleSignOnServices.Add(pe); idpSsoDescriptor.Keys.Add(SignedXmlHelper.TestKeyDescriptor); var subject = new IdentityProvider(ed.EntityId, StubFactory.CreateSPOptions()); subject.ReadMetadata(ed); // Ugly, but have to wait and see that nothing happened. Have tried // some different timeouts but need 100 to ensure fail before bug // is fixed :-( Thread.Sleep(100); // Would be changed if metadata was reloaded. subject.SingleSignOnServiceUrl.Should().Be(pe.Location); }
public void IdentityProvider_ConstructedFromEntityDescriptor_DoesntReloadMetadataWhenDisabled() { var ed = new ExtendedEntityDescriptor { ValidUntil = DateTime.UtcNow.AddYears(-1), EntityId = new EntityId("someEntityId") }; var idpSsoDescriptor = new IdentityProviderSingleSignOnDescriptor(); idpSsoDescriptor.ProtocolsSupported.Add(new Uri("urn:oasis:names:tc:SAML:2.0:protocol")); ed.RoleDescriptors.Add(idpSsoDescriptor); idpSsoDescriptor.SingleSignOnServices.Add(new ProtocolEndpoint() { Binding = Saml2Binding.HttpRedirectUri, Location = new Uri("http://idp.example.com/sso") }); idpSsoDescriptor.Keys.Add(SignedXmlHelper.TestKeyDescriptor); var subject = new IdentityProvider(ed.EntityId, StubFactory.CreateSPOptions()); Action a = () => { var b = subject.Binding; }; subject.LoadMetadata.Should().BeFalse(); // Will throw invalid Uri if it tries to use EntityId as metadata url. a.ShouldNotThrow(); }
private void ReadMetadataIdpDescriptor(ExtendedEntityDescriptor metadata) { var idpDescriptor = metadata.RoleDescriptors .OfType<IdentityProviderSingleSignOnDescriptor>().Single(); // Prefer an endpoint with a redirect binding, then check for POST which // is the other supported by AuthServices. var ssoService = idpDescriptor.SingleSignOnServices .FirstOrDefault(s => s.Binding == Saml2Binding.HttpRedirectUri) ?? idpDescriptor.SingleSignOnServices .First(s => s.Binding == Saml2Binding.HttpPostUri); binding = Saml2Binding.UriToSaml2BindingType(ssoService.Binding); singleSignOnServiceUrl = ssoService.Location; var key = idpDescriptor.Keys .Where(k => k.Use == KeyType.Unspecified || k.Use == KeyType.Signing) .SingleOrDefault(); if (key != null) { signingKey = ((AsymmetricSecurityKey)key.KeyInfo.CreateKey()) .GetAsymmetricAlgorithm(SignedXml.XmlDsigRSASHA1Url, false); } }
/// <summary> /// Reads the supplied metadata and sets all properties of the /// IdentityProvider based on the metadata. /// </summary> /// <param name="metadata">Metadata to read.</param> public void ReadMetadata(ExtendedEntityDescriptor metadata) { if (metadata == null) { throw new ArgumentNullException("metadata"); } lock (metadataLoadLock) { if (metadata.EntityId.Id != EntityId.Id) { var msg = string.Format(CultureInfo.InvariantCulture, "Unexpected entity id \"{0}\" found when loading metadata for \"{1}\".", metadata.EntityId.Id, EntityId.Id); throw new ConfigurationErrorsException(msg); } ReadMetadataIdpDescriptor(metadata); MetadataValidUntil = metadata.CalculateMetadataValidUntil(); } }
private void ReadMetadataIdpDescriptor(ExtendedEntityDescriptor metadata) { var idpDescriptor = metadata.RoleDescriptors .OfType<IdentityProviderSingleSignOnDescriptor>().Single(); WantAuthnRequestsSigned = idpDescriptor.WantAuthenticationRequestsSigned; var ssoService = GetPreferredEndpoint(idpDescriptor.SingleSignOnServices); if (ssoService != null) { binding = Saml2Binding.UriToSaml2BindingType(ssoService.Binding); singleSignOnServiceUrl = ssoService.Location; } var sloService = GetPreferredEndpoint(idpDescriptor.SingleLogoutServices); if (sloService != null) { SingleLogoutServiceUrl = sloService.Location; SingleLogoutServiceBinding = Saml2Binding.UriToSaml2BindingType(sloService.Binding); singleLogoutServiceResponseUrl = sloService.ResponseLocation; } foreach (var ars in idpDescriptor.ArtifactResolutionServices) { artifactResolutionServiceUrls[ars.Value.Index] = ars.Value.Location; } foreach (var ars in artifactResolutionServiceUrls.Keys .Where(k => !idpDescriptor.ArtifactResolutionServices.Keys.Contains(k))) { artifactResolutionServiceUrls.Remove(ars); } var keys = idpDescriptor.Keys.Where(k => k.Use == KeyType.Unspecified || k.Use == KeyType.Signing); signingKeys.SetLoadedItems(keys.Select(k => k.KeyInfo.First(c => c.CanCreateKey)).ToList()); }
private void ReadMetadataIdpDescriptor(ExtendedEntityDescriptor metadata) { var idpDescriptor = metadata.RoleDescriptors .OfType<IdentityProviderSingleSignOnDescriptor>().Single(); // Prefer an endpoint with a redirect binding, then check for POST which // is the other supported by AuthServices. var ssoService = idpDescriptor.SingleSignOnServices .FirstOrDefault(s => s.Binding == Saml2Binding.HttpRedirectUri) ?? idpDescriptor.SingleSignOnServices .FirstOrDefault(s => s.Binding == Saml2Binding.HttpPostUri); if (ssoService != null) { binding = Saml2Binding.UriToSaml2BindingType(ssoService.Binding); singleSignOnServiceUrl = ssoService.Location; } foreach(var ars in idpDescriptor.ArtifactResolutionServices) { artifactResolutionServiceUrls[ars.Value.Index] = ars.Value.Location; } foreach (var ars in artifactResolutionServiceUrls.Keys .Where(k => !idpDescriptor.ArtifactResolutionServices.Keys.Contains(k))) { artifactResolutionServiceUrls.Remove(ars); } var keys = idpDescriptor.Keys.Where(k => k.Use == KeyType.Unspecified || k.Use == KeyType.Signing); signingKeys.SetLoadedItems(keys.Select(k => ((AsymmetricSecurityKey)k.KeyInfo.CreateKey()) .GetAsymmetricAlgorithm(SignedXml.XmlDsigRSASHA1Url, false)).ToList()); }
public static ExtendedEntityDescriptor CreateMetadata(this ISPOptions spOptions, AuthServicesUrls urls, string entityIdSuffix) { var eid = string.IsNullOrEmpty(entityIdSuffix) ? spOptions.EntityId : new EntityId(spOptions.EntityId.Id + entityIdSuffix); var ed = new ExtendedEntityDescriptor { EntityId = eid, 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; }
public void ExtendedMetadataSerializer_Write_EntitiesDescriptorCacheDuration() { var metadata = new ExtendedEntitiesDescriptor { Name = "Federation Name", CacheDuration = new TimeSpan(0, 42, 0) }; var entity = new ExtendedEntityDescriptor { EntityId = new EntityId("http://some.entity.example.com") }; var idpSsoDescriptor = new IdentityProviderSingleSignOnDescriptor(); idpSsoDescriptor.ProtocolsSupported.Add(new Uri("urn:oasis:names:tc:SAML:2.0:protocol")); idpSsoDescriptor.SingleSignOnServices.Add(new ProtocolEndpoint { Binding = Saml2Binding.HttpRedirectUri, Location = new Uri("http://some.entity.example.com/sso") }); entity.RoleDescriptors.Add(idpSsoDescriptor); metadata.ChildEntities.Add(entity); var stream = new MemoryStream(); ExtendedMetadataSerializer.ReaderInstance.WriteMetadata(stream, metadata); stream.Seek(0, SeekOrigin.Begin); var result = XDocument.Load(stream).Root; result.Name.Should().Be(Saml2Namespaces.Saml2Metadata + "EntitiesDescriptor"); result.Attribute("cacheDuration").Value.Should().Be("PT42M"); result.Element(Saml2Namespaces.Saml2Metadata + "EntityDescriptor").Attribute("cacheDuration") .Should().BeNull(); }
public static ExtendedEntityDescriptor CreateMetadata(this ISPOptions spOptions, AuthServicesUrls urls) { var ed = new ExtendedEntityDescriptor { EntityId = spOptions.EntityId, Organization = spOptions.Organization, CacheDuration = spOptions.MetadataCacheDuration }; foreach (var contact in spOptions.Contacts) { ed.Contacts.Add(contact); } var spsso = new ExtendedServiceProviderSingleSignOnDescriptor(); 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.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; }
private void ReadMetadataIdpDescriptor(ExtendedEntityDescriptor metadata) { var idpDescriptor = metadata.RoleDescriptors .OfType<IdentityProviderSingleSignOnDescriptor>().Single(); WantAuthnRequestsSigned = idpDescriptor.WantAuthenticationRequestsSigned; // Prefer an endpoint with a redirect binding, then check for POST which // is the other supported by AuthServices. var ssoService = idpDescriptor.SingleSignOnServices .FirstOrDefault(s => s.Binding == Saml2Binding.HttpRedirectUri) ?? idpDescriptor.SingleSignOnServices .FirstOrDefault(s => s.Binding == Saml2Binding.HttpPostUri); if (ssoService != null) { binding = Saml2Binding.UriToSaml2BindingType(ssoService.Binding); singleSignOnServiceUrl = ssoService.Location; } var sloService = idpDescriptor.SingleLogoutServices .Where(slo => slo.Binding == Saml2Binding.HttpRedirectUri || slo.Binding == Saml2Binding.HttpPostUri) .FirstOrDefault(); if (sloService != null) { SingleLogoutServiceUrl = sloService.Location; SingleLogoutServiceBinding = Saml2Binding.UriToSaml2BindingType(sloService.Binding); singleLogoutServiceResponseUrl = sloService.ResponseLocation; } foreach (var ars in idpDescriptor.ArtifactResolutionServices) { artifactResolutionServiceUrls[ars.Value.Index] = ars.Value.Location; } foreach (var ars in artifactResolutionServiceUrls.Keys .Where(k => !idpDescriptor.ArtifactResolutionServices.Keys.Contains(k))) { artifactResolutionServiceUrls.Remove(ars); } var keys = idpDescriptor.Keys.Where(k => k.Use == KeyType.Unspecified || k.Use == KeyType.Signing); signingKeys.SetLoadedItems(keys.Select(k => k.KeyInfo.First(c => c.CanCreateKey)).ToList()); }