0

Comment remplacer les options d'authentification dans une IServiceCollection dans Asp.Net Core 2.0?Asp.Net Core 2 Remplacer les options d'authentification Open Id dans la collection de services au moment de l'exécution

En ConfigureServices:

AddAuthentication((o) => 
{ 
    o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; 
    o.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme; 
}).AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, (o) => 
{ 
    o.LoginPath = Constants.LoginPath; 
}).AddOpenIdConnect(ConfigureOpenIdConnectProvider); 

Disons que mon numéro de client a changé au moment de l'exécution, je veux recharger la configuration, donc je surveiller les changements dans mon appsettings.json.

Le remplacement de la configuration par sa suppression et son ajout dans les services n'applique pas la configuration.

Configuration.GetReloadToken().RegisterChangeCallback(OnConfigurationChanged(authServices), new Object()); 
private Action<object> OnConfigurationChanged(IServiceCollection authServices) 
{ 
    return o => 
    { 
     Action<OpenIdConnectOptions> action = ConfigureOpenIdConnectProvider; 

     //Replace the existing open id connection options 
     authServices.Remove(authServices.FirstOrDefault(s => typeof(IConfigureOptions<OpenIdConnectOptions>).Equals(s.ServiceType))); 
     authServices.Configure(OpenIdConnectDefaults.AuthenticationScheme, action); 
    }; 
} 


private void ConfigureOpenIdConnectProvider(OpenIdConnectOptions opts) 
{ 
    var provider = Configuration.GetSection("OAuthClientProvider").Get<OAuthClientProvider>(); 
    opts.ClientId = provider.ClientId; 
    opts.ClientSecret = provider?.ClientSecret ?? string.Empty; 
    opts.Authority = provider.Authority; 
} 

Répondre

0

Comment ajouter un nouveau programme en exécution:

private void AddGoogleScheme(IApplicationBuilder app) 
{ 
    var googleHandlerType = typeof(GoogleOptions).Assembly.GetType("Microsoft.AspNetCore.Authentication.Google.GoogleHandler"); 
    var provider = app.ApplicationServices.GetService<IAuthenticationSchemeProvider>(); 
    provider.AddScheme(new AuthenticationScheme("Google", "Google", googleHandlerType)); 
} 

Nous pouvons créer notre propre configuration, mais on n'a pas besoin de Google configurer. Ainsi, vous pouvez supprimer configurer Google:

var googleConfigureOptions = services.SingleOrDefault(x => x.ServiceType == typeof(IConfigureOptions<GoogleOptions>)); 
services.Remove(googleConfigureOptions); 

Vous devez créer et enregistrer de configurer les options:

builder.Services.AddTransient<IConfigureOptions<GoogleOptions>, OpenIdConnectConfigurator<GoogleOptions>>(); 

La mise en œuvre de nos options de configuration:

internal class OpenIdConnectConfigurator<TOptions> : IConfigureNamedOptions<TOptions> where TOptions : RemoteAuthenticationOptions 
{ 
    public void Configure(TOptions options) 
    { 
     throw new InvalidOperationException(); 
    } 

    public void Configure(string name, TOptions options) 
    { 
     if(name == "Google") // name == "YourScheme" 
     { 
     // you can get data from DB or other source 
     // options.ClientId = ... 
     // options.ClientSecret = ... 
     } else { 
     // Facebook or other IDP 
     } 
    } 
} 

Et si vous substituez options DB (par exemple), vous devez effacer le cache. Pourquoi?

  1. gestionnaire Google hérite AuthenticationHandler
  2. En AuthenticationHandler nous avons la méthode InitializeAsync.

  3. La méthode InitializeAsync obtient des options à partir de OptionsMonitor.

  4. OptionsMonitor obtient des options du cache ou en crée de nouvelles et ajoute au cache .

Bien sûr, vous devriez l'écrire de manière propre/mieux :) Par exemple: vous pouvez créer votre propre méthode AddGoogle() qui enregistre tout (vous ne avez pas besoin de déplacés internes au démarrage). Tous les codes ci-dessus devraient montrer que vous devez faire cela. Si vous avez des questions, faites le moi savoir :)

+0

Ma question initiale était comment remplacer un schéma existant avec de nouvelles options à l'exécution, pas ajouter un schéma. Cette solution ne fonctionne pas comme prévu. Même après la suppression du schéma et l'ajout d'une nouvelle instance et l'enregistrement d'une nouvelle option, les anciennes options sont toujours utilisées. – szahn

+0

Oui, les anciennes options sont encore utilisées, parce que vous obtenez du cache :) donc vous devez: 1. Injecter vos options 'IConfigureOptions ' 2. cache 'inject IOptionsMonitorCache ' 3. options de remplacement 4. effacez le cache. 5. N'oubliez pas que vous devez mettre à jour DB ou un autre magasin dans lequel vous conservez vos options :) Vous pouvez également remplacer les options dans 'IOptionsMonitorCache ' en utilisant les méthodes remove et add. Code source vers IOptionsMonitorCache: https://github.com/aspnet/Options/blob/dev/src/Microsoft.Extensions.Options/IOptionsMonitorCache.cs – Pyotreq