0

Asp.Net Core 2.0のIServiceCollectionの認証オプションをどのように置き換えるのですか? ConfigureServicesでAsp.Net Core 2実行時のオープンコレクションのサービスコレクションの認証オプションの置換

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

はのは、私のクライアントIDは、実行時に変更されているとしましょう、私はコンフィギュレーションをリロードしたいので、私は私のappsettings.jsonの変化を監視します。

構成を削除してサービスに追加して置き換えることは、構成には適用されません。実行時に新しいスキームを追加する方法を

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; 
} 

答えて

0

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)); 
} 

我々は独自のconfigureを作成することができますが、我々は、Googleのconfigureを必要としません。だから、あなたは、Googleのconfigureを削除することができます。

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

あなたはconfigureオプションを作成して登録する必要があります。私たちのconfigureオプションの

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

実装:

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 
     } 
    } 
} 

そして、あなたはでオプションをオーバーライドする場合をDB(例えば)の場合、キャッシュをクリアする必要があります。 なぜですか?

  1. Googleのハンドラは、私たちがInitializeAsyncメソッドを持っているAuthenticationHandlerでAuthenticationHandler
  2. を継承します。

  3. InitializeAsyncメソッドはOptionsMonitorからオプションを取得します。

  4. OptionsMonitorは、キャッシュからオプションを取得するか、または新規作成し、 キャッシュに追加します。もちろん

、あなたは、例えば、クリーン/より良い方法:) でそれを書く必要があります:あなたはすべてを(そしてあなたは、スタートアップのいずれかの国内避難民を必要としない)に登録独自のAddGoogle()メソッドを作成することができます。 上記のコードは、すべてそれを行う必要があることを示す必要があります。質問がある場合は私に知らせてください:)

+0

私の元来の質問は、実行時に既存のスキームを新しいオプションに置き換える方法であり、スキームを追加する方法ではありませんでした。このソリューションは期待どおりに機能しません。スキームを削除して新しいインスタンスを追加して新しいオプションを登録した後も、古いオプションは引き続き使用されます。あなたがキャッシュ:) からそれを得るためにあなたがする必要が – szahn

+0

はい、古いオプションはまだ使用され、: 1.あなたのオプション 'IConfigureOptions ' 2.注入キャッシュ 'IOptionsMonitorCache ' 3を注入します。オーバーライドオプション 4.キャッシュをクリアします。 5.オプションを保持しているDBや他のストアを更新する必要があることを覚えておいてください:) removeメソッドとaddメソッドを使用して、 'IOptionsMonitorCache 'のオプションを上書きすることもできます。 IOptionsMonitorCacheのソースコード:https://github.com/aspnet/Options/blob/dev/src/Microsoft.Extensions.Options/IOptionsMonitorCache.cs – Pyotreq

関連する問題