I am working on a backend project that I built using ASP.NET Core 3.1 Web API. All worked fine until I decided to migrate my project to .NET 6, I have updated all libraries accordingly to the new target framework.
Now when running my Web API, the check health Url works fine, but when trying to open swagger or call an endpoint of my web API I got this error:
No signing credential is configured by the 'IdentityServer:Key' configuration section.
I didn't have this issue when I was on .NET Core 3.1, I did some googling and I found that adding this function .AddDeveloperSigningCredential()
can resolve the issue but this didn't work for me.
Here is my code:
public static class ProgramExtensions
{
readonly static string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
private const string SecretKey = "**********************";
private static readonly SymmetricSecurityKey _signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(SecretKey));
public static IConfiguration? Configuration { get; set; }
public static WebApplicationBuilder ConfigureBuilder(this WebApplicationBuilder builder)
{
Configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json",
optional: true, reloadOnChange: true).Build();
AppDbContext.ConnectionString = Configuration.GetConnectionString("myCX");
builder.Services.AddSingleton<IEmailConfiguration>(Configuration.GetSection("EmailConfiguration").Get<EmailConfiguration>());
builder.Services.AddApplication();
services.AddDbContext<AppDbContext>(options =>
options.UseSqlServer(
connectionString,
x => x.UseNetTopologySuite()
.CommandTimeout(10000)));
services.AddScoped<IAppDbContext>(provider => provider.GetService<AppDbContext>());
services.AddTransient(typeof(IAppLogger<>), typeof(LoggerAdapter<>));
services.AddIdentity<ApplicationUser, IdentityRole>(opt =>
{
opt.Password.RequiredLength = 7;
opt.Password.RequireDigit = false;
opt.Password.RequireUppercase = false;
opt.User.RequireUniqueEmail = true;
}).AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
services.AddIdentityServer()
.AddDeveloperSigningCredential()
.AddApiAuthorization<ApplicationUser, AppDbContext>();
builder.Services.AddSingleton<IJwtFactory, JwtFactory>();
builder.Services.AddScoped<JwtIssuerOptions>();
// Get options from app settings
var jwtAppSettingOptions = Configuration.GetSection(nameof(JwtIssuerOptions));
// Configure JwtIssuerOptions
builder.Services.Configure<JwtIssuerOptions>(options =>
{
options.Issuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
options.Audience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)];
options.SigningCredentials = new SigningCredentials(_signingKey, SecurityAlgorithms.HmacSha256);
});
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)],
ValidateAudience = true,
ValidAudience = jwtAppSettingOptions[nameof(JwtIssuerOptions.Audience)],
ValidateIssuerSigningKey = true,
IssuerSigningKey = _signingKey,
RequireExpirationTime = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
builder.Services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
}).AddJwtBearer(configureOptions =>
{
configureOptions.ClaimsIssuer = jwtAppSettingOptions[nameof(JwtIssuerOptions.Issuer)];
configureOptions.TokenValidationParameters = tokenValidationParameters;
configureOptions.SaveToken = true;
});
builder.Services.AddAuthorization();
builder.Services.AddControllers();
builder.Services.AddSwaggerGen(c => c.SwaggerDoc("v1", new OpenApiInfo { Title = "COVAL API", Version = "v1" }));
builder.Services.AddHealthChecks()
.AddDbContextCheck<AppDbContext>();
return builder;
}
public static WebApplication ConfigureApplication(this WebApplication app)
{
app.UseCors(MyAllowSpecificOrigins);
app.UseCustomExceptionHandler();
app.UseHealthChecks("/health", new HealthCheckOptions
{
ResponseWriter = async (context, report) =>
{
context.Response.ContentType = "application/json";
var response = new HealthCheckReponse
{
Status = report.Status.ToString(),
HealthChecks = report.Entries.Select(x => new IndividualHealthCheckResponse
{
Component = x.Key,
Status = x.Value.Status.ToString(),
Description = $"{JsonConvert.SerializeObject(x)}\n{x.Value.Data}\n{x.Value.Description}\n{x.Value.Exception?.Message}\n{x.Value.Exception?.StackTrace}"
}),
HealthCheckDuration = report.TotalDuration
};
await context.Response.WriteAsync(JsonConvert.SerializeObject(response));
}
});
app.UseHttpsRedirection();
app.UseAuthentication();
app.UseIdentityServer();
app.UseRouting();
app.UseAuthorization();
// Enable middleware to serve generated Swagger as a JSON endpoint.
app.UseSwagger();
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), specifying the Swagger JSON endpoint.
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"));
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
return app;
}
}
Can anyone tell me what am I missing in my code please or what should I do to resolve this issue ?
Many thanks.