WPF on .NET Core + Azure AD B2C でカスタム Web UI を使って認証したい


2020/04/17 現在 MSAL.NET を使って WPF on .NET Core を使うとシステムブラウザーでの認証になります。さらに、リダイレクト URL で http://localhost:ポート番号 のように、空いてるポートを自分でみつけないといけないみたいです。

B2C and ADFS 2019 do not yet implement the "any port" option. 
So you cannot set "http://localhost" (no port) redirect uri, 
but only "http://localhost:1234" (with port) uri.

回避方法としては、実装がされるのを待つか、とりあえず自前でカスタム Web UI の機能を使ってシステム ブラウザーではなく、自前のブラウザーをホストした Window を出すようにするかになります。自前のブラウザーを使う場合は旧 Edge か新 Edgeか、WPF が持ってる IE ベースの WebBrowser コントロールになります。

旧 Edge の WebView は、新 Edge が WebView が出たら置き換えた方がいいものなのすが、いかんせん、まだ開発者プレビューの段階にあります。

とりあえず、ここでは簡単に WPF 組込の IE がベースの WebBrowser コントロールを使ってみたいと思います。

作った

ということで、WPF の WebBrowser コントロールを使ってカスタム Web UI 作ってみました。

簡単に試せるように NuGet にしてます。

ということで、Azure AD B2C に適当なアプリを作成して、ネイティブのパブリックアプリケーションを追加します。

Azure AD B2C にアプリを登録して、以下のように設定しました。API のアクセス許可で適当な API へのアクセス許可も与えておきます。(これしないとアクセストークンが返ってこない)

IPublicClientApplication は MSAL.NET を普通に使うときと同じで、AcquireTokenInteractive をするところで、WithCustomWebUi に EmbeddedBrowserWebUi のインスタンスを渡します。

var r = await App.Current
    .PublicClientApplication
    .AcquireTokenInteractive(new[]
    {
        "https://xxx.onmicrosoft.com/xxxxxx-xxxx-xxx-xxx-xxxxx/xxx" // スコープ
    })
    .WithCustomWebUi(new EmbeddedBrowserWebUi(this)) // ここでカスタム UI を設定
    .ExecuteAsync();

EmbeddedBrowserWebUi のコンストラクターには、親となる Window のインスタンスを渡します。
ここら辺は、リポジトリー内の TestApp プロジェクトの MainWindow.xaml.cs あたりを見てください。

以下のような感じで動きます。

まとめ

そのうち新 Edge を使ったものがリリースされると思うので、リリースされたらそちらに乗り換えるとして、とりあえずアプリ内ブラウザーでログインダイアログを出したい場合は、こんな感じで実装すればいいのではないだろうかという所ですね。