Search code examples
authenticationidentityserver4saml-2.0

Dynamic schemes SAML 2.0 for IdentityServer4 with IAuthenticationSchemeProvider


I'm trying to setup IdentityServer4 to work with multiple external IdPs which are added dynamically with the help of IAuthenticationSchemeProvider's AddScheme method.

I've successfully done it for OpenIdConnect IdPs, but having a bit of a trouble with Saml2p based IdPs. Following this sample, I followed the same logic for Saml2p:

Injected IOptionsMonitorCache<Saml2pAuthenticationOptions> and :

if (await _schemeProvider.GetSchemeAsync(scheme) == null)
            {
                _schemeProvider.AddScheme(new AuthenticationScheme(scheme, scheme, typeof(Saml2pAuthenticationHandler)));
            }
            else
            {
                 _saml2pOptionsCache.TryRemove(scheme);
            }
            _saml2pOptionsCache.TryAdd(scheme, samlOptions);

And I'm getting an exception:

Unable to resolve service for type 'Rsk.AspNetCore.Authentication.Saml2p.Factories.ISamlFactory``1[IdentityServer4.Saml.Generators.Interfaces.IServiceProviderMetadataGenerator]' while attempting to activate 'Rsk.AspNetCore.Authentication.Saml2p.Saml2pAuthenticationHandler'.

I am not sure if i should setup some additional configurations regarding Saml while adding the scheme, any help appreciated.

Edit: I am using Rsk NuGet for SAML 2.0


Solution

  • The call to AddSaml2p registers a load of dependencies as well as the authentication handler.

    I would either call AddSaml2p somewhere in your code or register the required dependencies yourself like so:

    builder.Services.AddMemoryCache();
    builder.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
    
    builder.Services.TryAddScoped<ISamlFactory<IServiceProviderMetadataGenerator>, 
    builder.Services.TryAddScoped<ISamlFactory<ISaml2SingleSignOnRequestGenerator>, Saml2SingleSignOnRequestGeneratorFactory>();
    builder.Services.TryAddScoped<ISamlFactory<ISaml2SingleLogoutRequestGenerator>, Saml2SingleLogoutRequestGeneratorFactory>();
    builder.Services.TryAddScoped<ISamlFactory<ISaml2SingleSignOnResponseValidator>, Saml2SingleSignOnResponseValidatorFactory>();
    
    builder.Services.TryAddScoped<ISamlBindingService, SamlBindingService>();
    builder.Services.TryAddScoped<ISamlSigningService, SamlSigningService>();
    builder.Services.TryAddScoped<IDateTimeService, SystemClockDateTimeService>();
    builder.Services.TryAddScoped<ISamlTimeComparer, SamlTimeComparer>();
    builder.Services.TryAddScoped<ISamlCorrelationStore, CookieCorrelationStore>();