2025年12月28日日曜日

【Azure】App Serviceで「勝手にログアウトされる」謎の現象。Data Protectionの罠と解決策

 


「ローカルでは正常にログインできるのに、Azureに上げたらセッションが維持されない…」

「しばらく放置すると、すぐにログイン画面に戻されてしまう…」

もし、ASP.NET CoreなどのWebアプリをAzure App Service(特にLinux版)で動かしてこのような現象が起きたら、それはコードのバグではなく「Data Protection(データ保護)キーの永続化」が原因かもしれません。

今回は、中級者でも意外と見落としがちな、クラウド環境におけるセッション管理の急所について解説します。

1. 現象:なぜかセッションが維持されない

App ServiceにデプロイしたWebシステムで、以下のような不安定な挙動が発生することがあります。

• ログインして操作している最中に、突然ログアウトされる。

• アプリを再デプロイ(スロット切替含む)すると、全員強制ログアウトされる。

• インスタンスを2つ以上に増やす(スケールアウト)と、ログインがほぼ不可能になる。

これらはすべて、「認証Cookieを復号するための鍵(マスターキー)」が失われているサインです。

2. 原因:Azure App Serviceの「揮発性」

ASP.NET Coreなどは、デフォルトで「Data Protection(データ保護)」という仕組みを使い、ログイン情報を暗号化しています。この暗号化に使う「鍵」の保存先が問題です。

• ローカル環境: Windowsのレジストリやファイルシステムに鍵が半永久的に保存されます。

• App Service (Linux): デフォルトではコンテナ内のファイルシステムに保存されます。しかし、App Serviceは再起動やデプロイのたびに中身がリセットされる「揮発性」を持っています。

つまり、サーバーが再起動するたびに「鍵」が捨てられ、新しく作り直されてしまうのです。古い鍵で作られたCookieは、新しい鍵では解読できないため、システムは「不正なユーザー」とみなしてログアウトさせてしまいます。

3. 解決策:鍵の保存先を「外部」に固定する

この問題を解決するには、Azureのストレージサービスを使って、鍵をコンテナの外に逃がしてあげる必要があります。

もっとも一般的な方法は、Azure Blob Storage を鍵の保管庫にすることです。

実装のイメージ(Startup.cs / Program.cs)

public void ConfigureServices(IServiceCollection services)

{

    // Blob Storageに鍵を保存する設定を追加

    services.AddDataProtection()

        .PersistKeysToAzureBlobStorage(new Uri("<BlobのSASトークン付URI>"));

}


※実際には、Azure Key Vaultを使って鍵自体をさらに暗号化するのがベストプラクティスです。

4. 初学者が知っておくべき「クラウドの流法」

今回のトラブルの教訓は、「サーバーの中を信用してはいけない」ということです。

• サーバーはいつでも使い捨てられる(ステートレス)。

• 消えて困る情報(鍵、ファイル、セッション)は必ず外部サービス(Blob, Redis, DB)に預ける。

この「クラウドの作法」を知っているだけで、デバッグに費やす数時間を節約できます。

5. まとめ:知れば怖くないData Protection

私もWebシステムの経験がありましたが、Azure特有のこの挙動には驚かされました。しかし、一度仕組みを理解してしまえば、設定一つで解決できる問題です。

「なぜかログインが切れる」と悩んでいる初学者の方がいたら、まずはData Protectionの保存先を疑ってみてください。