private EntityDescriptorBuilder(string entityID) { _entityDescriptor = new EntityDescriptorType { entityID = entityID, ID = $"pfx_{Guid.NewGuid()}" }; }
public static string ToXmlMetadata(this Saml2Options options) { IndexedEndpointType[] AssertionConsumerService = options.ServiceProvider.AssertionConsumerServices; EndpointType[] SingleLogoutServices = options.ServiceProvider.SingleLogoutServices; SamlCore.AspNetCore.Authentication.Saml2.Metadata.KeyDescriptorType[] KeyDescriptor = null; if (options.hasCertificate) { KeyDescriptor = new SamlCore.AspNetCore.Authentication.Saml2.Metadata.KeyDescriptorType[] { new SamlCore.AspNetCore.Authentication.Saml2.Metadata.KeyDescriptorType() { useSpecified = true, use = KeyTypes.signing, KeyInfo = new SamlCore.AspNetCore.Authentication.Saml2.Metadata.KeyInfoType() { ItemsElementName = new [] { SamlCore.AspNetCore.Authentication.Saml2.Metadata.ItemsChoiceType2.X509Data }, Items = new SamlCore.AspNetCore.Authentication.Saml2.Metadata.X509DataType[] { new SamlCore.AspNetCore.Authentication.Saml2.Metadata.X509DataType() { Items = new object[] { options.ServiceProvider.X509Certificate2.GetRawCertData() }, ItemsElementName = new [] { SamlCore.AspNetCore.Authentication.Saml2.Metadata.ItemsChoiceType.X509Certificate } } } } }, new SamlCore.AspNetCore.Authentication.Saml2.Metadata.KeyDescriptorType() { useSpecified = true, use = KeyTypes.encryption, KeyInfo = new SamlCore.AspNetCore.Authentication.Saml2.Metadata.KeyInfoType() { ItemsElementName = new [] { SamlCore.AspNetCore.Authentication.Saml2.Metadata.ItemsChoiceType2.X509Data }, Items = new SamlCore.AspNetCore.Authentication.Saml2.Metadata.X509DataType[] { new SamlCore.AspNetCore.Authentication.Saml2.Metadata.X509DataType() { Items = new object[] { options.ServiceProvider.X509Certificate2.GetRawCertData() }, ItemsElementName = new [] { SamlCore.AspNetCore.Authentication.Saml2.Metadata.ItemsChoiceType.X509Certificate } } } } } }; } var entityDescriptor = new EntityDescriptorType() { entityID = options.ServiceProvider.EntityId, Items = new object[] { new SPSSODescriptorType() { NameIDFormat = new [] { Saml2Constants.NameIDFormats.Email }, protocolSupportEnumeration = new [] { Saml2Constants.Namespaces.Protocol }, AuthnRequestsSignedSpecified = true, AuthnRequestsSigned = options.hasCertificate, WantAssertionsSignedSpecified = true, WantAssertionsSigned = options.WantAssertionsSigned, KeyDescriptor = KeyDescriptor, SingleLogoutService = SingleLogoutServices, AssertionConsumerService = AssertionConsumerService, AttributeConsumingService = new AttributeConsumingServiceType[] { new AttributeConsumingServiceType { ServiceName = new localizedNameType[] { new localizedNameType() { Value = options.ServiceProvider.ServiceName, lang = options.ServiceProvider.Language } }, ServiceDescription = new localizedNameType[] { new localizedNameType() { Value = options.ServiceProvider.ServiceDescription, lang = options.ServiceProvider.Language } }, index = 0, isDefault = true, isDefaultSpecified = true, RequestedAttribute = options.RequestedAttributes.ToArray() } }, Organization = new OrganizationType() { OrganizationDisplayName = new localizedNameType[] { new localizedNameType { lang = options.ServiceProvider.Language, Value = options.ServiceProvider.OrganizationDisplayName }, }, OrganizationName = new localizedNameType[] { new localizedNameType { lang = options.ServiceProvider.Language, Value = options.ServiceProvider.OrganizationName }, }, OrganizationURL = new localizedURIType[] { new localizedURIType { lang = options.ServiceProvider.Language, Value = options.ServiceProvider.OrganizationURL }, }, }, }, }, ContactPerson = new ContactType[] { new ContactType() { Company = options.ServiceProvider.ContactPerson.Company, GivenName = options.ServiceProvider.ContactPerson.GivenName, EmailAddress = options.ServiceProvider.ContactPerson.EmailAddress, contactType = options.ServiceProvider.ContactPerson.contactType, TelephoneNumber = options.ServiceProvider.ContactPerson.TelephoneNumber } } }; //generate the sp metadata xml file string xmlTemplate = string.Empty; XmlSerializer xmlSerializer = new XmlSerializer(typeof(EntityDescriptorType)); using (MemoryStream memStm = new MemoryStream()) { xmlSerializer.Serialize(memStm, entityDescriptor); memStm.Position = 0; xmlTemplate = new StreamReader(memStm).ReadToEnd(); } return(xmlTemplate); }
/// <summary> /// Invoked to post configure a TOptions instance. /// </summary> /// <param name="name">The name of the options instance being configured.</param> /// <param name="options">The options instance to configure.</param> /// <exception cref="InvalidOperationException"> /// Service Provider certificate could not be found. /// or /// Multiple Service Provider certificates were found, must only provide one. /// or /// The certificate for this service providerhas no private key. /// or /// The MetadataAddress must use HTTPS unless disabled for development by setting RequireHttpsMetadata=false. /// </exception> public void PostConfigure(string name, Saml2Options options) { options.DataProtectionProvider = options.DataProtectionProvider ?? _dp; if (string.IsNullOrEmpty(options.SignOutScheme)) { options.SignOutScheme = options.SignInScheme; } if (options.StateDataFormat == null) { var dataProtector = options.DataProtectionProvider.CreateProtector( typeof(Saml2Handler).FullName, name, "v1"); options.StateDataFormat = new PropertiesDataFormat(dataProtector); } var request = _httpContextAccessor.HttpContext.Request; if (options.ServiceProvider.AssertionConsumerServices != null) { foreach (var assertionConsumerService in options.ServiceProvider.AssertionConsumerServices) { if (string.IsNullOrEmpty(assertionConsumerService.Location)) { assertionConsumerService.Location = request.Scheme + "://" + request.Host.Value + options.CallbackPath; } else { Uri uriAppUrlResult; bool appProductionURLresult = Uri.TryCreate(assertionConsumerService.Location, UriKind.Absolute, out uriAppUrlResult) && (uriAppUrlResult.Scheme == Uri.UriSchemeHttp || uriAppUrlResult.Scheme == Uri.UriSchemeHttps); if (!appProductionURLresult) { throw new InvalidOperationException("AssertionConsumerService is not a valid URL."); } } } } if (options.ServiceProvider.SingleLogoutServices != null) { foreach (var singleLogoutService in options.ServiceProvider.SingleLogoutServices) { if (string.IsNullOrEmpty(singleLogoutService.Location)) { singleLogoutService.Location = request.Scheme + "://" + request.Host.Value + options.SignOutPath; } else { Uri uriAppUrlResult; bool appProductionURLresult = Uri.TryCreate(singleLogoutService.Location, UriKind.Absolute, out uriAppUrlResult) && (uriAppUrlResult.Scheme == Uri.UriSchemeHttp || uriAppUrlResult.Scheme == Uri.UriSchemeHttps); if (!appProductionURLresult) { throw new InvalidOperationException("SingleLogoutService is not a valid URL."); } } } } if (options.ServiceProvider.X509Certificate2 != null) { options.hasCertificate = true; } if (options.Backchannel == null) { options.Backchannel = new HttpClient(options.BackchannelHttpHandler ?? new HttpClientHandler()); options.Backchannel.DefaultRequestHeaders.UserAgent.ParseAdd("ASP.NET SamlCore handler"); options.Backchannel.Timeout = options.BackchannelTimeout; options.Backchannel.MaxResponseContentBufferSize = 1024 * 1024 * 10; // 10 MB } if (string.IsNullOrEmpty(options.TokenValidationParameters.ValidAudience)) { options.TokenValidationParameters.ValidAudience = options.ServiceProvider.EntityId; } if (options.ConfigurationManager == null) { if (options.Configuration != null) { options.ConfigurationManager = new StaticConfigurationManager <Saml2Configuration>(options.Configuration); } else if (!string.IsNullOrEmpty(options.MetadataAddress)) { Uri uriResult; bool result = Uri.TryCreate(options.MetadataAddress, UriKind.Absolute, out uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); if (result) { if (options.RequireHttpsMetadata && !options.MetadataAddress.StartsWith("https://", StringComparison.OrdinalIgnoreCase)) { throw new InvalidOperationException("The MetadataAddress must use HTTPS unless disabled for development by setting RequireHttpsMetadata=false."); } options.ConfigurationManager = new ConfigurationManager <Saml2Configuration>(options.MetadataAddress, new Saml2ConfigurationRetriever(), new HttpDocumentRetriever(options.Backchannel) { RequireHttps = options.RequireHttpsMetadata }); } else { _idoc.GetDocumentAsync(options.MetadataAddress, default(CancellationToken)); options.ConfigurationManager = new ConfigurationManager <Saml2Configuration>(options.MetadataAddress, new Saml2ConfigurationRetriever(), _idoc); } } } if (options.CreateMetadataFile) { //delete the metadata.xml if exists string[] xmlList = Directory.GetFiles(options.DefaultMetadataFolderLocation, "*.xml"); foreach (string f in xmlList) { if (f == options.DefaultMetadataFolderLocation + "\\" + options.DefaultMetadataFileName + ".xml") { File.Delete(f); } } //overwrite or create metadata.xml if set to true IndexedEndpointType[] AssertionConsumerService = options.ServiceProvider.AssertionConsumerServices; EndpointType[] SingleLogoutServices = options.ServiceProvider.SingleLogoutServices; Metadata.KeyDescriptorType[] KeyDescriptor = null; if (options.hasCertificate) { KeyDescriptor = new Metadata.KeyDescriptorType[] { new Metadata.KeyDescriptorType() { useSpecified = true, use = KeyTypes.signing, KeyInfo = new Metadata.KeyInfoType() { ItemsElementName = new [] { Metadata.ItemsChoiceType2.X509Data }, Items = new Metadata.X509DataType[] { new Metadata.X509DataType() { Items = new object[] { options.ServiceProvider.X509Certificate2.GetRawCertData() }, ItemsElementName = new [] { Metadata.ItemsChoiceType.X509Certificate } } } } }, new Metadata.KeyDescriptorType() { useSpecified = true, use = KeyTypes.encryption, KeyInfo = new Metadata.KeyInfoType() { ItemsElementName = new [] { Metadata.ItemsChoiceType2.X509Data }, Items = new Metadata.X509DataType[] { new Metadata.X509DataType() { Items = new object[] { options.ServiceProvider.X509Certificate2.GetRawCertData() }, ItemsElementName = new [] { Metadata.ItemsChoiceType.X509Certificate } } } } } }; } var entityDescriptor = new EntityDescriptorType() { entityID = options.ServiceProvider.EntityId, Items = new object[] { new SPSSODescriptorType() { NameIDFormat = new [] { Saml2Constants.NameIDFormats.Email }, protocolSupportEnumeration = new [] { Saml2Constants.Namespaces.Protocol }, AuthnRequestsSignedSpecified = true, AuthnRequestsSigned = options.hasCertificate, WantAssertionsSignedSpecified = true, WantAssertionsSigned = options.WantAssertionsSigned, KeyDescriptor = KeyDescriptor, SingleLogoutService = SingleLogoutServices, AssertionConsumerService = AssertionConsumerService, AttributeConsumingService = new AttributeConsumingServiceType[] { new AttributeConsumingServiceType { ServiceName = new localizedNameType[] { new localizedNameType() { Value = options.ServiceProvider.ServiceName, lang = options.ServiceProvider.Language } }, ServiceDescription = new localizedNameType[] { new localizedNameType() { Value = options.ServiceProvider.ServiceDescription, lang = options.ServiceProvider.Language } }, index = 0, isDefault = true, isDefaultSpecified = true, RequestedAttribute = new RequestedAttributeType[] //this doesnt work with ADFS { new RequestedAttributeType { isRequired = true, isRequiredSpecified = true, NameFormat = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", Name = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", FriendlyName = "Name" }, new RequestedAttributeType { isRequired = true, isRequiredSpecified = true, NameFormat = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", Name = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress", FriendlyName = "E-Mail-Adresses" }, new RequestedAttributeType { isRequired = true, isRequiredSpecified = true, NameFormat = "urn:oasis:names:tc:SAML:2.0:attrname-format:uri", Name = "nameid:persistent", FriendlyName = "mail" } } } }, Organization = new OrganizationType() { OrganizationDisplayName = new localizedNameType[] { new localizedNameType { lang = options.ServiceProvider.Language, Value = options.ServiceProvider.OrganizationDisplayName }, }, OrganizationName = new localizedNameType[] { new localizedNameType { lang = options.ServiceProvider.Language, Value = options.ServiceProvider.OrganizationName }, }, OrganizationURL = new localizedURIType[] { new localizedURIType { lang = options.ServiceProvider.Language, Value = options.ServiceProvider.OrganizationURL }, }, }, }, }, ContactPerson = new ContactType[] { new ContactType() { Company = options.ServiceProvider.ContactPerson.Company, GivenName = options.ServiceProvider.ContactPerson.GivenName, EmailAddress = options.ServiceProvider.ContactPerson.EmailAddress, contactType = options.ServiceProvider.ContactPerson.contactType, TelephoneNumber = options.ServiceProvider.ContactPerson.TelephoneNumber } } }; //generate the sp metadata xml file string xmlTemplate = string.Empty; XmlSerializer xmlSerializer = new XmlSerializer(typeof(EntityDescriptorType)); using (MemoryStream memStm = new MemoryStream()) { xmlSerializer.Serialize(memStm, entityDescriptor); memStm.Position = 0; xmlTemplate = new StreamReader(memStm).ReadToEnd(); } //create xml document from string XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(xmlTemplate); xmlDoc.PreserveWhitespace = true; xmlDoc.Save(options.DefaultMetadataFolderLocation + "\\" + options.DefaultMetadataFileName + ".xml"); } }