しばやん雑記

Azure Serverless とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure Static Web Apps と Front Door の組み合わせが正式にサポートされたので試した

少し前に App Service Authentication と Front Door や Application Gateway を組み合わせた時の問題と解決法を書きましたが、ほぼ同じアーキテクチャの Static Web Apps では当時は回避方法が無く利用困難でした。

Static Web Apps はグローバルに分散されて配信されますが、CDN ではないので Front Door を入れてさらに高度なルーティングとキャッシュを行いたくなることは多いです。

当然ながら非常に困る挙動なので GitHub に Issue を作成していたのですが、先日対応完了したというコメントを貰ったので再度検証することにしました。

まずは適当に Static Web App を Standard で作成して、カスタム認証として Azure AD B2C を設定したアプリケーションを GitHub 経由でデプロイしていきます。

その後 Front Door Standard を作成して、ログインを行った結果が以下になります。

f:id:shiba-yan:20211002223153p:plain

f:id:shiba-yan:20211002223200p:plain

まだ設定を入れていないので、これまで通りリダイレクト URL が Static Web App のものになってしまい、Azure AD B2C 側でミスマッチエラーが出ていることが分かります。

ここからが新しい話になります。この問題は Static Web App が X-Forwarded-Host を正しく扱ってくれないことが原因でしたが、最近のアップデートで staticwebapp.config.jsonforwardingGateway プロパティが追加されました。ドキュメントも更新されています。

今回 allowedForwardedHosts に配列で許可するホスト名を設定すれば、X-Forwarded-Host の値が使われるようになりました。今回の例では Front Door のホスト名を指定すれば良いので以下のようになります。

{
  "$schema": "https://json.schemastore.org/staticwebapp.config.json",
  "forwardingGateway": {
    "allowedForwardedHosts": [
      "afd-swa.z01.azurefd.net"
    ]
  }
}

この設定を使って再度デプロイを行って、Front Door 経由でログインを行うと今度はリダイレクト URL が Static Web App ではなく Front Door のままになっていることが確認できます。もちろん Azure AD B2C のログイン画面も正しく表示されるようになりました。

f:id:shiba-yan:20211002223734p:plain

App Service の場合は X-Forwarded-Host の値を無条件で受け入れるものでしたが、Static Web App は許可制になったという点だけ注意したいですね。

今回のアップデートに伴って Static Web App の前に Front Door を置く方法が正式にサポートされたようで、関連するドキュメントも追加されるようになりました。若干書きかけ感はありますが、今回の肝は forwardingGateway の設定だけなので難しいことはありません。

ほぼチュートリアル通りにはなりますが、以下が Front Door 向けに networkingforwardingGateway を追加した設定になります。auth は長くなるので省略していますが、必要に応じて追加してください。

ひっそりと allowedIpRanges に名前に反して IP アドレス以外に Service Tag を指定できるようになっているので、App Service と同様に AzureFrontDoor.Backend を指定することで、アクセス元を Front Door に制限することができます。これで Static Web App にインターネットから直接アクセスは出来なくなります。

{
  "$schema": "https://json.schemastore.org/staticwebapp.config.json",
  "networking": {
    "allowedIpRanges": [
      "AzureFrontDoor.Backend"
    ]
  },
  "forwardingGateway": {
    "allowedForwardedHosts": [
      "afd-swa.z01.azurefd.net"
    ],
    "requiredHeaders": {
      "X-Azure-FDID": "00000000-0000-0000-0000-000000000000"
    }
  }
}

今回 forwardingGateway に追加された requiredHeaders を使うと必須ヘッダーとしてヘッダー名と値を定義できるので、これで App Service と同じように X-Azure-FDID と Front Door ID を指定すれば、特定の Front Door からのアクセスのみに限定できます。

この辺りは Front Door と App Service での組み合わせ時にも書いているので、そっちを参照してください。

設定を追加してデプロイすると、Front Door 経由以外はアクセス出来なくなったことが確認できます。直接 Static Web App にアクセスしようとすると 403 が返ってくるようになっています。

f:id:shiba-yan:20211002224333p:plain

Service Tag と Front Door ID を組み合わせた方法が許容されないような場合には、Front Door Premium を利用すると Private Endpoint 経由でのアクセスに限定できるので、よりセキュアにできます。

Private Endpoint を使った方法に興味がある方は以前のエントリを参照してください。Private Endpoint を使う場合にも allowedForwardedHosts の設定だけは必要になるので注意してください。

カスタムドメインを設定する場合は Static Web App 側に追加するのではなく、Front Door に対してカスタムドメインを追加して allowedForwardedHosts にホスト名を指定する形になります。

この辺り勘違いされやすい部分ですが、今回のアップデートによって Static Web App にカスタムドメインを追加する必要は完全に無くなったので、デフォルトのドメインと HTTPS のままで問題ありません。