しばやん雑記

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

App Service Authentication (Easy Auth) と ASP.NET のフォーム認証を共存させつつ利用する

App Service Authentication と ASP.NET を組み合わせて使うと、自動的に Thread.CurrentPrincipal に App Service Authentication で認証したユーザー情報を格納してくれるので、アプリケーション側では Request.IsAuthenticatedUser.Identity でログイン状態やユーザーの情報を確認できて便利です。

ASP.NET 側で以下のようなコードを書くだけで、ログインユーザーの情報を表示できます。

<p>
  @if (Request.IsAuthenticated)
  {
    <text>Login user: </text><b>@User.Identity.Name</b>
  }
</p>

実際に App Service Authentication を有効化した App Service にデプロイしてアクセスすると、以下のように Azure AD でログイン中のユーザー情報が表示されます。

非常に便利なので、もし新規で ASP.NET アプリケーションをデプロイする場合、あるいは既存のアプリケーションの認証を App Service Authentication に移行する場合は、少ない手間で実現できるのでお勧めです。

しかし、既存のアプリケーションが ASP.NET のフォーム認証を利用している場合には少し話が変わってきます。何故なら App Service Authentication は ASP.NET の認証周りをオーバーライドすることで、認証したユーザー情報をセットしているからです。

例えば以下のような簡単な FormsAuthentication を利用するコードと設定を追加します。

public class AccountController : Controller
{
    // GET: Account
    public ActionResult Login()
    {
        FormsAuthentication.SetAuthCookie("shibayan", true);

        return RedirectToAction("Index", "Home");
    }
}
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.8" />
    <httpRuntime targetFramework="4.8" />
    <authentication mode="Forms" />
  </system.web>
</configuration>

この状態でフォーム認証でのログインを行っても、表示されるユーザー情報は以下のように App Service Authentication で認証されたものが表示され続けます。フォーム認証のクッキーは発行されていますが、それが使われているように見えません。

本番環境向けであれば 2 重に認証を有効化することはないので問題ないですが、ステージング環境など開発者のみ確認可能にしたい場合にはログイン画面すら見せたくないので App Service Authentication を使って App Service 全体を守る必要が出てきます。

そのような用途ではアプリケーション側にユーザー情報を渡す必要がそもそもないため、App Settings に WEBSITE_AUTH_DISABLE_IDENTITY_FLOW を追加することで回避可能です。

WEBSITE_AUTH_DISABLE_IDENTITY_FLOW の名前からは挙動が想像付きにくいですが、ASP.NET へのユーザー情報の反映を無効化する設定なので、以下のように App Settings で true を設定すれば良いです。

設定後に再度アクセスすると、App Service Authentication のユーザー情報ではなくフォーム認証のユーザー情報が表示されることが確認出来ます。

これでステージング環境などのアクセス制限をアプリの認証とは別に付けることが出来ました。

実際 App Service Authentication は Twitter / Facebook / Google といった B2C 向けのユーザー認証以外にも、Azure Active Directory を使って IP 制限のように限られたユーザーのみアクセスさせる用途にも使えるので、ステージング環境やスロットでは積極的に使っていきたい機能です。