次の方法で共有


ASP.NET Core Blazor WebAssembly .NET バンドルのキャッシュと整合性チェックの失敗

これは、この記事の最新バージョンではありません。 現在のリリースについては、 この記事の .NET 10 バージョンを参照してください。

警告

このバージョンの ASP.NET Core はサポート対象から除外されました。 詳細については、 .NET および .NET Core サポート ポリシーを参照してください。 現在のリリースについては、 この記事の .NET 10 バージョンを参照してください。

この記事では、 Blazor WebAssembly の資産キャッシュと、整合性エラーを診断して解決する方法について説明します。

Blazor WebAssembly アプリがブラウザーに読み込まれると、アプリはサーバーからブート リソースをダウンロードします。

  • アプリをブートストラップする JavaScript コード
  • .NET ランタイムとアセンブリ
  • ロケール固有のデータ

Blazorにインライン化されたdotnet.jsブート構成には、各ファイルのコンテンツのハッシュと共にダウンロードする必要があるアプリを構成するファイルのフィンガープリント マニフェストが含まれています。 アプリのファイルはプリロードされ、ブラウザーによってキャッシュされます。

† .NET 10 以降では、 blazor.boot.json マニフェスト ファイルが存在しなくなりました。 カスタム処理のためにマニフェスト ファイルに依存するアプリをアップグレードする場合は、ビルドから直接情報を収集することをお勧めします。

Blazor WebAssembly によってアプリのスタートアップ ファイルがダウンロードされると、応答に対して整合性チェックを実行するようにブラウザーに指示が出されます。 Blazor は、DLL (.dll)、WebAssembly (.wasm)、およびその他のファイルの SHA-256 ハッシュ値を送信します。 キャッシュされたファイルのファイル ハッシュは、ブート構成のハッシュと比較されます。 ダウンロードされたファイルの整合性チェックが失敗した場合、ブラウザーによってエラーが生成されます。

詳細については、「 基礎: 静的ファイル 」の記事の以下のセクションを参照してください。

Blazorのブート マニフェスト ファイル (blazor.boot.json) を除き、WebAssembly .NET ランタイム ファイルとアプリ バンドル ファイルはクライアントにキャッシュされます。 Blazorブート構成には、ダウンロードする必要があるアプリを構成するファイルのマニフェストと、ブート リソースのいずれかが変更されたかどうかを検出するために使用されるファイルのコンテンツのハッシュが含まれています。 Blazor は、ブラウザーの Cache API を使用してダウンロードしたファイルを キャッシュ します。

Blazor WebAssembly によってアプリのスタートアップ ファイルがダウンロードされると、応答に対して整合性チェックを実行するようにブラウザーに指示が出されます。 Blazor は、DLL (.dll)、WebAssembly (.wasm)、およびクライアントにキャッシュされない Blazor ブート構成内の他のファイルの SHA-256 ハッシュ値を送信します。 キャッシュされたファイルのファイル ハッシュは、 Blazor ブート構成のハッシュと比較されます。 キャッシュされたファイルのハッシュが一致する場合は、キャッシュされたファイルが Blazor で使われます。 それ以外の場合、サーバーのファイルが要求されます。 ファイルがダウンロードされた後、整合性の検証のためにそのハッシュが再度チェックされます。 ダウンロードされたファイルの整合性チェックが失敗した場合、ブラウザーによってエラーが生成されます。

ファイルの整合性を管理するための Blazor のアルゴリズム:

  • たとえば、ユーザーがアプリケーション ファイルをダウンロードしている間に、Web サーバーに新しい展開が適用された場合などに、アプリによって整合性のないファイルのセットが読み込まれるリスクがないことが保証されます。 ファイルに整合性がないと、アプリが誤動作する可能性があります。
  • ユーザーのブラウザーによって不整合のない応答や無効な応答がキャッシュされないことが保証されます。そのようなことがあると、ユーザーがページを手動で更新してもアプリを起動できなくなる可能性があります。
  • 応答をキャッシュし、想定される SHA-256 ハッシュ自体の変更までサーバー側の変更をチェックしなくても安全になるため、後続のページ読み込みに伴う要求の数が減り、速く完了するようになります。

想定される SHA-256 ハッシュに一致しない応答が Web サーバーから返された場合、ブラウザーの開発者コンソールに次の例のようなエラーが表示されます。

Failed to find a valid digest in the 'integrity' attribute for resource 'https://myapp.example.com/_framework/MyBlazorApp.dll' with computed SHA-256 integrity 'IIa70iwvmEg5WiDV17OpQ5eCztNYqL186J56852RpJY='. (計算された SHA-256 整合性 'IIa70iwvmEg5WiDV17OpQ5eCztNYqL186J56852RpJY=' を持つリソース 'https://myapp.example.com/_framework/MyBlazorApp.dll' の 'integrity' 属性に有効なダイジェストが見つかりませんでした。) The resource has been blocked. (リソースがブロックされています。)

ほとんどの場合、この警告は整合性チェックに関する問題を示していません。 代わりに、通常、警告は他の問題が存在することを意味します。

Blazor WebAssemblyのブート参照ソースについては、Boot.WebAssembly.ts GitHub リポジトリのdotnet/aspnetcore ファイルを参照してください。

通常、.NET 参照ソースへのドキュメント リンクを使用すると、リポジトリの既定のブランチが読み込まれます。このブランチは、.NET の次回リリースに向けて行われている現在の開発を表します。 特定のリリースのタグを選択するには、[ 分岐またはタグの切り替え ] ドロップダウン リストを使用します。 詳細については、「 ASP.NET Core ソース コード (dotnet/AspNetCore.Docs #26205) のバージョン タグを選択する方法」を参照してください。

整合性の問題を診断する

アプリがビルドされると、生成されたブート マニフェストは、ビルド出力が生成されたときのブート リソースの SHA-256 ハッシュを記述します。 ブート マニフェストの SHA-256 ハッシュがブラウザーに配信されたファイルと一致する限り、整合性チェックは合格します。

これが失敗する一般的な理由は次のとおりです。

  • Web サーバーの応答は、ブラウザーが要求したファイルではなく、エラー (たとえば、 404 - Not Found または 500 - Internal Server Error) です。 これはブラウザーによって、応答エラーとしてではなく整合性チェックの失敗として報告されます。
  • ファイルのビルドからブラウザーへの配信の間に、何らかによってファイルの内容が変更された場合。 次のような場合に発生します。
    • ユーザーまたはビルド ツールによって、ビルド出力が手動で変更された場合。
    • 展開プロセスの何らかの側面によってファイルが変更された場合。 たとえば、Git ベースの展開メカニズムを使用する場合は、Windows でファイルをコミットして Linux でチェックアウトすると、Git によって Windows スタイルの改行コードが Unix スタイルの改行コードに透過的に変換されることに注意してください。 ファイルの改行コードを変更すると、SHA-256 ハッシュが変更されます。 この問題を回避するには、.gitattributesを使用してビルド成果物をbinary ファイルとして扱うことを検討してください。
    • Web サーバーによるファイル提供の一環として、その内容が変更された場合。 たとえば、一部のコンテンツ配布ネットワーク (CDN) は HTML の 縮小 を自動的に試み、それによって HTML を変更します。 場合によっては、このような機能を無効にする必要があります。
  • ブート マニフェストが正しく読み込みに失敗するか、クライアントに正しくキャッシュされません。 一般的な原因は次のどちらかです。
    • 正しく構成されていないか、誤動作しているカスタム開発者コード。
    • 1 つ以上の正しく構成されていない中間キャッシュ レイヤー。

これらのうちどれが自分のケースに当てはまるか診断するには:

  1. エラー メッセージを確認し、エラーをトリガーしているファイルをメモします。
  2. ブラウザーの開発者ツールを開き、[ ネットワーク ] タブを確認します。必要に応じて、ページを再読み込みして、要求と応答の一覧を表示します。 その一覧でエラーをトリガーしているファイルを見つけます。
  3. 応答に含まれる HTTP 状態コードを確認します。 サーバーが 200 - OK (または別の 2xx 状態コード) 以外のものを返す場合は、診断するサーバー側の問題があります。 たとえば、状態コード 403 は承認に関する問題があることを意味しますが、状態コード 500 は、サーバーが未指定のエラーで失敗していることを意味します。 サーバー側のログを参照してアプリを診断し、修正してください。
  4. 状態コードが 200 - リソースに対して OK である場合は、ブラウザーの開発者ツールで応答コンテンツを確認し、コンテンツが予想されるデータと一致することを確認します。 たとえば、よくある問題は、他のファイルに対しても要求から index.html データが返されるように、ルーティングを誤って構成してしまうことです。 .wasm 要求への応答が WebAssembly であり、.dll 要求への応答が .NET アセンブリ バイナリであることを確認してください。 そうでない場合、サーバー側のルーティングに関する問題を診断する必要があります。
  1. エラー メッセージを確認し、エラーをトリガーしているファイルをメモします。
  2. ブラウザーの開発者ツールを開き、[ ネットワーク ] タブを確認します。必要に応じて、ページを再読み込みして、要求と応答の一覧を表示します。 その一覧でエラーをトリガーしているファイルを見つけます。
  3. 応答に含まれる HTTP 状態コードを確認します。 サーバーが 200 - OK (または別の 2xx 状態コード) 以外のものを返す場合は、診断するサーバー側の問題があります。 たとえば、状態コード 403 は承認に関する問題があることを意味しますが、状態コード 500 は、サーバーが未指定のエラーで失敗していることを意味します。 サーバー側のログを参照してアプリを診断し、修正してください。
  4. 状態コードが 200 - リソースに対して OK である場合は、ブラウザーの開発者ツールで応答コンテンツを確認し、コンテンツが予想されるデータと一致することを確認します。 たとえば、よくある問題は、他のファイルに対しても要求から index.html データが返されるように、ルーティングを誤って構成してしまうことです。 .wasm 要求への応答が WebAssembly であり、.dll 要求への応答が .NET アセンブリ バイナリであることを確認してください。 そうでない場合、サーバー側のルーティングに関する問題を診断する必要があります。
  5. 整合性のトラブルシューティング PowerShell スクリプトを使用して、アプリの発行およびデプロイされた出力を検証します。

サーバーから正しいと思われるデータが返されていることを確認した場合は、ファイルのビルドと配布の間で何か別の原因によって内容が変更されています。 これを調査するには:

  • ファイルがビルドされた後にファイルが変更される場合に備えて、ビルド ツールチェーンと展開メカニズムを調べます。 この例としては、前に説明したように、Git によってファイルの改行コードが変換される場合が挙げられます。
  • 応答を動的に変更する (たとえば、HTML を縮小しようとする) ように設定されている場合があるため、Web サーバーまたは CDN の構成を確認します。 Web サーバーに HTTP 圧縮が実装されていても問題ありません (たとえば content-encoding: brcontent-encoding: gzip が返される場合)。これは展開後の結果には影響しないためです。 ただし、Web サーバーが圧縮されていないデータを変更することは許されません。

整合性 PowerShell スクリプトのトラブルシューティング

integrity.ps1 PowerShell スクリプトを使用して、発行および展開された Blazor アプリを検証します。 このスクリプトは、アプリに Blazor フレームワークでは特定できない整合性の問題がある場合の出発点として PowerShell Core 7 以降向けに提供されています。 バージョン 7.2.0 より後のバージョンの PowerShell で実行する場合など、スクリプトのカスタマイズが必要になることがあります。

スクリプトを実行すると、publish フォルダー内のファイルと展開されたアプリからダウンロードしたファイルがチェックされ、整合性ハッシュを含むさまざまなマニフェストの問題が検出されます。 これらのチェックにより、最も一般的な問題が検出されます。

  • 発行された出力で、知らずにファイルを変更した。
  • アプリが展開ターゲットに正しく展開されなかった、または展開ターゲットの環境内で何かが変更された。
  • 展開されたアプリと、アプリの発行からの出力の間に違いがある。

PowerShell コマンド シェルで次のコマンドを使用してスクリプトを呼び出します。

.\integrity.ps1 {BASE URL} {PUBLISH OUTPUT FOLDER}

次の例では、https://localhost:5001/ のローカルで実行されているアプリでスクリプトが実行されています。

.\integrity.ps1 https://localhost:5001/ C:\TestApps\BlazorSample\bin\Release\net6.0\publish\

プレースホルダー:

  • {BASE URL}: 展開されたアプリの URL。 末尾のスラッシュ (/) が必要です。
  • {PUBLISH OUTPUT FOLDER}: アプリの publish フォルダー、またはアプリが展開のために発行される場所へのパス。

dotnet/AspNetCore.Docs GitHub リポジトリを複製すると、integrity.ps1 スクリプトが Bitdefender またはシステム上に存在する別のウイルス スキャナーによって検疫される可能性があります。 通常、ファイルはウイルス スキャナーの ヒューリスティック スキャン テクノロジによってトラップされます。これは、マルウェアの存在を示す可能性があるファイル内のパターンを探すだけです。 ウイルス検索プログラムによってファイルが検疫されないようにするには、リポジトリを複製する前に、ウイルス検索プログラムに例外を追加します。 次の例は、Windows システム上のスクリプトへの一般的なパスです。 他のシステムに必要なパスを調整します。 プレースホルダー {USER} はユーザーのパス セグメントです。

C:\Users\{USER}\Documents\GitHub\AspNetCore.Docs\aspnetcore\blazor\host-and-deploy\webassembly\_samples\integrity.ps1

警告: ウイルス スキャナーの例外の作成は危険であり、ファイルが安全であると確信している場合にのみ実行する必要があります。

ファイルのチェックサムを有効なチェックサム値と比較しても、ファイルの安全性は保証されませんが、悪意のあるユーザーにとってはチェックサム値を維持するようにファイルを変更するのは簡単ではありません。 そのため、チェックサムは一般的なセキュリティ アプローチとして役立ちます。 ローカル integrity.ps1 ファイルのチェックサムを次のいずれかの値と比較します。

  • SHA256: 32c24cb667d79a701135cb72f6bae490d81703323f61b8af2c7e5e5dc0f0c2bb
  • MD5: 9cee7d7ec86ee809a329b5406fbf21a8

次のコマンドを使用して Windows OS でファイルのチェックサムを取得します。 {PATH AND FILE NAME} プレースホルダーのパスとファイル名を指定し、{SHA512|MD5} プレースホルダーに対して生成するチェックサムの種類として、SHA256 または MD5 のいずれかを指定します。

CertUtil -hashfile {PATH AND FILE NAME} {SHA256|MD5}

チェックサムの検証が自身の環境では十分なセキュリティ確保にならないという懸念材料がある場合は、組織のセキュリティのリーダーシップに相談し、ガイダンスを得てください。

詳細については、「 Microsoft Defender ウイルス対策による脅威保護の概要」を参照してください。

非 PWA アプリの整合性チェックを無効にする

ほとんどの場合、整合性チェックを無効にしないでください。 整合性チェックを無効にしても、予期しない応答の原因となった根本的な問題は解決されず、前述の利点が失われる結果になります。

Web サーバーから一貫した応答が返されるとは限らないため、基になっている問題が解決されるまで、整合性チェックを一時的に無効にするしかないケースがあります。

整合性チェックを無効にするには、 クライアント側のブート リソースを手動で読み込みintegrity パラメーターを fetch 呼び出しに渡さないようにします。

整合性チェックを無効にするには、Blazor WebAssembly アプリのプロジェクト ファイル (.csproj) 内のプロパティ グループに次を追加します。

<BlazorCacheBootResources>false</BlazorCacheBootResources>

BlazorCacheBootResources により、SHA-256 ハッシュに基づいて Blazor、.dll、およびその他のファイルをキャッシュする .wasm の既定の動作も無効になります。このプロパティによって、SHA-256 ハッシュの正確性を信頼できないことが指定されるためです。 この設定を使用しても、ブラウザーの通常の HTTP キャッシュによってこれらのファイルがキャッシュされる可能性がありますが、このような状況が発生するかどうかは、Web サーバーの構成と、それによって提供される cache-control ヘッダーによって異なります。

BlazorCacheBootResources プロパティは、プログレッシブ Web アプリケーション (PWA) の整合性チェックを無効にしません。 PWA に関するガイダンスについては、「PWA の 整合性チェックを無効にする」 セクションを参照してください。

整合性チェックを無効にする必要があるシナリオの完全な一覧を提供することはできません。 サーバーは、Blazor フレームワークの範囲外の任意の方法で要求に応答できます。 このフレームワークでは、アプリが 提供できる整合性の保証を失う代償でアプリを実行できるようにする上記のアプローチを許可します。 ここでも、整合性チェックを無効にしないことをお勧めします (特に運用展開の場合)。 開発者は、整合性チェックが失敗する原因になっている、根本的な整合性の問題を解決する必要があります。

整合性の問題が発生する可能性があるいくつかの一般的なケースを次に示します。

  • 整合性をチェックできない HTTP での実行。
  • 展開プロセスによって、発行後のファイルに何らかの変更が加えられる場合。
  • ホストによってファイルに何らかの変更が行われる場合。

PWA の整合性チェックを無効にする

Blazor のプログレッシブ Web アプリケーション (PWA) テンプレートには、オフライン使用のためにアプリケーション ファイルをフェッチおよび格納するための推奨される service-worker.published.js ファイルが含まれています。 これは通常のアプリの起動メカニズムとは別のプロセスであり、独自の整合性チェック ロジックを備えています。

service-worker.published.js ファイル内に、次の行があります。

.map(asset => new Request(asset.url, { integrity: asset.hash }));

整合性チェックを無効にするには、行を次のように変更して integrity パラメーターを削除します。

.map(asset => new Request(asset.url));

ここでも、整合性チェックを無効にすることは、整合性チェックによって提供される安全性の保証が失われることを意味します。 たとえば、ユーザーのブラウザーでアプリをキャッシュしている瞬間に、新しいバージョンを展開した場合、古い展開から一部のファイルがキャッシュされ、新しい展開から別のファイルがキャッシュされるリスクがあります。 そのような場合、さらなる更新プログラムを展開するまで、アプリは破損した状態のままになります。