I am trying to configure IdentityServer4 Authentication using a strongly typed configuration object.
The Options pattern documentation by Microsoft says:
You can access other services from dependency injection while configuring options in two ways:
Pass a configuration delegate to Configure on OptionsBuilder. OptionsBuilder provides overloads of Configure that allow you to use up to five services to configure options:
services.AddOptions<MyOptions>("optionalName") .Configure<Service1, Service2, Service3, Service4, Service5>( (o, s, s2, s3, s4, s5) => o.Property = DoSomethingWith(s, s2, s3, s4, s5));
Create your own type that implements IConfigureOptions or IConfigureNamedOptions and register the type as a service.
We recommend passing a configuration delegate to Configure, since creating a service is more complex. Creating your own type is equivalent to what the framework does for you when you use Configure. Calling Configure registers a transient generic IConfigureNamedOptions, which has a constructor that accepts the generic service types specified.
I've looked at the source code for the OptionsBuilder
and it looks like the documentation is accurate in that these two methods are functionally equivalent, but the configuration delegate method isn't working for IdentityServer4 so I'm asking this question as more of a curiosity.
This doesn't work when I add it to Startup.cs
:
services
.AddOptions<IdentityServerAuthenticationOptions>()
.Configure<IdentityServerConfiguration>((options, configuration)) =>
{
options.Audience = configuration.Audience
// etc.
});
services
.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication();
However, creating a class like below:
public sealed class ConfigureOptions : IConfigureNamedOptions<IdentityServerAuthenticationOptions>
{
private readonly IdentityServerConfiguration _configuration;
public ConfigureOptions(IdentityServerConfiguration configuration)
{
_configuration = configuration;
}
public void Configure(string name, IdentityServerAuthenticationOptions options)
{
options.ApiName = _configuration.Audience;
// etc.
}
public void Configure(IdentityServerAuthenticationOptions options)
{
options.ApiName = _configuration.Audience;
// etc.
}
}
And adding it to Startup.cs
like:
services
.AddTransient<IConfigureOptions<IdentityServerAuthenticationOptions>, ConfigureOptions>();
services
.AddAuthentication(IdentityServerAuthenticationDefaults.AuthenticationScheme)
.AddIdentityServerAuthentication();
Makes it work perfectly.
Does anyone know why it would behave like that?