I’m having a problem with the metadata generation. I am attempting to generate metadata using my current configuration.
I am configuring programatically, not using the saml.config file. I followed the metadata export example but am getting
incomplete results when the metadata gets generated.
Here is what I get: (see below of the actual xml returned)
All of the locations that should have URLs in them instead have the string “TODO: URL of xxxx”, none of the locations have URLS present even though they were defined in the configuration.
The “WantAssertionSigned” is present but not the “WantSAMLResponseSigned”, both of them are configured.
// Configuration code that is run when app starts up
SAMLConfiguration cfg = new SAMLConfiguration();
cfg.LocalServiceProviderConfiguration = new LocalServiceProviderConfiguration()
{
Name = “urn:componentspace:MvcExampleServiceProvider”,
AssertionConsumerServiceUrl = “~/SSO/AssertionConsumerService”,
};
cfg.AddPartnerIdentityProvider(new PartnerIdentityProviderConfiguration()
{
Name = “urn:componentspace:MvcExampleIdentityProvider”,
WantSAMLResponseSigned = true,
WantAssertionSigned = true,
WantAssertionEncrypted = false,
SingleSignOnServiceUrl = “<a href=“http://localhost/SamlIdentityProvider/SAML/SSOService",">http://localhost/SamlIdentityProvider/SAML/SSOService”,
SingleLogoutServiceUrl = “<a href=“http://localhost/SamlIdentityProvider/SAML/SLOService",">http://localhost/SamlIdentityProvider/SAML/SLOService”,
});
SAMLController.Configuration = cfg;
// Code to generate the MetaData after the system has been configured
public ActionResult MetaData()
{
EntityDescriptor entityDescriptor = MetadataExporter.Export(ComponentSpace.SAML2.SAMLController.Configuration, “urn:componentspace:MvcExampleIdentityProvider”); // last param is PartnerName
XmlDocument xmlDocument = entityDescriptor.ToXml().OwnerDocument;
string xmlstr;
using (var sw = new StringWriter())
{
using (XmlTextWriter xmlTextWriter = new XmlTextWriter(sw))
{
xmlTextWriter.Formatting = Formatting.Indented;
xmldocument.Save(xmlTextWriter);
}
xmlstr = sw.ToString();
}
return this.Content(xmlstr, “text/xml”);
}
// XML that is generated by the metadata exporter (some of the non-relevant stuff has been removed)
<md:EntityDescriptor xmlns:md=“urn:oasis:names:tc:SAML:2.0:metadata” entityID=“urn:componentspace:MvcExampleServiceProvider” ID=”_67c6fc46-5cd2-4eb5-b618-e25ff1126807”>
<md:SPSSODescriptor ID=“_8e981668-a153-4eb4-8251-fbceeb8f4d51” protocolSupportEnumeration=“urn:oasis:names:tc:SAML:2.0:protocol” AuthnRequestsSigned=“false” WantAssertionsSigned=“true”>
<md:SingleLogoutService Binding=“urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect” Location=“TODO: URL of SLO service endpoint”/>
<md:SingleLogoutService Binding=“urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST” Location=“TODO: URL of SLO service endpoint”/>
<md:AssertionConsumerService Binding=“urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST” Location=“TODO: URL of assertion consumer service endpoint” index=“0” isDefault=“true”/>
</md:SPSSODescriptor>
</md:EntityDescriptor>
The URL issue is a limitation at the moment that will be addressed in a future release. If you configure absolute URLs as you’ve done then we should use these rather than including “TODO” instructions.
In the meantime, please update these manually.
I’ve copied below some code from the high-level API ExampleServiceProvider’s SAML/ExportMetadata.aspx page which handles URLs.
// Replace placeholder URLs.
string assertionConsumerServiceUrl = CreateAbsoluteURL(“~/SAML/AssertionConsumerService.aspx”);
string singleLogoutServiceUrl = CreateAbsoluteURL(“~/SAML/SLOService.aspx”);
entityDescriptor.SPSSODescriptors[0].AssertionConsumerServices.Clear();
entityDescriptor.SPSSODescriptors[0].AssertionConsumerServices.Add(new IndexedEndpointType(SAMLIdentifiers.BindingURIs.HTTPPost, assertionConsumerServiceUrl, null, 0, true));
entityDescriptor.SPSSODescriptors[0].SingleLogoutServices.Clear();
entityDescriptor.SPSSODescriptors[0].SingleLogoutServices.Add(new EndpointType(SAMLIdentifiers.BindingURIs.HTTPRedirect, singleLogoutServiceUrl, null));
entityDescriptor.SPSSODescriptors[0].SingleLogoutServices.Add(new EndpointType(SAMLIdentifiers.BindingURIs.HTTPPost, singleLogoutServiceUrl, null));
Normally you would require either the SAML response or SAML assertion signed but not both. Signing the SAML response covers the SAML assertion as well.
There is no WantSAMLResponseSigned equivalent in SAML metadata. If WantAssertionsSigned is false then the implication is that the SAML responses should be signed.