I am working on .Net Core Web App with IdentityServer4 installed and configured on Startup.cs, Here I am loading the token signing certificate from a service that I already registered in the IOC:
builder.AddSigningCredential(services.BuildServiceProvider().
GetService<ISecretStoreService>().
TokenSigningCertificate().Result);
Below the full code:
public void ConfigureServices(IServiceCollection services)
{
//....
var builder = services.AddIdentityServer(options =>
{
options.IssuerUri = Configuration.GetValue<string>("IdSrv:IssuerUri"); ;
options.PublicOrigin = Configuration.GetValue<string>("IdSrv:PublicOrigin"); ;
options.Events.RaiseErrorEvents = true;
options.Events.RaiseInformationEvents = true;
options.Events.RaiseFailureEvents = true;
options.Events.RaiseSuccessEvents = true;
options.UserInteraction.LoginUrl = "/Account/Login";
options.UserInteraction.LogoutUrl = "/Account/Logout";
options.Authentication = new AuthenticationOptions()
{
CookieLifetime = TimeSpan.FromHours(10),
CookieSlidingExpiration = true
};
})
.AddConfigurationStore(options =>
{
options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
})
.AddOperationalStore(options =>
{
options.ConfigureDbContext = b => b.UseSqlServer(connectionString, sql => sql.MigrationsAssembly(migrationsAssembly));
options.EnableTokenCleanup = true;
})
.AddAspNetIdentity<AppUser>()
.AddExtensionGrantValidator<PhoneNumberTokenGrantValidator>();
if (Environment.IsDevelopment())
{
builder.AddDeveloperSigningCredential();
}
else
{
builder.AddSigningCredential(services.BuildServiceProvider().
GetService<ISecretStoreService>().
TokenSigningCertificate().Result);
}
//....
}
Also:
public interface ISecretStoreService
{
Task<X509Certificate2> TokenValidationCertificate();
Task<X509Certificate2> TokenSigningCertificate();
Task<X509Certificate2> RetrieveCertificate(string certName);
Task<X509Certificate2> RetrieveSecretAsCertificate(string certName);
}
I am getting this warning and it makes sense as service locator is an anti-pattern:
ASP0000 Calling 'BuildServiceProvider' from application code results in an additional copy of singleton services being created. Consider alternatives such as dependency injecting services as parameters to 'Configure'.
The question here is, how can I avoid calling services.BuildServiceProvider()
inside the Startup class' ConfigureServices(IServiceCollection services){...}
to follow the correct pattern and to get rid of this warning?
I went through some answers on SO but it was just to get rid of the warning but still inject the whole Service Locator which is an anti-pattern. I'd say that the only solution in mind is to extend the middleware to add a specific logic (middleware options) so I can call it without the need to construct the services.BuildServiceProvider()
.