/// <summary> /// Creates the necessary key descriptors for the metadata based on the certificate in the IDPConfig class. /// </summary> /// <returns></returns> private static KeyDescriptor[] CreateKeyDescriptors() { List<KeyDescriptor> keys = new List<KeyDescriptor>(); // Pack the certificate. KeyInfo keyinfo = new KeyInfo(); KeyInfoX509Data keyClause = new KeyInfoX509Data(IDPConfig.IDPCertificate, X509IncludeOption.EndCertOnly); keyinfo.AddClause(keyClause); { // Create signing key element. KeyDescriptor key = new KeyDescriptor(); keys.Add(key); key.use = KeyTypes.signing; key.useSpecified = true; key.KeyInfo = Serialization.DeserializeFromXmlString<dk.nita.saml20.Schema.XmlDSig.KeyInfo>(keyinfo.GetXml().OuterXml); } { // Create encryption key element KeyDescriptor key = new KeyDescriptor(); keys.Add(key); key.use = KeyTypes.encryption; key.useSpecified = true; key.KeyInfo = Serialization.DeserializeFromXmlString<dk.nita.saml20.Schema.XmlDSig.KeyInfo>(keyinfo.GetXml().OuterXml); } return keys.ToArray(); }
static SignedXmlHelper() { var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(TestCert)); KeyInfoXml = keyInfo.GetXml().OuterXml; }
private XmlElement CreateEncryptedSymmetricKeyInfo(byte[] key, EncryptingCredentials credentials, XmlDocument document) { var digestMethod = null as string; var clause = null as Legacy.KeyInfoClause; if (credentials.Key is X509SecurityKey x509) { digestMethod = "http://www.w3.org/2000/09/xmldsig#sha1"; var securityTokenReference = document.CreateElement(WsSecurityConstants.WsSecurity10.Prefix, "SecurityTokenReference", WsSecurityConstants.WsSecurity10.Namespace); var keyIdentifier = document.CreateElement(WsSecurityConstants.WsSecurity10.Prefix, "KeyIdentifier", WsSecurityConstants.WsSecurity10.Namespace); keyIdentifier.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1"); keyIdentifier.InnerText = x509.X5t; securityTokenReference.AppendChild(keyIdentifier); using (var rsa = x509.Certificate.GetRSAPublicKey()) clause = EncryptKey(key, rsa, credentials.Alg, new Legacy.KeyInfoNode(securityTokenReference)); } else if (credentials.Key is RsaSecurityKey rsa) { clause = EncryptKey(key, rsa.Rsa, credentials.Alg, CreateKeyInfoClause(rsa)); } else { throw new NotSupportedException($"Encryption key type '{credentials?.Key.GetType()?.Name}' not supported."); } var keyInfo = new Legacy.KeyInfo(); keyInfo.AddClause(clause); var element = keyInfo.GetXml(); if (digestMethod != null) { var encryptionMethods = element .SelectNodes("//*") .OfType <XmlElement>() .Where(e => e.LocalName == "EncryptionMethod") .Where(e => { var algorithm = e.GetAttribute("Algorithm"); return(algorithm == Legacy.EncryptedXml.XmlEncRSAOAEPUrl); }) ; foreach (var encryptionMethod in encryptionMethods) { var digest = element.OwnerDocument.CreateElement("DigestMethod", "http://www.w3.org/2000/09/xmldsig#"); digest.SetAttribute("Algorithm", digestMethod); encryptionMethod.AppendChild(digest); } } return(element); }
private XObject KeyDescriptor(X509Certificate2 certificate, string keyType) { KeyInfo keyinfo = new KeyInfo(); keyinfo.AddClause(new KeyInfoX509Data(certificate, CertificateIncludeOption)); return new XElement(Saml2MetadataConstants.MetadataNamespaceX + Saml2MetadataConstants.Message.KeyDescriptor, new XAttribute(Saml2MetadataConstants.Message.Use, keyType), XElement.Parse(keyinfo.GetXml().OuterXml)); }
public void WriteContentsTo ( AddressingVersion addressingVersion, XmlDictionaryWriter writer) { if (writer == null) throw new ArgumentNullException ("writer"); #if NET_2_1 writer.WriteString (Uri.AbsoluteUri); #else if (addressingVersion == AddressingVersion.None) writer.WriteString (Uri.AbsoluteUri); else { writer.WriteStartElement ("Address", addressingVersion.Namespace); writer.WriteString (Uri.AbsoluteUri); writer.WriteEndElement (); if (Headers != null) foreach (AddressHeader ah in Headers) ah.WriteAddressHeader (writer); if (Identity == null) return; writer.WriteStartElement ("Identity", Constants.WsaIdentityUri); X509CertificateEndpointIdentity x509 = Identity as X509CertificateEndpointIdentity; if (x509 != null) { KeyInfo ki = new KeyInfo (); KeyInfoX509Data x = new KeyInfoX509Data (); foreach (X509Certificate2 cert in x509.Certificates) x.AddCertificate (cert); ki.AddClause (x); ki.GetXml ().WriteTo (writer); } else { DataContractSerializer ds = new DataContractSerializer (Identity.IdentityClaim.GetType ()); ds.WriteObject (writer, Identity.IdentityClaim); } writer.WriteEndElement (); } #endif }
void IXmlSerializable.WriteXml (XmlWriter writer) { if (writer == null) throw new ArgumentNullException ("writer"); writer.WriteStartElement ("Address", Constants.WsaNamespace); writer.WriteString (address.Uri.AbsoluteUri); writer.WriteEndElement (); if (address.Identity == null) return; if (address.Headers != null) foreach (AddressHeader ah in address.Headers) ah.WriteAddressHeader (writer); writer.WriteStartElement ("Identity", Constants.WsaIdentityUri); #if !NET_2_1 X509CertificateEndpointIdentity x509 = address.Identity as X509CertificateEndpointIdentity; if (x509 != null) { KeyInfo ki = new KeyInfo (); KeyInfoX509Data x = new KeyInfoX509Data (); foreach (X509Certificate2 cert in x509.Certificates) x.AddCertificate (cert); ki.AddClause (x); ki.GetXml ().WriteTo (writer); } else { DataContractSerializer ds = new DataContractSerializer (address.Identity.IdentityClaim.GetType ()); ds.WriteObject (writer, address.Identity.IdentityClaim); } #endif writer.WriteEndElement (); }
/// <summary> /// Takes the configuration class and converts it to a SAML2.0 metadata document. /// </summary> /// <param name="config">The config.</param> /// <param name="keyInfo">The keyInfo.</param> private void ConvertToMetadata(Saml2Section config, KeyInfo keyInfo) { var entity = CreateDefaultEntity(); entity.EntityID = config.ServiceProvider.Id; entity.ValidUntil = DateTime.Now + config.Metadata.Lifetime; var serviceProviderDescriptor = new SpSsoDescriptor { ProtocolSupportEnumeration = new[] { Saml20Constants.Protocol }, AuthnRequestsSigned = XmlConvert.ToString(true), WantAssertionsSigned = XmlConvert.ToString(true) }; if (config.ServiceProvider.NameIdFormats.Count > 0) { serviceProviderDescriptor.NameIdFormat = new string[config.ServiceProvider.NameIdFormats.Count]; var count = 0; foreach (var elem in config.ServiceProvider.NameIdFormats) { serviceProviderDescriptor.NameIdFormat[count++] = elem.Format; } } var baseUrl = new Uri(config.ServiceProvider.Server); var logoutServiceEndpoints = new List<Endpoint>(); var signonServiceEndpoints = new List<IndexedEndpoint>(); var artifactResolutionEndpoints = new List<IndexedEndpoint>(2); // Include endpoints. foreach (var endpoint in config.ServiceProvider.Endpoints) { if (endpoint.Type == EndpointType.SignOn) { var loginEndpoint = new IndexedEndpoint { Index = endpoint.Index, IsDefault = true, Location = new Uri(baseUrl, endpoint.LocalPath).ToString(), Binding = GetBinding(endpoint.Binding, Saml20Constants.ProtocolBindings.HttpPost) }; signonServiceEndpoints.Add(loginEndpoint); var artifactSignonEndpoint = new IndexedEndpoint { Binding = Saml20Constants.ProtocolBindings.HttpSoap, Index = loginEndpoint.Index, Location = loginEndpoint.Location }; artifactResolutionEndpoints.Add(artifactSignonEndpoint); continue; } if (endpoint.Type == EndpointType.Logout) { var logoutEndpoint = new Endpoint { Location = new Uri(baseUrl, endpoint.LocalPath).ToString() }; logoutEndpoint.ResponseLocation = logoutEndpoint.Location; logoutEndpoint.Binding = GetBinding(endpoint.Binding, Saml20Constants.ProtocolBindings.HttpPost); logoutServiceEndpoints.Add(logoutEndpoint); // TODO: Look at this... logoutEndpoint = new Endpoint { Location = new Uri(baseUrl, endpoint.LocalPath).ToString() }; logoutEndpoint.ResponseLocation = logoutEndpoint.Location; logoutEndpoint.Binding = GetBinding(endpoint.Binding, Saml20Constants.ProtocolBindings.HttpRedirect); logoutServiceEndpoints.Add(logoutEndpoint); var artifactLogoutEndpoint = new IndexedEndpoint { Binding = Saml20Constants.ProtocolBindings.HttpSoap, Index = endpoint.Index, Location = logoutEndpoint.Location }; artifactResolutionEndpoints.Add(artifactLogoutEndpoint); continue; } } serviceProviderDescriptor.SingleLogoutService = logoutServiceEndpoints.ToArray(); serviceProviderDescriptor.AssertionConsumerService = signonServiceEndpoints.ToArray(); // Attribute consuming service. if (config.Metadata.RequestedAttributes.Count > 0) { var attConsumingService = new AttributeConsumingService(); serviceProviderDescriptor.AttributeConsumingService = new[] { attConsumingService }; attConsumingService.Index = signonServiceEndpoints[0].Index; attConsumingService.IsDefault = true; attConsumingService.ServiceName = new[] { new LocalizedName("SP", "en") }; attConsumingService.RequestedAttribute = new RequestedAttribute[config.Metadata.RequestedAttributes.Count]; for (var i = 0; i < config.Metadata.RequestedAttributes.Count; i++) { attConsumingService.RequestedAttribute[i] = new RequestedAttribute { Name = config.Metadata.RequestedAttributes[i].Name }; if (config.Metadata.RequestedAttributes[i].IsRequired) { attConsumingService.RequestedAttribute[i].IsRequired = true; } attConsumingService.RequestedAttribute[i].NameFormat = SamlAttribute.NameformatBasic; } } else { serviceProviderDescriptor.AttributeConsumingService = new AttributeConsumingService[0]; } if (config.Metadata == null || !config.Metadata.ExcludeArtifactEndpoints) { serviceProviderDescriptor.ArtifactResolutionService = artifactResolutionEndpoints.ToArray(); } entity.Items = new object[] { serviceProviderDescriptor }; // Keyinfo var keySigning = new KeyDescriptor(); var keyEncryption = new KeyDescriptor(); serviceProviderDescriptor.KeyDescriptor = new[] { keySigning, keyEncryption }; keySigning.Use = KeyTypes.Signing; keySigning.UseSpecified = true; keyEncryption.Use = KeyTypes.Encryption; keyEncryption.UseSpecified = true; // Ugly conversion between the .Net framework classes and our classes ... avert your eyes!! keySigning.KeyInfo = Serialization.DeserializeFromXmlString<Schema.XmlDSig.KeyInfo>(keyInfo.GetXml().OuterXml); keyEncryption.KeyInfo = keySigning.KeyInfo; // apply the <Organization> element if (config.Metadata.Organization.ElementInformation.IsPresent) { entity.Organization = new Organization { OrganizationName = new[] { new LocalizedName { Value = config.Metadata.Organization.Name } }, OrganizationDisplayName = new[] { new LocalizedName { Value = config.Metadata.Organization.DisplayName } }, OrganizationURL = new[] { new LocalizedURI { Value = config.Metadata.Organization.Url } } }; } if (config.Metadata.Contacts != null && config.Metadata.Contacts.Count > 0) { entity.ContactPerson = config.Metadata.Contacts.Select(x => new Contact { ContactType = (Schema.Metadata.ContactType) ((int)x.Type), Company = x.Company, GivenName = x.GivenName, SurName = x.SurName, EmailAddress = new[] { x.Email }, TelephoneNumber = new[] { x.Phone } }).ToArray(); } }
internal XmlElement GetXml(XmlDocument document) { if (CipherData == null) { throw new CryptographicException("Cipher data is not specified."); } XmlElement xel = document.CreateElement(XmlEncryption.ElementNames.EncryptedKey, EncryptedXml.XmlEncNamespaceUrl); if (EncryptionMethod != null) { xel.AppendChild(EncryptionMethod.GetXml(document)); } if (KeyInfo != null) { xel.AppendChild(document.ImportNode(KeyInfo.GetXml(), true)); } if (CipherData != null) { xel.AppendChild(CipherData.GetXml(document)); } if (EncryptionProperties.Count > 0) { XmlElement xep = document.CreateElement(XmlEncryption.ElementNames.EncryptionProperties, EncryptedXml.XmlEncNamespaceUrl); foreach (EncryptionProperty p in EncryptionProperties) { xep.AppendChild(p.GetXml(document)); } xel.AppendChild(xep); } if (ReferenceList.Count > 0) { XmlElement xrl = document.CreateElement(XmlEncryption.ElementNames.ReferenceList, EncryptedXml.XmlEncNamespaceUrl); foreach (EncryptedReference er in ReferenceList) { xrl.AppendChild(er.GetXml(document)); } xel.AppendChild(xrl); } if (CarriedKeyName != null) { XmlElement xck = document.CreateElement(XmlEncryption.ElementNames.CarriedKeyName, EncryptedXml.XmlEncNamespaceUrl); xck.InnerText = CarriedKeyName; xel.AppendChild(xck); } if (Id != null) { xel.SetAttribute(XmlEncryption.AttributeNames.Id, Id); } if (Type != null) { xel.SetAttribute(XmlEncryption.AttributeNames.Type, Type); } if (MimeType != null) { xel.SetAttribute(XmlEncryption.AttributeNames.MimeType, MimeType); } if (Encoding != null) { xel.SetAttribute(XmlEncryption.AttributeNames.Encoding, Encoding); } if (Recipient != null) { xel.SetAttribute(XmlEncryption.AttributeNames.Recipient, Recipient); } return(xel); }
internal XmlElement GetXml(XmlDocument document) { // Create the EncryptedKey element XmlElement encryptedKeyElement = (XmlElement)document.CreateElement("EncryptedKey", EncryptedXml.XmlEncNamespaceUrl); // Deal with attributes if (!string.IsNullOrEmpty(Id)) { encryptedKeyElement.SetAttribute("Id", Id); } if (!string.IsNullOrEmpty(Type)) { encryptedKeyElement.SetAttribute("Type", Type); } if (!string.IsNullOrEmpty(MimeType)) { encryptedKeyElement.SetAttribute("MimeType", MimeType); } if (!string.IsNullOrEmpty(Encoding)) { encryptedKeyElement.SetAttribute("Encoding", Encoding); } if (!string.IsNullOrEmpty(Recipient)) { encryptedKeyElement.SetAttribute("Recipient", Recipient); } // EncryptionMethod if (EncryptionMethod != null) { encryptedKeyElement.AppendChild(EncryptionMethod.GetXml(document)); } // KeyInfo if (KeyInfo.Count > 0) { encryptedKeyElement.AppendChild(KeyInfo.GetXml(document)); } // CipherData if (CipherData == null) { throw new CryptographicException(SR.Cryptography_Xml_MissingCipherData); } encryptedKeyElement.AppendChild(CipherData.GetXml(document)); // EncryptionProperties if (EncryptionProperties.Count > 0) { XmlElement encryptionPropertiesElement = document.CreateElement("EncryptionProperties", EncryptedXml.XmlEncNamespaceUrl); for (int index = 0; index < EncryptionProperties.Count; index++) { EncryptionProperty ep = EncryptionProperties.Item(index); encryptionPropertiesElement.AppendChild(ep.GetXml(document)); } encryptedKeyElement.AppendChild(encryptionPropertiesElement); } // ReferenceList if (ReferenceList.Count > 0) { XmlElement referenceListElement = document.CreateElement("ReferenceList", EncryptedXml.XmlEncNamespaceUrl); for (int index = 0; index < ReferenceList.Count; index++) { referenceListElement.AppendChild(ReferenceList[index].GetXml(document)); } encryptedKeyElement.AppendChild(referenceListElement); } // CarriedKeyName if (CarriedKeyName != null) { XmlElement carriedKeyNameElement = (XmlElement)document.CreateElement("CarriedKeyName", EncryptedXml.XmlEncNamespaceUrl); XmlText carriedKeyNameText = document.CreateTextNode(CarriedKeyName); carriedKeyNameElement.AppendChild(carriedKeyNameText); encryptedKeyElement.AppendChild(carriedKeyNameElement); } return(encryptedKeyElement); }
/// <summary> /// Takes the Safewhere configuration class and converts it to a SAML2.0 metadata document. /// </summary> private void ConvertToMetadata(SAML20FederationConfig config, KeyInfo keyinfo) { EntityDescriptor entity = CreateDefaultEntity(); entity.entityID = config.ServiceProvider.ID; entity.validUntil = DateTime.Now.AddDays(7); SPSSODescriptor spDescriptor = new SPSSODescriptor(); spDescriptor.protocolSupportEnumeration = new string[] { Saml20Constants.PROTOCOL }; spDescriptor.AuthnRequestsSigned = XmlConvert.ToString(true); spDescriptor.WantAssertionsSigned = XmlConvert.ToString(true); if(config.ServiceProvider.NameIdFormats.All) { spDescriptor.NameIDFormat = new string[] {Saml20Constants.NameIdentifierFormats.Email, Saml20Constants.NameIdentifierFormats.Entity, Saml20Constants.NameIdentifierFormats.Kerberos, Saml20Constants.NameIdentifierFormats.Persistent, Saml20Constants.NameIdentifierFormats.Transient, Saml20Constants.NameIdentifierFormats.Unspecified, Saml20Constants.NameIdentifierFormats.Windows, Saml20Constants.NameIdentifierFormats.X509SubjectName}; }else { spDescriptor.NameIDFormat = new string[config.ServiceProvider.NameIdFormats.NameIdFormats.Count]; int count = 0; foreach(NameIdFormatElement elem in config.ServiceProvider.NameIdFormats.NameIdFormats) { spDescriptor.NameIDFormat[count++] = elem.NameIdFormat; } } Uri baseURL = new Uri(config.ServiceProvider.Server); List<Endpoint> logoutServiceEndpoints = new List<Endpoint>(); List<IndexedEndpoint> signonServiceEndpoints = new List<IndexedEndpoint>(); List<IndexedEndpoint> artifactResolutionEndpoints = new List<IndexedEndpoint>(2); // Include endpoints. foreach (Saml20ServiceEndpoint endpoint in config.ServiceProvider.serviceEndpoints) { if (endpoint.endpointType == EndpointType.SIGNON) { IndexedEndpoint loginEndpoint = new IndexedEndpoint(); loginEndpoint.index = endpoint.endPointIndex; loginEndpoint.isDefault = true; loginEndpoint.Location = new Uri(baseURL, endpoint.localPath).ToString(); loginEndpoint.Binding = GetBinding(endpoint.Binding, Saml20Constants.ProtocolBindings.HTTP_Post); signonServiceEndpoints.Add(loginEndpoint); IndexedEndpoint artifactSignonEndpoint = new IndexedEndpoint(); artifactSignonEndpoint.Binding = Saml20Constants.ProtocolBindings.HTTP_SOAP; artifactSignonEndpoint.index = loginEndpoint.index; artifactSignonEndpoint.Location = loginEndpoint.Location; artifactResolutionEndpoints.Add(artifactSignonEndpoint); continue; } if (endpoint.endpointType == EndpointType.LOGOUT) { Endpoint logoutEndpoint = new Endpoint(); logoutEndpoint.Location = new Uri(baseURL, endpoint.localPath).ToString(); logoutEndpoint.ResponseLocation = logoutEndpoint.Location; logoutEndpoint.Binding = GetBinding(endpoint.Binding, Saml20Constants.ProtocolBindings.HTTP_Post); logoutServiceEndpoints.Add(logoutEndpoint); logoutEndpoint = new Endpoint(); logoutEndpoint.Location = new Uri(baseURL, endpoint.localPath).ToString(); logoutEndpoint.ResponseLocation = logoutEndpoint.Location; logoutEndpoint.Binding = GetBinding(endpoint.Binding, Saml20Constants.ProtocolBindings.HTTP_Redirect); logoutServiceEndpoints.Add(logoutEndpoint); IndexedEndpoint artifactLogoutEndpoint = new IndexedEndpoint(); artifactLogoutEndpoint.Binding = Saml20Constants.ProtocolBindings.HTTP_SOAP; artifactLogoutEndpoint.index = endpoint.endPointIndex; artifactLogoutEndpoint.Location = logoutEndpoint.Location; artifactResolutionEndpoints.Add(artifactLogoutEndpoint); continue; } } spDescriptor.SingleLogoutService = logoutServiceEndpoints.ToArray(); spDescriptor.AssertionConsumerService = signonServiceEndpoints.ToArray(); // NameIdFormat if (!string.IsNullOrEmpty(config.NameIdFormat)) { spDescriptor.NameIDFormat = new string[] { config.NameIdFormat }; } // Attribute consuming service. if (config.RequestedAttributes.Attributes.Count > 0) { AttributeConsumingService attConsumingService = new AttributeConsumingService(); spDescriptor.AttributeConsumingService = new AttributeConsumingService[] { attConsumingService }; attConsumingService.index = signonServiceEndpoints[0].index; attConsumingService.isDefault = true; attConsumingService.ServiceName = new LocalizedName[] { new LocalizedName("SP", "da") }; attConsumingService.RequestedAttribute = new RequestedAttribute[config.RequestedAttributes.Attributes.Count]; for (int i = 0; i < config.RequestedAttributes.Attributes.Count; i++) { attConsumingService.RequestedAttribute[i] = new RequestedAttribute(); attConsumingService.RequestedAttribute[i].Name = config.RequestedAttributes.Attributes[i].name; if (config.RequestedAttributes.Attributes[i].IsRequired) attConsumingService.RequestedAttribute[i].isRequired = true; attConsumingService.RequestedAttribute[i].NameFormat = SamlAttribute.NAMEFORMAT_BASIC; } } else { spDescriptor.AttributeConsumingService = new AttributeConsumingService[0]; } if(config.Metadata != null && config.Metadata.IncludeArtifactEndpoints) spDescriptor.ArtifactResolutionService = artifactResolutionEndpoints.ToArray(); entity.Items = new object[] { spDescriptor }; // Keyinfo KeyDescriptor keySigning = new KeyDescriptor(); KeyDescriptor keyEncryption = new KeyDescriptor(); spDescriptor.KeyDescriptor = new KeyDescriptor[] { keySigning, keyEncryption }; keySigning.use = KeyTypes.signing; keySigning.useSpecified = true; keyEncryption.use = KeyTypes.encryption; keyEncryption.useSpecified = true; // Ugly conversion between the .Net framework classes and our classes ... avert your eyes!! keySigning.KeyInfo = Serialization.DeserializeFromXmlString<Schema.XmlDSig.KeyInfo>(keyinfo.GetXml().OuterXml); keyEncryption.KeyInfo = keySigning.KeyInfo; // apply the <Organization> element if (config.ServiceProvider.Organization != null) entity.Organization = config.ServiceProvider.Organization; if (config.ServiceProvider.ContactPerson != null && config.ServiceProvider.ContactPerson.Count > 0) entity.ContactPerson = config.ServiceProvider.ContactPerson.ToArray(); }
/// <summary> /// Takes the configuration class and converts it to a SAML2.0 metadata document. /// </summary> /// <param name="config">The config.</param> /// <param name="keyInfo">The keyInfo.</param> private void ConvertToMetadata(Saml2Configuration config) { var entity = CreateDefaultEntity(); entity.EntityId = config.ServiceProvider.Id; if (config.ServiceProvider.UseValidUntil) { entity.ValidUntil = DateTime.Now.AddDays(7); } var serviceProviderDescriptor = new SpSsoDescriptor { ProtocolSupportEnumeration = new[] { Saml20Constants.Protocol }, AuthnRequestsSigned = XmlConvert.ToString(config.ServiceProvider.AuthNRequestsSigned), WantAssertionsSigned = XmlConvert.ToString(config.ServiceProvider.WantAssertionsSigned) }; if (config.ServiceProvider.NameIdFormats.Count > 0) { serviceProviderDescriptor.NameIdFormat = new string[config.ServiceProvider.NameIdFormats.Count]; var count = 0; foreach (var elem in config.ServiceProvider.NameIdFormats) { serviceProviderDescriptor.NameIdFormat[count++] = elem.Format; } } var baseUrl = new Uri(config.ServiceProvider.Server); var logoutServiceEndpoints = new List <Endpoint>(); var signonServiceEndpoints = new List <IndexedEndpoint>(); var artifactResolutionEndpoints = new List <IndexedEndpoint>(2); // Include endpoints. foreach (var endpoint in config.ServiceProvider.Endpoints) { if (endpoint.Type == EndpointType.SignOn) { var loginEndpoint = new IndexedEndpoint { Index = endpoint.Index, IsDefault = endpoint.Default, Location = new Uri(baseUrl, endpoint.LocalPath).ToString(), Binding = GetBinding(endpoint.Binding, Saml20Constants.ProtocolBindings.HttpPost) }; signonServiceEndpoints.Add(loginEndpoint); if (config.ServiceProvider.IncludeArtifactResolutionEndpoints) { var artifactSignonEndpoint = new IndexedEndpoint { Binding = Saml20Constants.ProtocolBindings.HttpSoap, Index = loginEndpoint.Index, Location = loginEndpoint.Location }; artifactResolutionEndpoints.Add(artifactSignonEndpoint); } continue; } if (endpoint.Type == EndpointType.Logout) { var location = new Uri(baseUrl, endpoint.LocalPath).ToString(); var logoutEndpoint = new Endpoint { Location = location, ResponseLocation = location, Binding = GetBinding(endpoint.Binding, Saml20Constants.ProtocolBindings.HttpPost) }; logoutServiceEndpoints.Add(logoutEndpoint); if (config.ServiceProvider.IncludeArtifactResolutionEndpoints) { var artifactLogoutEndpoint = new IndexedEndpoint { Binding = Saml20Constants.ProtocolBindings.HttpSoap, Index = endpoint.Index, Location = logoutEndpoint.Location }; artifactResolutionEndpoints.Add(artifactLogoutEndpoint); } continue; } } serviceProviderDescriptor.SingleLogoutService = logoutServiceEndpoints.ToArray(); serviceProviderDescriptor.AssertionConsumerService = signonServiceEndpoints.ToArray(); // Attribute consuming service. if (config.Metadata.RequestedAttributes.Count > 0) { var attConsumingService = new AttributeConsumingService(); serviceProviderDescriptor.AttributeConsumingService = new[] { attConsumingService }; attConsumingService.Index = signonServiceEndpoints[0].Index; attConsumingService.IsDefault = true; attConsumingService.ServiceName = new[] { new LocalizedName("SP", "en") }; attConsumingService.RequestedAttribute = new RequestedAttribute[config.Metadata.RequestedAttributes.Count]; for (var i = 0; i < config.Metadata.RequestedAttributes.Count; i++) { attConsumingService.RequestedAttribute[i] = new RequestedAttribute { Name = config.Metadata.RequestedAttributes[i].Name, NameFormat = SamlAttribute.NameformatBasic }; if (config.Metadata.RequestedAttributes[i].IsRequired) { attConsumingService.RequestedAttribute[i].IsRequired = true; } } } else { serviceProviderDescriptor.AttributeConsumingService = new AttributeConsumingService[0]; } if (config.Metadata == null || !config.Metadata.ExcludeArtifactEndpoints) { serviceProviderDescriptor.ArtifactResolutionService = artifactResolutionEndpoints.ToArray(); } entity.Items = new object[] { serviceProviderDescriptor }; // Keyinfo var keySigning = new KeyDescriptor(); var keyEncryption = new KeyDescriptor(); serviceProviderDescriptor.KeyDescriptor = new[] { keySigning, keyEncryption }; keySigning.Use = KeyTypes.Signing; keySigning.UseSpecified = true; keyEncryption.Use = KeyTypes.Encryption; keyEncryption.UseSpecified = true; var keyinfo = new System.Security.Cryptography.Xml.KeyInfo(); var keyClause = new System.Security.Cryptography.Xml.KeyInfoX509Data(config.ServiceProvider.SigningCertificate, X509IncludeOption.EndCertOnly); keyinfo.AddClause(keyClause); // Ugly conversion between the .Net framework classes and our classes ... avert your eyes!! keySigning.KeyInfo = Serialization.DeserializeFromXmlString <Schema.XmlDSig.KeyInfo>(keyinfo.GetXml().OuterXml); keyEncryption.KeyInfo = keySigning.KeyInfo; // apply the <Organization> element if (config.Metadata.Organization != null) { entity.Organization = new Schema.Metadata.Organization { OrganizationName = new[] { new LocalizedName { Value = config.Metadata.Organization.Name, Language = "en" } }, OrganizationDisplayName = new[] { new LocalizedName { Value = config.Metadata.Organization.DisplayName, Language = "en" } }, OrganizationURL = new[] { new LocalizedURI { Value = config.Metadata.Organization.Url, Language = "en" } } }; } if (config.Metadata.Contacts != null && config.Metadata.Contacts.Any()) { entity.ContactPerson = config.Metadata.Contacts.Select(x => new Schema.Metadata.Contact { ContactType = (Schema.Metadata.ContactType) ((int)x.Type), Company = x.Company, GivenName = x.GivenName, SurName = x.SurName, EmailAddress = new[] { x.Email }, TelephoneNumber = new[] { x.Phone } }).ToArray(); } }