okta / okta-aspnet

okta-aspnet
https://github.com/okta/okta-aspnet
Apache License 2.0
85 stars 52 forks source link

Configuration Reload Support #184

Open agilenut opened 2 years ago

agilenut commented 2 years ago

We have a requirement to be able to dynamically reload all configuration without requiring an app restart.

This would normally be accomplished by having a config like:

{
"JwtBearerOptions": {
    "Authority": "https://myauthority",
    "Audience":  "https://myaudience"
  } 
}

And then configuring the options like:

services.Configure<JwtBearerOptions>(Configuration.GetSection("JwtBearerOptions"));

However, the Okta examples usually ask you to do:

services.AddAuthentication(options => {
    options.DefaultAuthenticateScheme = OktaDefaults.ApiAuthenticationScheme;
    options.DefaultChallengeScheme = OktaDefaults.ApiAuthenticationScheme;
    options.DefaultSignInScheme = OktaDefaults.ApiAuthenticationScheme;
})
.AddOktaWebApi(new OktaWebApiOptions
    {
        OktaDomain = config.OktaDomain,
        AuthorizationServerId = config.OktaAuthServerId,
        Audience = config.OktaAudienceUrl
    });

The AddOktaWebApi method only accepts an instance of OktaWebApiOptions. There is no way to bind the okta options to the underlying configuration so that they are updated when the config is reloaded. The implementation of AddOktaWebApi sets up the JwtBearerOptions with several Okta defaults as well as your passed in config. But none of this code gets re-executed after config reloads.

I can bypass the AddOktaWebApi method altogether and re-implement the logic in my own direct configuration of JwtBearerOptions but that means I'm duplicating the code in the Okta libraries and will likely miss any important updates that are made to these libraries.

I'd like for this library to directly support dynamic config reloads.

I'd also be curious if anyone knows of another work around that would allow me to continue using AddOktaWebApi but retrigger the execution when the underlying config reloads.

Thanks.

bryanapellanes-okta commented 2 years ago

@agilenut, Thanks for reaching out! We will need to review your request internally to determine how best to address the use case. We'll comment here when there's more.

Thanks for using Okta!

sunefred commented 2 years ago

I would like this as well. This has the added benefit of allowing ASP .NET Core to deslerialize the OktaWebApiOptions directly from appsettings, rather than rely on (possibly misspelled) strings.

Hardcoded strings

services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = OktaDefaults.ApiAuthenticationScheme;
    options.DefaultChallengeScheme = OktaDefaults.ApiAuthenticationScheme;
    options.DefaultSignInScheme = OktaDefaults.ApiAuthenticationScheme;
})
.AddOktaWebApi(new OktaWebApiOptions()
{
    OktaDomain = Configuration["OktaWebApi:OktaDomain"],
    AuthorizationServerId = Configuration["OktaWebApi:AuthorizationServerId"],
    Audience = Configuration["OktaWebApi:Audience"]
});

Let ASP .NET Core deserialize based on OktaWebApiOptions

services.Configure<OktaWebApiOptions>(options => Configuration.Bind(OktaWebApiOptions.DefaultOptionsKey, options));
services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = OktaDefaults.ApiAuthenticationScheme;
    options.DefaultChallengeScheme = OktaDefaults.ApiAuthenticationScheme;
    options.DefaultSignInScheme = OktaDefaults.ApiAuthenticationScheme;
})
.AddOktaWebApi();

A common pattern is to supply a DefaultOptionsKey as a const with a value "Okta" in this case.