The Rock Solid Knowledge SAML SP allows you to customize your metadata document. Some of the common uses cases for customizing metadata include:
- Adding Organization and Contact details
- Adding
AttributeConsumingServices
- Changing the expiration time of the metadata
- Changing the maximum amount of time a consumer should cache the metadata
- Adding supported NameID formats
- Setting a default ACS endpoint
Metadata Configuration Settings
The startup configuration option ServiceProviderOptions.MetadataOptions
allows you to configure information such as your Organization and Contact details.
Check out the SP configuration options for more details.
.AddSaml2p("saml2p", options =>
{
// Other configuration code removed for brevity
options.ServiceProviderOptions.MetadataOptions = new ServiceProviderMetadataOptions
{
OrganizationDetails = new Organization
{
Name = "RSK",
Url = new Uri("https://www.rocksolidknowledge.com/")
}
};
});
Overriding Metadata Generator
If you cannot make the desired customization using the ServiceProviderOptions.MetadataOptions
configuration option, you can override the IServiceProviderMetadataGenerator
.
This service generates the metadata configuration before it gets serialized.
This class is injected into the DI container as a factory, meaning you must override the factory to use your implementation.
public class CustomServiceProviderMetadataGenerator : IServiceProviderMetadataGenerator
{
private readonly IServiceProviderMetadataGenerator defaultGenerator;
public CustomServiceProviderMetadataGenerator(IServiceProviderMetadataGenerator defaultGenerator)
{
this.defaultGenerator = defaultGenerator ?? throw new ArgumentNullException(nameof(defaultGenerator));
}
public async Task<SamlEntityDescriptor> GenerateMetadata()
{
var metadata = await defaultGenerator.GenerateMetadata();
// edit the metadata, for example:
var descriptor = metadata.RoleDescriptors.First(x => x.GetType() == typeof(ServiceProviderSingleSignOnDescriptor)) as ServiceProviderSingleSignOnDescriptor;
descriptor.NameIdentifierFormats.Add(new Uri(SamlConstants.NameIdentifierFormats.Unspecified));
return metadata;
}
}
public class CustomServiceProviderMetadataGeneratorFactory : ISamlFactory<IServiceProviderMetadataGenerator>
{
private readonly IHttpContextAccessor contextAccessor;
public CustomServiceProviderMetadataGeneratorFactory(IHttpContextAccessor contextAccessor)
{
this.contextAccessor = contextAccessor ?? throw new ArgumentNullException(nameof(contextAccessor));
}
public IServiceProviderMetadataGenerator Create(SamlSpOptions options)
{
return new CustomServiceProviderMetadataGenerator(new ServiceProviderMetadataGenerator(
contextAccessor,
new SamlSigningCertificateStore(new SamlOptionsKeyService(options)),
options));
}
}
services.AddScoped<ISamlFactory<IServiceProviderMetadataGenerator>, CustomServiceProviderMetadataGeneratorFactory>();