ASP.NET Core アプリケーションのSAML認証でIdPを切り替える方法

Category: fx aspnet_ja

Question

hadamard06 on Mon, 03 May 2021 08:18:44


ASP.NET Core のWebアプリケーションでSAMLを使用したSSOを実装しています。

下記のサイトを参考にしたテストプログラムを作成して、Azure ADにて期待通りに認証できる(クレームを受け取る)ことができることは確認できました。
https://cmatskas.com/asp-net-core-saml-authentication-with-azure-ad/

ここで紹介されている方法は、Startup.csのConfigureServicesメソッドにて、services.AddAuthenticationの中で各種の設定をしています。これらの設定の中に、Azure ADのAPP IDとメタデータURLを指定しています。

ただし、実際には、これらの設定を実行中に切り替える、ということを実現したいと考えています。
例えば、画面の中に「Azure ADで認証」とか「Oktaで認証」といったボタンを設けて、ログインするユーザーがIdPを選択するようにできないかと考えています。

しかし、いろいろと調べているのですが、その方法が見つけられませんでした。
認証を行うChallengeメソッドでAPP IDとメタデータURLを指定できるか、もしくは、services.AddAuthenticationと同等の処理がStartup.cs以外の部分で実行できるか、いずれかができないかと調べているのですが、該当する情報が見つけられませんでした。

どなたか情報をお持ちでしたらご教示いただけますと幸いです。
よろしくお願いいたします。

Replies

Haruka6002 on Tue, 11 May 2021 07:49:57


hadamard06さん、こんにちは。フォーラムオペレーターのHarukaです。
MSDNフォーラムにご投稿くださいましてありがとうございます。

複数の認証スキームを使用するには、複数のJWTベアラー認証の使用を検討してください。
このドキュメントを参照してください。 

他にご存知の方がおりましたら、情報をご共有いただければ幸いです。

どうぞよろしくお願いいたします。

hadamard06 on Wed, 12 May 2021 05:35:31


Haruka様

返信ありがとうございます。

お教えいただいたドキュメントに記載されている内容について、ご教示ください。

最初の投稿に記載したサイトを参考に、ConfigureServices内に以下のようなコードを記載しています。

public void ConfigureServices(IServiceCollection services)
{
        services.AddAuthentication(sharedOptions =>
        {
             sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
             sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
             sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
       })
       .AddWsFederation(options =>
       {
  // this is where your AppID URI goes
             options.Wtrealm = "<APIキー>";
             options.MetadataAddress = "<メタデータ>";
       })
       .AddCookie();

       services.AddMvc();
}

また、ユーザー認証を実行するタイミングでは、以下のようにChallengeメソッドを実行すると、Azure ADの認証画面にリダイレクトされます。

[HttpGet]
public IActionResult Login(string returnUrl = null)
{
    var redirectUrl = Url.Content("~/");
    return Challenge(
        new AuthenticationProperties { RedirectUri = redirectUrl },
        WsFederationDefaults.AuthenticationScheme);
}

リダイレクト時に使用されるURL等がAddWsFederationで指定したメタデータに記載されているのだと思いますが、これをConfigureServicesで複数指定した場合に、Challengeメソッドでどちらを使用するのかをどのように指定すれば良いのでしょうか?


情報をおもちでしたらお教えいただけますと幸いです。
よろしくお願いいたします。

Haruka6002 on Tue, 18 May 2021 05:36:48


hadamard06さん、こんにちは。フォーラムオペレーターのHarukaです。
ご返信いただきありがとうございます。

複数のプロバイダーを許可するには、次のようにコードを変更する必要があります。
sharedOptions.DefaultChallengeScheme = CookieAuthenticationDefaults.AuthenticationScheme;
また、AddAuthenticationの背後にある2番目のプロバイダー拡張メソッドをチェーンする必要があります。
https://docs.microsoft.com/ja-jp/aspnet/core/security/authentication/social/?view=aspnetcore-5.0&tabs=visual-studio
.AddWsFederation (options =>
       {
  // this is where your AppID URI goes
             options.Wtrealm = "<API key>";
             options.MetadataAddress = "<metadata>";
       }).AddWsFederation ( options=> ……..)

どうぞよろしくお願いいたします。

hadamard06 on Thu, 20 May 2021 11:37:51


Haruka様

ご回答ありがとうございます。
また、確認が遅くなり、申し訳ありません。

いただいた回答にて『AddAuthenticationの背後にある2番目のプロバイダー拡張メソッドをチェーンする』とのことですが、コードとしては、

.AddWsFederation(options =>
{
      options.Wtrealm = "<APIキー①>";
      options.MetadataAddress = "<メタデータ①>";
})
.AddWsFederation(options =>
{
      options.Wtrealm = "<APIキー②>";
      options.MetadataAddress = "<メタデータ②>";
})

のような形になろうかと思います。

私が質問させていただいたのは、ConfigureServices内で上記を指定したとして、Challengeメソッドの実行時に、指定している①と②のどちらを使うのかを、どうやって指定するのでしょうか?という内容でした。
例えば、「①で認証する」と「②で認証する」のボタンを画面に配置して、「①で認証する」をクリックした時は<APIキー①>、<メタデータ①>のIdPで認証したい、といったことを実現するには、どのようにすればよろしいでしょうか?

以上、よろしくお願いいたします。


Haruka6002 on Tue, 25 May 2021 07:58:24


hadamard06さん、こんにちは。フォーラムオペレーターのHarukaです。
ご返信いただきありがとうございます。

.netCoreの専門家ではありませんが、このリンクには、チャレンジメソッドの構成方法に関するいくつかの有用な情報が含まれていますので、ご参照いただければと思います。

どうぞよろしくお願いいたします。

hadamard06 on Thu, 27 May 2021 12:35:57


Haruka様

情報ありがとうございます。

紹介いただいたサイトにて、ConfigureServices内で

.AddWsFederation("名前①", options =>
{
      options.Wtrealm = "<APIキー①>";
      options.MetadataAddress = "<メタデータ①>";
})
.AddWsFederation("名前②", options =>
{
      options.Wtrealm = "<APIキー②>";
      options.MetadataAddress = "<メタデータ②>";
})

のように名称を指定し、Challengeメソッドの代わり new ChallengeResult() を使用することで、ConfigureServicesで指定した名前を指定できそうだということが分かりました。

ただし、実際に試してみると上記のように2つのIdPを指定した際に、1つ目に指定した方は期待通り認証できるのですが、2つ目に指定した方は期待通りの動作になりません。Azure ADの認証画面には遷移するのですが、認証後にアプリに戻ってきた際に、クレームを正しく受け取ることができていないようです。順序を入れ替えても1つ目に指定したものは期待通りに動作し、指定する順序で挙動が変わるようでした。

仕組みを正しく理解できていない部分はあるのですが、上記について、何かヒントになるようなことがありましたら、ご教授いただけますと幸いです。



Haruka6002 on Wed, 02 Jun 2021 01:38:35


hadamard06さん、こんにちは。フォーラムオペレーターのHarukaです。
ご返信いただきありがとうございます。

本件をエスカレーターしました。
返信をもらうまで時間がかかりますので、しばらくお待ちいただけますでしょうか。
確認ができ次第、また連絡いたします。

どうぞよろしくお願いいたします。