Azure AD B2C サインインでロゴが表示されない|MSAL.NET・組み込みWebViewの不具合と対処(2024年4月発生・修正済み)

2024年4月中旬、Azure AD B2C のサインイン画面で「ロゴや背景画像だけが表示されない」現象が、MSAL.NET を使う Windows/モバイルなどの .NET クライアントで同時多発的に報告されました。現在は Microsoft により修正済みですが、再発時の切り分けや運用上のベストプラクティスをまとめ、現場でそのまま使えるチェックリストやサンプルコードまで網羅的に解説します。

目次

現象のポイント(要約)

  • Angular 等のブラウザベースのポータルではロゴ・背景画像が正常表示。
  • MSAL.NET を用いた .NET クライアント(Windows, Xamarin/MAUI, 一部モバイルの組み込み WebView 経路など)では、ブランディングの色は反映されるが画像のみ消える。
  • 発生は 2024‑04‑11〜12 ごろに複数テナント(開発・本番)で同時多発。
  • .NET クライアントは組み込み WebView を使うため、F12 開発者ツールでの DOM/ネットワーク検証が難しい。
  • 根本原因は Azure AD B2C 側の不具合で、2024‑04‑27 に Microsoft が「修正(mitigated)」と公表。基本的に再ログインで回復。

症状の詳細と影響範囲

以下は、当時の典型的な再現パターンです。色(背景色・アクセントカラー)は反映される一方、会社ロゴ・背景画像だけが読み込まれない点が共通していました。

クライアント/経路ロゴ背景画像色(テーマ)備考
Angular Web(ブラウザ)表示表示反映ブラウザの開発者ツールで検証可
.NET(MSAL.NET)組み込み WebView非表示非表示反映DOM/ネットワーク検証が難しい
.NET(システムブラウザ/WAM)概ね表示概ね表示反映環境差あり。切替で回避できる場合あり

発生日とタイムライン

日付出来事
2024‑04‑11〜12.NET クライアント限定でロゴ・背景画像が表示されない事象が複数テナントで同時多発
2024‑04‑27Microsoft が Azure AD B2C のバグを修正(mitigated)と公表

回答・解決策(結論)

種別内容
根本原因Microsoft 側の Azure AD B2C の不具合。サーバー側の変更の影響で、組み込み WebView を経由する一部の .NET クライアントのみロゴ・背景画像が取得されない状態になっていた。
現在の対処既に修正済み。再度サインインをやり直すだけで画像が表示されるのが基本挙動。まだ再現する場合は以下のチェックリストを順に確認。
再発時のチェックリスト1. サインイン アカウントの種類:Microsoft アカウントではなく Entra ID(旧 Azure AD)アカウントで試す。
2. 会社ブランディング設定:Azure ポータル →「会社ブランディング」で画像が正しくアップロード済みか、URL が有効かを確認。
3. ネットワーク制限:組織のファイアウォール/プロキシで *.b2clogin.com 上の画像取得がブロックされていないか確認。
4. キャッシュの影響:シークレット(InPrivate)ウィンドウでポータルを開き、ロゴが読み込まれるか比較。
5. 公式サポート:解消しない場合は Microsoft サポートにチケットを起票し、テナント設定の詳細調査を依頼。
参考情報同時期に起きた事象の共通点は「画像だけが抜ける」。設定変更やコード修正は不要で、条件として「.NET の組み込み WebView でのみ」「Angular Web では正常」が判明していた。

.NET クライアント特有の切り分けポイント

ブラウザに比べ、.NET アプリ内の組み込み WebView はデバッグ手段が限られます。現場で素早く判定するため、以下の順序で切り分けするのが有効です。

  1. 同一テナントをブラウザで確認:Angular などの Web ポータルでロゴ・背景画像の URL/HTTP ステータスを確認(200 応答か、画像サイズ・形式に異常がないか)。
  2. 組み込み WebView ↔ システムブラウザの切替:MSAL.NET の WithUseEmbeddedWebView(true/false) を切り替えて挙動差を見る(後述のサンプルコード参照)。
  3. MSAL ログの採取:PII 非表示でログレベルを上げ、B2C ページロードや遷移の成否を把握(本番では PII ログは収集しない運用を徹底)。
  4. ネットワークの透過性確認:プロキシ越しでも *.b2clogin.com と画像 CDN が取得できるかをパケット/フィルタログで確認。TLS インスペクション対象外の例外設定も検討。
  5. キャッシュ/セッションの影響排除:ユーザープロファイルの切替やゲスト/一時プロファイルでの再現性を確認。WebView2 のユーザーデータを分離する(アプリ側でユーザーデータフォルダを専用に設定するなど)。

MSAL.NET(Windows/デスクトップ)サンプル

以下は、組み込み WebView を使う場合と使わない場合を即座に切り替えられる最小構成の例です。これにより、現象が「WebView 経路依存なのか」「アプリ/環境に閉じた問題なのか」を素早く見極められます。

// MSAL.NET (Microsoft.Identity.Client)
// WinForms/WPF 等のデスクトップ想定

using Microsoft.Identity.Client;
using System;
using System.Threading.Tasks;

public class AuthSample
{
// B2C 固有の設定(例)
private const string ClientId = "YOUR_CLIENT_ID";
private const string AuthoritySignIn = "[https://YOUR_TENANT.b2clogin.com/YOUR_TENANT.onmicrosoft.com/B2C_1A_SIGNIN](https://YOUR_TENANT.b2clogin.com/YOUR_TENANT.onmicrosoft.com/B2C_1A_SIGNIN)";
private static readonly string[] Scopes = new[] { "[https://YOUR_TENANT.onmicrosoft.com/api/demo.read](https://YOUR_TENANT.onmicrosoft.com/api/demo.read)" };
private readonly IPublicClientApplication _pca;

public AuthSample()
{
    _pca = PublicClientApplicationBuilder
        .Create(ClientId)
        .WithB2CAuthority(AuthoritySignIn)
        .WithRedirectUri("http://localhost") // デスクトップ既定のループバック
        .Build();
}

public async Task<AuthenticationResult> SignInAsync(bool useEmbeddedWebView)
{
    var builder = _pca.AcquireTokenInteractive(Scopes)
        .WithPrompt(Prompt.SelectAccount);

    if (useEmbeddedWebView)
    {
        builder = builder.WithUseEmbeddedWebView(true);
        // WebView2 を前提にする場合、必要に応じて EmbeddedWebViewOptions を指定
        // builder = builder.WithEmbeddedWebViewOptions(new EmbeddedWebViewOptions());
    }
    else
    {
        builder = builder.WithUseEmbeddedWebView(false);
        // Windows なら WAM(Web Account Manager)/ システムブラウザ経路が利用される場合あり
    }

    // 親ウィンドウハンドルが取得できる環境なら指定推奨
    // builder = builder.WithParentActivityOrWindow(new WindowInteropHelper(Application.Current.MainWindow).Handle);

    return await builder.ExecuteAsync().ConfigureAwait(false);
}

} 

実務ヒント:上記 useEmbeddedWebView を切り替えて比較するだけで、.NET クライアント限定の表示崩れかどうかを高精度に判別できます。問題が埋め込み経路に偏在するなら、暫定回避として「システムブラウザ/WAM 経路に寄せる」方針も検討できます。

.NET MAUI / Xamarin(モバイル)の観点

  • iOS/Android では OS 提供の認証セッション(ASWebAuthenticationSession 等)を経由する構成が一般的です。組み込み WebView を強制しないほうが、セキュリティ・サインイン継続性の観点で推奨されます。
  • MSAL の カスタム Web UI を使うと一部経路を調整できますが、基本は OS 標準経路の利用を優先してください。
  • ブラウザアプリや OS のアップデート差分で挙動が変わるため、端末 OS バージョン × アプリ経路 × B2C ポリシーの組み合わせテストを回す体制を整備しておくと安心です。

会社ブランディング設定の健全性チェック

B2C 側のバグが解消した現在も、画像が表示されないケースは「コンテンツ側の品質」に起因することがあります。再発時は次の観点で見直してください。

  • 画像形式/容量:PNG/JPEG を基本に、数百 KB 程度を目安(極端に大きい画像や透過・メタ情報過多は失敗要因)。
  • 解像度:ロゴは横長の高精細画像を、背景はフル HD クラス以上のアスペクト比を意識。
  • CDN/配信安定性:自社 CDN を使う場合は、cache-control・有効期限・リダイレクトの有無などを点検。
  • HTTPS と証明書:自己署名・古い暗号スイートは不可。チェーン欠落や失効は画像取得失敗の温床です。
  • パス/ファイル名:空白や日本語文字、クエリストリング依存の動的 URL は避け、シンプルなパス設計に。

ネットワーク/セキュリティ設定の確認

企業ネットワークでは、プロキシや TLS インスペクションにより画像リソースのみブロックされる事例もあります。以下を順に確認します。

  1. ドメイン許可リスト:*.b2clogin.com および B2C が参照する静的リソースの配信元を許可。
  2. 大容量応答の扱い:画像のみサイズ上限で切られていないか、プロキシのポリシーを点検。
  3. TLS インスペクション例外:認証系ドメインは復号対象外にする運用が推奨。
  4. IPv6/DoH の影響:クライアントとプロキシの名前解決経路が分断されると取得失敗が発生することがあります。

キャッシュ/セッションの影響を排除する

  • 匿名ウィンドウでの再テスト:InPrivate/シークレットでの挙動をまず比較。
  • WebView2 のユーザーデータ分離:アプリ側でユーザーデータフォルダを専用化し、テスト用に消去できる導線を用意。
  • トークンキャッシュの整理:MSAL の永続化層を使っている場合は、検証セッションでは空の状態から再実行。

将来に向けた堅牢化戦略

カスタムポリシーでの独自ホスティング

Identity Experience Framework(IEF)のカスタムポリシーを用いれば、独自ホスティングした HTML/CSS/画像を使ってサインイン UI を柔軟に制御できます。これにより、プラットフォーム側 UI の変更や一時的な不具合の影響を最小化できます。

  • 画像は自社 CDN に配置し、ステージング/本番で明確に切替。
  • 外形監視(合成トランザクション)で UI の重要要素(ロゴ/背景)の有無を巡回チェック。
  • 障害時は即座に最低限のシンプルテンプレートにフェイルバックできる運用を準備。

WebView2(Edge ベース)への移行

Windows デスクトップでは WebView2 採用が主流です。開発中は DevTools を活用した HTML/スタイル検証が容易になり、画像のネットワークエラーの追跡も短時間で可能になります。

運用ベストプラクティスとチェックリスト

観点実施内容頻度/タイミング
監視テナントごとにサインイン UI の合成モニタリング(ロゴの存在・画像応答コード)5〜15 分間隔
リリース管理MSAL/ランタイム更新時は「埋め込み/システム」双方の認証経路を回帰試験毎リリース
セキュリティプロキシ/TLS インスペクション例外の棚卸し、証明書失効監視四半期
資産管理会社ブランディング画像の原本・サイズ・更新履歴を中央管理随時
訓練サインイン障害の標準化 Runbook(本記事のフロー)をチーム教育半期

よくある質問(FAQ)

Q. いまもコード修正は必要ですか? A. 原因が B2C 側の不具合だったため、基本的には不要です。再ログインで正常化します。再発時は本記事のチェックリストを順に確認してください。

<dt>Q. なぜ .NET の組み込み WebView だけで起きたのですか?</dt>
<dd>A. 画像配信の経路やページ読み込み条件がブラウザと異なるためです。2024 年 4 月の事象は B2C 側の変更が特定経路に影響したもので、ブラウザでは再現しませんでした。</dd>

<dt>Q. システムブラウザを強制すると改善しますか?</dt>
<dd>A. 当時は改善する報告が多く、暫定回避として有効でした。恒久対策としては、WebView2 やカスタムポリシーの活用、監視強化が推奨です。</dd>

<dt>Q. 画像の必須要件はありますか?</dt>
<dd>A. PNG/JPEG を推奨し、サイズは数百 KB 程度、シンプルなファイル名・ HTTPS 提供・有効な証明書を守ると安定します。</dd>

まとめ(実務で使える短縮版)

  • 事象:.NET 組み込み WebView 経路でロゴ/背景画像のみが消える(色は反映)。
  • 原因:Azure AD B2C 側の不具合。2024‑04‑27 修正済み。
  • まずやること:再サインイン。改善しなければ「アカウント種別」「会社ブランディング」「ネットワーク」「キャッシュ」「サポート」を順に確認。
  • 将来対策:カスタムポリシーでの独自ホスティング、WebView2 への移行、監視・回帰試験の自動化。

付録:B2C サインインの健全性を可視化する KQL 例

Log Analytics / Entra サインインログに取り込んでいる場合、ユーザーフロー単位でエラー傾向や UI 表示の遷移成否を概観できます(環境に応じて列名は調整)。

// 直近 7 日の B2C サインイン(ユーザーフロー名で集計)
SigninLogs
| where TimeGenerated >= ago(7d)
| where AppDisplayName has "B2C"
| summarize count() by ResultType, ResultDescription, UserFlow = tostring(AdditionalDetails["UserFlow"])
| order by count_ desc

// 画像読み込みに影響しそうなクライアント/OS を俯瞰
SigninLogs
| where TimeGenerated >= ago(7d)
| project TimeGenerated, UserPrincipalName, AppDisplayName, ClientAppUsed, OperatingSystem, Browser
| summarize dcount(UserPrincipalName) by ClientAppUsed, OperatingSystem, Browser
| order by dcount_UserPrincipalName desc 

付録:検証チェックリスト(コピペ運用可)

項目手順判定
ブラウザ正常性Angular ポータルでロゴ・背景画像・色の反映を確認(F12 で画像 URL/HTTP ステータス)OK / NG
組み込み/システム切替MSAL.NET の WithUseEmbeddedWebView を切替し挙動比較OK / NG
アカウント種別Entra ID アカウントでサインイン(Microsoft アカウントではないこと)OK / NG
会社ブランディング画像形式/容量/HTTPS/有効証明書・URL 生存を確認OK / NG
ネットワーク*.b2clogin.com と画像 CDN の許可・TLS 例外・サイズ上限を確認OK / NG
キャッシュInPrivate/別プロファイル/分離ユーザーデータで再テストOK / NG
ログPII なしで MSAL ログ収集、遷移の成功/失敗を時系列で把握OK / NG
サポート未解決なら Microsoft サポートにテナント情報を添えて依頼OK / NG

実装補足:MSAL ログの取り方(PII 無効)

// ログは検証環境でのみ詳細化し、本番では PII を無効化する
_pca = PublicClientApplicationBuilder
    .Create(ClientId)
    .WithB2CAuthority(AuthoritySignIn)
    .WithRedirectUri("http://localhost")
    .WithLogging((level, message, pii) =&gt; {
        // ここでファイル/Telemetry に出力。pii は false のみ記録。
        if (!pii)
        {
            System.Diagnostics.Debug.WriteLine($"[{level}] {message}");
        }
    },
    LogLevel.Verbose, enablePiiLogging: false, enableDefaultPlatformLogging: true)
    .Build();

実装補足:ユーザーデータの分離(WebView2)

テスト時に再現性を高めるには、WebView2 ユーザーデータを分離するのが有効です。MSAL 組み込み WebView をそのまま使う場合は制約もありますが、アプリの WebView2 ホスト側でユーザーデータフォルダをテスト用に切り替えると、キャッシュ影響を排除できます。

最後に

今回の事象はサーバー側の不具合であり、基本的にアプリ側の修正は不要でした。ただし再発や類似事象に迅速に対応するには、「ブラウザでの先行検証」→「埋め込み/システム切替」→「ネットワーク/キャッシュ/画像品質の確認」という標準フローをチームで共有しておくことが肝要です。あわせて、カスタムポリシーによる独自ホスティングや WebView2 への移行、監視と回帰試験の自動化を進め、UI 健全性を継続的に担保しましょう。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次