The
RsaKeyService.cs
file is inspired by this repo.
In Startup.cs of an IdentityServer4 app written for dotnet core 2.x, you'll see code like:
if (Environment.IsDevelopment())
{
builder.AddDeveloperSigningCredential();
}
else
{
throw new Exception("need to configure key material");
}
An Exception will be thrown in production, because you're expected to specify a more secure signing credential in production.
I don't fully understand how signing credentials are used, so I am open to simple explanations on the subject, but considering that I spent quite a while coming up with this way to generate signing credentials for production, I thought to share.
Please give feedback if you know a better way, and be kind enough to explain why.
You can register the RsaKeyService
class as a Singleton in your Startup.cs file like:
public void ConfigureServices(IServiceCollection services)
{
var rsa = new RsaKeyService(Environment, TimeSpan.FromDays(30));
services.AddSingleton<RsaKeyService>(provider => rsa);
}
This makes sure that at least 30 days passes before a new RSA key file is generated.
Next, rewrite the signing credential conditional snippet as:
if (Environment.IsDevelopment())
{
builder.AddDeveloperSigningCredential();
}
else
{
builder.AddSigningCredential(rsa.GetKey());
}
Holla in the comments, if this helps you.
I have a question about rotating the signing key. Does this code force IdentityServer4 to use the new signing key when it's generated? If it does, how do you ensure that both previously signed tokens keep working until they expire? If it doesn't, do you simply reload the new key each time the app is restarted?