The Rock Solid Knowledge SAML SP component allows you to customize your authentication requests. Some of the common use cases for customizing requests include:
- Requesting a NameID format
- Sending a subject login hint
- Enabling the
ForceAuthn
attribute to request the IdP to re-authenticate the user - Sending an advisory list of identity providers that are deemed acceptable to respond to the authentication request
Global Configuration
The Saml2pAuthenticationOptions
contains properties that allow you to customize your authentication requests, such as ForceAuthn
and NameIdPolicy
.
These options are applied to every authentication request you generate.
Check out the SP configuration options for more details.
.AddSaml2p("saml2p", options =>
{
// Other configuration code removed for brevity
options.NameIdPolicy = new NameIdPolicy
{
Format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
};
});
Overriding Options per Request
For configuring a specific request, check out the Overriding Options per Request page for more details.
Overriding the way requests are generated
If you cannot customize your authentication requests using the above configuration options, you can override the SamlSingleSignOnRequestGenerator
class, which is used for generating authentication requests.
This class is injected into the DI container using a factory, meaning you must override the factory to use your implementation.
public class CustomSamlSingleSignOnRequestGenerator : SamlSingleSignOnRequestGenerator
{
public CustomSamlSingleSignOnRequestGenerator(
ISamlBindingService bindingService,
IDateTimeService dateTimeService,
ISamlArtifactService artifactService,
SamlSigningCertificateStore signingCertificateStore,
ISamlArtifactStore artifactStore,
IHttpContextAccessor httpContextAccessor,
SamlSpOptions samlOptions,
SigningOptions signingOptions,
ILogger<ISamlSingleSignOnRequestGenerator> logger)
: base(bindingService, dateTimeService, artifactService, signingCertificateStore,
artifactStore, httpContextAccessor, samlOptions, signingOptions, logger)
{ }
protected override async Task<SamlRequest> CreateRequest(EntityId issuer, Uri destination)
{
var request = await base.CreateRequest(issuer, destination);
// edit request
return request;
}
}
public class CustomSamlSingleSignOnRequestGeneratorFactory : ISamlFactory<ISamlSingleSignOnRequestGenerator>
{
private readonly ISamlBindingService bindingService;
private readonly IDateTimeService dateTimeService;
private readonly IHttpContextAccessor httpContextAccessor;
private readonly ISamlArtifactService artifactService;
private readonly ISamlArtifactStore artifactStore;
private readonly ILogger<ISamlSingleSignOnRequestGenerator> logger;
public CustomSamlSingleSignOnRequestGeneratorFactory(
ISamlBindingService bindingService,
IDateTimeService dateTimeService,
IHttpContextAccessor httpContextAccessor,
ISamlArtifactService artifactService,
ISamlArtifactStore artifactStore,
ILogger<ISamlSingleSignOnRequestGenerator> logger)
{
this.bindingService = bindingService ?? throw new ArgumentNullException(nameof(bindingService));
this.dateTimeService = dateTimeService ?? throw new ArgumentNullException(nameof(dateTimeService));
this.httpContextAccessor = httpContextAccessor ?? throw new ArgumentNullException(nameof(httpContextAccessor));
this.artifactService = artifactService ?? throw new ArgumentNullException(nameof(artifactService));
this.artifactStore = artifactStore ?? throw new ArgumentNullException(nameof(artifactStore));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
public ISamlSingleSignOnRequestGenerator Create(SamlSpOptions options)
{
return new CustomSamlSingleSignOnRequestGenerator(
bindingService,
dateTimeService,
artifactService,
new SamlSigningCertificateStore(new SamlOptionsKeyService(options)),
artifactStore,
httpContextAccessor,
options,
options?.SigningOptions,
logger);
}
}
services.AddScoped<ISamlFactory<ISamlSingleSignOnRequestGenerator>, CustomSamlSingleSignOnRequestGeneratorFactory>();
You should register your factory with DI after the call to AddSaml2p
.