Visual Studio 2017 による ASP.NET Core MVC の Azure Active Directory 認証の構成

# ASP.NET Core MVC でサポートされる認証方式について

以前の投稿 [Visual Studio 2017 による ASP.NET Core MVC 開発](http://qiita.com/hiromasa-masuda/items/5b9ff175aac3d1ef6ca6) では、"ASP.NET Core Web アプリケーション" のプロジェクト テンプレートを利用して、ASP.NET Core MVC アプリケーションを作成しました。

今回は、Web アプリケーションに必ず必要となる要件の一つである認証、認可の実現方法についてです。
少々昔すぎるかもしれませんが、ASP.NET では、以下の認証がサポートされていると説明されていました。

- Windows 認証
- フォーム認証
- Passport 認証

ASP.NET MVC では、メンバーシップ プロバイダーにより、既存の用意された認証方式を利用したり、独自の認証方式を実装したりしました。
さらに、ASP.NET MVC 4 以降では、[ASP.NET Identity](https://docs.microsoft.com/en-us/aspnet/identity/overview/getting-started/introduction-to-aspnet-identity) が採用され、ASP.NET Core MVC でも同様の仕組みがサポートされています。

プロジェクト作成時に認証の種類毎にコードを出力できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/07c15bcc-268f-bbc7-8b5e-e1cb356c7871.png)

- 個別のユーザー アカウント: SQL Server にユーザー アカウント プロファイルを作成します。その他 Facebook, Twitter, Google, Microsoft アカウントで認証する場合もこちらを選択します。
- 職場または学校アカウント: Active Directory, Azure Active Directory により認証を行う場合は、こちらを選択します。 
- Windows 認証: Windows 認証を選択する場合は、こちらを選択します。

今回は、認証に Azure Active Directory を利用した認証方法の実装を行いたいと考えています。


# Azure Active Directory の作成

Azure Active Directory の認証を構成するには、Azure 環境が必要です。
Azure アカウントをお持ちでない場合は、以下から、無料で Azure アカウントを作成できます。

- [無料の Azure アカウントを作成](https://azure.microsoft.com/ja-jp/free/)

アカウント作成時にクレジット カードが必要となりますが、有償のサービスを利用しなければ課金されることはありません。
Azure Active Directory においても有償版を明示的に選ばなければ、課金されることはありません。
無料クレジットが付与されることもあるので、この機会に Azure の利用をはじめてみましょう。

Azure の環境が整ったら、[新規] - [セキュリティ + ID] - [Azure Active Directory] を選択する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/1849b5f0-5e26-a03a-a0d7-2f32b2409edb.png)

[組織名] に任意の名称を入力、[初期ドメイン名] ドメイン名を入力、[国/リージョン] に任意のリージョンを入力し、[作成] を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/98ab748e-211e-03ae-670f-59cd15801653.png)

Azure Active Directory が作成されたら、ブラウザーをリロードします。
右上のアカウント名をクリックすると、作成した Azure Active Directory が選択可能となるので、これを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/558f74f3-f5b8-4703-0419-e56346e9cbe8.png)

選択したディレクトリに移動するので、この状態から [Azure Active Directory] を選択します。
同画面より新規に作成した "Azure Active Directory" の設定を行うことができるので、この手順を覚えておきます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/25ba0c0f-5a6c-1e61-1e67-036de229e00e.png)

# Azure Active Directory のユーザーの追加

次に、Azure Active Directory にユーザーを追加します。
[すべてのユーザー] - [新しいユーザー] を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/9708a83d-f20b-445c-5594-656b0f304e1e.png)

[名前] に任意の名前、[ユーザー名] に任意のアカウント名 + "@" + Azure Active Directory の FQDN を設定、[パスワードを表示] をチェックし、表示されたパスワードを覚えておきます、[作成] を選択します。
Azure Active Directory 内のローカル アカウントはこの方法で作成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/37e69a83-aa75-ae48-da66-2ead66dffb82.png)

**Azure Active Directory の非常に便利な点として、外部のユーザーを追加できるということがあります。**
**Microsoft アカウントや他の Azure Active Directory のユーザーを招待し、追加できます。**
[すべてのユーザー] - [新しいゲスト ユーザー] を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/6bcc3c3a-f380-cc96-6d7d-b3755278a37c.png)

招待する Microsoft アカウントや他の Azure Active Directory のアカウント、招待メッセージを入力し、[招待する] を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/808a4619-a36f-a691-414d-d15bcd5adf7b.png)


# プロジェクトの作成
次に、Visual Studio 2017 により Azure Active Directory を利用した認証を行う ASP.NET Core MVC プロジェクトを作成します。

Visual Studio 2017 を起動し、[ファイル] - [新規作成] - [プロジェクト] を選択。
[テンプレート] - [Visual C#] - [.NET Core] を選択し、[ASP.NET Core Web アプリケーション(.NET Core)] を選択し、[OK] を選択。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/e2a0527c-51db-9941-839a-0a3c42fbc05e.png)

[Web アプリケーション] を選択し、[認証の変更] を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/a87712ed-0d60-965d-eeda-74d17ff80a4a.png)

[ドメイン] に、前出の手順で作成した Azure Active Directory の FQDN を入力、[OK] を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/770a09ff-842c-783c-a004-877d32595dbb.png)

認証が要求されるので、Azure の管理権限を持つアカウントでサインインします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/a66d05a7-a97c-ef6f-6806-7a40d6820ec0.png)

テンプレート選択画面に戻ってくるので、[OK] でプロジェクト テンプレートを生成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/da8c0525-61cf-8ebd-6178-0dd58cf95c53.png)

次に生成されたプロジェクトを実行します。[F5] キーもしくは、[IIS Express] を選択して、プロジェクトを実行します。
実行時に、IIS Express の自己証明書の信頼についてのダイアログが表示された場合は、[はい] を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/5d7aad08-2faf-401a-8a5b-3b81f511b656.png)
続けて証明書をインストールします。[はい] を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/9a233133-c61f-7ae3-3c69-c7a4f3c18a50.png)

プロジェクト起動後、認証画面に遷移するので、前出の手順で、Azure Active Directory に追加したユーザーのアカウントとパスワードでサインインします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/88a6957b-a4c9-a917-66a1-322215b59fde.png)

パスワードの更新が促された場合は、パスワードを更新します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/7fb923f7-e905-e799-1654-83091c88afe9.png)

ここで、Intenal Server Error が発生することがあります。
https://localhost:xxxx/signin-oidc に遷移してしまっている場合は、https://localhost:xxxx/ へ遷移し直してください。
初期画面が表示され、右上のサインインしたアカウントが表示されていることが確認できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/4f5fbbec-f570-cea7-8c35-9b846ca5b052.png)

<!--- ![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/4c724389-a5c4-4087-a38d-274e797e6738.png) !-->


# 生成されたソース コードの確認

生成されたソース コードの Startup.Configure メソッドを確認すると、OpenID Connect の認証の定義が追加されていることが分かります。IApplicationBuilder.UseOpenIdConnectAuthentication メソッドにより、Azure Active Directory への OpenID Connect 認証に必要な情報を OpenIdConnectOptions のインスタンスにより設定しています。

```csharp:Startup.cs

public class Startup
{
    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseBrowserLink();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
        }

        app.UseStaticFiles();

        app.UseCookieAuthentication();

        app.UseOpenIdConnectAuthentication(new OpenIdConnectOptions
        {
            ClientId = Configuration["Authentication:AzureAd:ClientId"],
            Authority = Configuration["Authentication:AzureAd:AADInstance"] + Configuration["Authentication:AzureAd:TenantId"],
            CallbackPath = Configuration["Authentication:AzureAd:CallbackPath"]
        });

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}
```

OpenIdConnectOptions により OpenID Connect の情報を設定しているのは、ClientId, Authority, CallbackPath の 3 つのみです。
この **3 つの情報を設定するのみで、Azure Active Director を利用した認証を実現できてしまいます。**

「[ASP.NET Core MVC における構成ファイル appsettings.json からの値取得](http://qiita.com/hiromasa-masuda/items/d7e33b20d3eedee771f4)」でも書いたように、ClientId, Authority, CallbackPath の値は、appsettings.json に定義された値を取得するように実装されています。

```json:appsettings.json
{
  "Authentication": {
    "AzureAd": {
      "AADInstance": "https://login.microsoftonline.com/",
      "CallbackPath": "/signin-oidc",
      "ClientId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "Domain": "aspnetcore001.onmicrosoft.com",
      "TenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
    }
  },
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  }
}
```
これらの値が Azure Active Directory のどの値に該当するかを見ていきます。
このコードで別の Azure Active Directory への接続へ設定を変更する場合に必要となります。

まず、TenantId は、[プロパティ] - [ディレクトリ ID] に対応します。この値は、Azure Active Directory のインスタンスを識別する一意な ID です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/d27a57a8-c90b-7d84-e19d-45fb376d2f10.png)

ClientId は、[アプリの登録] から、該当のアプリを選択、[アプリケーション ID] に対応します。この値は、Azure Active Directory 上に登録したアプリに対する一意な ID です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/7f24a0a3-bb4b-20c5-45b7-78ed73c437ef.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/172205/f56e4de2-9127-ea96-e43f-8663bdedc565.png)

以上で、Visual Studio 2017 に標準で提供されている ASP.NET Core MVC のテンプレートを利用し、Azure Active Directory の認証の実装を容易に行うことができました。
認証機構を独自に開発する際には、パスワードのリセット、パスワードの複雑さのポリシーなども自身で開発する必要があり、これには、多くのコストが必要となります。
Azure Active Directory は、この認証に伴う必要な機能の多くを提供するため、開発者は、本来のアプリケーションの重要な機能にリソースを集中できるようになり、より魅力的なアプリケーションの開発を行うことができるようになると考えています。