ASP.NET Core Blazor WebAssembly .NET ランタイムとアプリ バンドルのキャッシュ

Note

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

重要

この情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。

現在のリリースについては、この記事の .NET 8 バージョンを参照してください。

Blazor WebAssembly アプリがブラウザーに読み込まれると、アプリによってサーバーから次のブート リソースがダウンロードされます。

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

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

Blazor WebAssembly によってアプリのスタートアップ ファイルがダウンロードされると、応答に対して整合性チェックを実行するようにブラウザーに指示が出されます。 Blazor は、は、DLL (.dll)、WebAssembly (.wasm)、blazor.boot.json ファイル内のその他のファイルの SHA-256 ハッシュ値を送信します。 キャッシュされたファイルのファイル ハッシュは、blazor.boot.json ファイル内のハッシュと比較されます。 キャッシュされたファイルのハッシュが一致する場合は、キャッシュされたファイルが 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. (リソースがブロックされています。)

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

Note

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

整合性に関する問題の診断

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

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

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

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

  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 フォルダー、またはアプリが展開のために発行される場所へのパス。

Note

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

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

<BlazorCacheBootResources>false</BlazorCacheBootResources>

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

Note

BlazorCacheBootResources プロパティによってプログレッシブ Web アプリケーション (PWA) の整合性チェックが無効になることはありません。 PWA に関連するガイダンスについては、「PWA の整合性チェックを無効にする」セクションをご覧ください。

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

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

  • 整合性をチェックできない 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));

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

その他のリソース

ブート リソースの読み込み