I am using Google authentication in my web app, and the OAuth keys are currently hard-coded in ConfigureServices:
services.AddAuthentication()
.AddGoogle(options =>
{
options.ClientId = "my-client-id";
options.ClientSecret = "my-client-secret";
});
However, I would like to give the site administrator the opportunity to change the ClientId and ClientSecret from the web app's settings page, preferably without having to restart the server.
To do this, I'd have to somehow trigger a re-configuration of the Google service and the GoogleOptions object when the user hits 'Save' on the settings page. This is what I'm having trouble with. Also, I would like to store these settings in an EF Core DbContext, and not in a physical config file.
So far I've tried to move the settings to a separate class that implements IPostConfigureOptions. This should allow me to inject my database context, because based on the documentation, PostConfigure is supposed to run after all other configurations have occurred. The settings are loaded correctly from this new class, but the injection of the DB context fails with the following exception:
System.InvalidOperationException: Cannot consume scoped service 'AppDatabase' from singleton 'IOptionsMonitor`1[GoogleOptions]'
This is weird, because the ConfigureGoogleOptions is registered as Scoped, and not as a Singleton.
Here's my options class:
public class ConfigureGoogleOptions : IPostConfigureOptions<GoogleOptions>
{
private readonly AppDatabase database;
public ConfigureGoogleOptions(AppDatabase database)
{
this.database = database;
}
public void PostConfigure(string name, GoogleOptions options)
{
options.ClientId = "my-client-id.apps.googleusercontent.com";
options.ClientSecret = "my-client-secret";
}
}
And registering it in ConfigureServices:
services.AddScoped<IPostConfigureOptions<GoogleOptions>, ConfigureGoogleOptions>();
Even if the databse injection worked, there's still a second problem. The PostConfigure function in my class only gets called once after the application starts, and never again. I assume that it caches the settings somewhere, and I don't know how to invalidate or disable this cache so I can dynamically provide values.
Short Summary / tl;dr:
I want to load the ClientId and ClientSecret settings of the Google OAuth service from my own database, and I want to be able to change them dynamically while the server is running.