こんにちは。先日娘が「タカラトミーの提供でお送りします。アンパンマンはご覧のスポンサーでお送りします」と言っていて色んなことを覚えてるなと感心した木村です。
AppServiceの前段にFrontDoorを置き、AppServiceへの直接アクセスを制限するというのはよくある構成ですが、この構成でAppServiceにEasyAuthでの認証を組み込むとうまく動きません。その解決方法を今日は書こうと思います。
FrontDoor + AppServiceの環境を準備する
まずはFrontDoorとAppServiceを準備します。
AppServiceは今回OSはLinux、ランタイムは.NET6とし、.NET6のWebアプリのテンプレートで作成したアプリをそのままデプロイしました。手順は省略しますが、以下のような画面が表示されます。アドレスバーを見ると、URLがhttps://appserviceのリソース名.azurewebsites.net
とAppServiceのドメイン名になっていることが分かります。
次に、FrontDoorを作ります。これまた手順は省略しますが、メニューの「フロントドアマネージャ」からエンドポイントと配信元グループを追加し、全てのアクセスをAppServiceに向けるようにします。
ルートの設定はこんな感じです。
配信元グループの設定はこんな感じです。配信元に先ほど作成したAppServiceを選んだだけで、他はデフォルトのままです。
あとはこのエンドポイントのURLにアクセスしてみましょう。フロントドアマネージャの画面から、エンドポイントのURLをコピーして貼り付けます。
先ほどと同じ画面が表示されれば成功です。アドレスバーのURLがhttps://エンドポイントの名前.azurefd.net
と、FrontDoorのドメイン名になっていることが分かります。
また、AppServiceへのアクセスをFrontDoor経由だけにしておきましょう。設定はAppServiceの「ネットワーク」から「アクセス制限」を追加します。ソースの種類にサービスタグ「Azure.FrontDoor.Backend」を選び、「X-Azure-FDID」にフロントドアIDを入れてやります。詳細な手順は以下の公式ドキュメントを参照してください。
余談ですが、2022年4月にFrontDoorはGAしたのですが、ポータルでの設定画面がだいぶ変わっていてちょっとビックリしました。
EasyAuthを設定する
これでFrontDoorからのみアクセスできるAppServiceができました。次はこれにEasyAuthを仕掛けましょう。今回はAzureADでの認証を追加します。手順については以下の公式ドキュメントを参照してください。
アクセスしてみる
これでEasyAuthも設定できました。さっそくhttps://エンドポイントの名前.azurefd.net
にアクセスしてみましょう。
AzureAD認証のページに無事リダイレクトされました(弊社では認証ページをカスタムしてるのでロゴが表示されています)。では、認証してみます。
初回は上記のようにアクセス許可を求める画面が出ますので「承諾」を押します。
・・・おっと、エラーになりました。アドレスバーを見るとhttps://appserviceのリソース名.azurewebsites.net/.auth/login/aad/callback
となっています。これは、AzureADで認証した後にリダイレクトされる先がAppServiceのURLになってしまっていて(本当はFrontDoorのURLに戻ってきて欲しい)、現在AppServiceはFrontDoorからのアクセス以外を許可していないからです。
実際、最初にリダイレクトされたAzureADのURLを見てみると
https://login.microsoftonline.com/*****/oauth2/v2.0/authorize?response_type=code+id_token&redirect_uri=https%3A%2F%2Fappserviceのリソース名.azurewebsites.net%2F.auth%2Flogin%2Faad%2Fcallback.....
と、redirect_uri
オプションがAppServiceのURLを向いてしまっています。
EasyAuthでは「認証したらアプリケーション自身のドメイン名のURLに戻ってくるように」とredirect_uri
を設定してAzureADの認証画面にリダイレクトするわけですが、この時にAppServiceは標準の状態だと自分自身のホスト名はappserviceのリソース名.azurewebsites.net
だと認識しているからこのような動作になるわけです。
そこで、どうにかしてFrontDoorからアクセスした場合には、AppServiceに「FrontDoorのドメイン名」を自分自身のドメイン名だと認識させてやる必要があります。
解決方法1:カスタムドメインを設定する
1つの解決方法は、FrontDoorとAppServiceの両方に同じカスタムドメインを付けてやるという方法です。この時、手順としてはまずAppServiceにカスタムドメインを設定し、その後にFrontDoorに設定し、カスタムドメインのDNSの設定をFrontDoorに向けるという順番で行います。
詳細な手順は以下の公式ドキュメントを参考にしてください。
しかし、この方法を使うためには自由になるドメインが必要なのと、カスタムドメインを使うためにはAppServiceはB1プラン以上が必要ということもあり、開発段階で使うにはちょっと費用がかかります。そこで今回はもう1つの方法を紹介します。
解決方法2:AppServiceのproxy設定を変更する
今回紹介するのは、AppServiceのproxy設定を変更するという方法です。「自身の前段にリバースプロキシーがいるから、そこから渡されたリバースプロキシーのドメイン名を自分自身のドメイン名だと思いなさい」とAppServiceに教えてあげる感じですね。
こちら、2022年4月21日現在はポータルからは設定を変更できないので、リソースエクスプローラーで設定をします。
リソースエクスプローラーにアクセスし、AppServiceの設定を確認します。「subscriptions」→「resourceGroups」の順に該当のサブスクリプション名とリソースグループ名を選択し、その下の「providers」で「Microsoft.Web」を開きます。その下の「sites」の中に、該当のAppServiceの名前が見つかるので、その下の「config」→「authsettinsVs」を開きます。また、設定を変更するので画面上部の「ReadWrite」を押して権限を変更し、「Edit」ボタンを押してください。
この中に、forwardProxy
という設定があります。デフォルトでは以下のように"convention":"NoProxy"
となっているかと思いますが、これを"convention":"Standard"
という値に変更します。
変更したら、画面上部で「PUT」ボタンを押します。
設定が反映されるのに数分程度かかることがあるので、しばらく待って再度アクセスしてみます。
おっと、別のエラーが出ました。これはFrontDoorのURLがredirect_uri
に指定されているが、そのuriがAzureADアプリケーションでリダイレクト先として許可されていないためにエラーになっています。
redirect_uri
には正しくFrontDoorのURLが渡るところまで来ました。ここまで来れば後もう少しです。
AppServiceの「認証」メニューから、AzureADアプリケーションにアクセスします。
AzureADアプリケーションの、「認証」メニューで「Web」の「リダイレクトURI」の部分にhttps://appserviceのリソース名.azurewebsites.net/.auth/login/aad/callback
というURIが入っているかと思います。これをhttps://エンドポイントの名前.azurefd.net/.auth/login/aad/callback
に変更(またはURIを追加する)し、「保存」を押します。
では、アクセスしてみましょう。
うまくいきましたね!
まとめ
今回はAppServiceの前段にFrontDoorを置いた構成でEasyAuthを設定するとうまく動かないという事象を解決してみました。
なお、前段に置くのがFrontDoorではなくApplication Gatewayも同様の設定で解決可能です。Applicaiton Gatewayの場合の詳細は以下を参考にしてください。
皆様のお役に立てば幸いです。