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(null, ""))); 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 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(); }
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); }
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); } }
public void MetadatabaseExtensions_ToXmlString_ShouldUseSuppliedEntityDescriptorId() { var metadata = new ExtendedEntityDescriptor { EntityId = new EntityId("http://idp.example.com/metadata"), CacheDuration = new TimeSpan(1, 0, 0), EntityDescriptorId = Guid.NewGuid().ToString() }; 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(null))); var ds = XNamespace.Get(SignedXml.XmlDsigNamespaceUrl); subject.Element(Saml2Namespaces.Saml2Metadata + "EntityDescriptor").Attribute("ID") .Value.Should().BeEquivalentTo(metadata.EntityDescriptorId); }
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()); }
private ExtendedEntityDescriptor CreateIdpMetadata(IOwinRequest request, bool includeCacheDuration = true) { var metadata = new ExtendedEntityDescriptor { EntityId = new EntityId(GetAbsoluteUri(request, MetadataPath).AbsoluteUri) }; if (includeCacheDuration) { metadata.CacheDuration = new TimeSpan(0, 15, 0); metadata.ValidUntil = DateTime.UtcNow.AddDays(1); } 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 = GetAbsoluteUri(request, AuthorizePath) }); idpSsoDescriptor.ArtifactResolutionServices.Add(0, new IndexedProtocolEndpoint { Index = 0, IsDefault = true, Binding = Saml2Binding.SoapUri, Location = GetAbsoluteUri(request, ArtifactPath) }); idpSsoDescriptor.SingleLogoutServices.Add(new ProtocolEndpoint { Binding = Saml2Binding.HttpRedirectUri, Location = GetAbsoluteUri(request, LogoutPath) }); idpSsoDescriptor.SingleLogoutServices.Add(new ProtocolEndpoint { Binding = Saml2Binding.HttpPostUri, Location = GetAbsoluteUri(request, LogoutPath) }); var key = new KeyDescriptor( new SecurityKeyIdentifier( new X509SecurityToken(Options.SigningCertificate) .CreateKeyIdentifierClause <X509RawDataKeyIdentifierClause>())); idpSsoDescriptor.Keys.Add(key); return(metadata); }
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()); }
/// <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(nameof(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(); } }
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(); }
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()); }
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); }