Microsoft Entra Verified ID を使ってみた（①環境構築編）

2022 年 8 月に Microsoft Entra Verified ID が GA されました。

参考：https://techcommunity.microsoft.com/t5/microsoft-entra-azure-ad-blog/microsoft-entra-verified-id-now-generally-available/ba-p/3295506

本記事では下記の公式ドキュメントを参考に、Verified IDを利用するための環境構築手順をご紹介します。

* [Configure your tenant for Microsoft Entra Verified ID](https://learn.microsoft.com/en-us/azure/active-directory/verifiable-credentials/verifiable-credentials-configure-tenant)
* [Issue Microsoft Entra Verified ID credentials from an application](https://learn.microsoft.com/en-us/azure/active-directory/verifiable-credentials/verifiable-credentials-configure-issuer)

## Microsoft Entra Verified ID

- Microsoft が提供する分散型 ID サービスです。
- ブロックチェーンの技術を利用したデジタル証明書を発行したり、検証したりすることができます。
- 旧称は Azure Active Directory Verifiable Credentials で、GA に向けて名称が変更されました。

## 事前準備

Verified ID の環境構築にはいくつか事前に準備が必要です。

### 前提条件

- Azure の各種リソースを作成するため、Azure サブスクリプションが適用された Azure テナントがあるものとします
- 環境構築を行うユーザーは、テナントのグローバル管理者権限があるものとします

参考：https://docs.microsoft.com/ja-jp/azure/active-directory/verifiable-credentials/verifiable-credentials-configure-tenant#prerequisites

### サービスエンドポイントの準備

詳しい内容については後で紹介しますが、Verified ID の利用には任意のドメインが必要です。

さらに、そのドメインを使い下記 URL にアクセスできる状態にしておく必要があります。

- `https://<Verified IDのドメイン>/.well-known/did.json`
- `https://<Verified IDのドメイン>/.well-known/did-configuration.json`

今回は App Services で代替しますが、既に上記のような URL にアクセスできる環境があればお使いの環境でも問題ありません。

#### App Service の作成

- 名前：任意の名前
- ランタイムスタック：.NET6
- オペレーティング システム：Windows
- 地域：Japan East
- App Serviceプラン：無ければ新規作成

他はデフォルトで問題ありません。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/143ea7ef-1be7-bd8c-5a97-e656406a7b9f.png)


#### コントローラーの作成

- 新規に ASP .NET Web API のプロジェクトを作成し、下記のようなコントローラーを追加します。
  - 本記事では.NET6 を前提としたコードとなります。
- コード内で`did.json`や`did-configuration.json`という JSON ファイルを参照していますが、こちらは後述の Verified ID の環境構築の際にダウンロードします。
  - こちらのソースコードは下記のGitHubをご参照ください。
    - https://github.com/AsukaSeki/verified-id-sample/tree/main/backend/VerifiedIdDomain

```csharp
using Microsoft.AspNetCore.Mvc;

namespace VerifiedId.Did.Api.Controllers
{
    [ApiController]
    public class DidController : ControllerBase
    {
        [Route("/.well-known/did.json")]
        public ActionResult GetDid()
        {
            var json = "";

            using (StreamReader stream = new StreamReader("./did.json"))
            {
                json = stream.ReadToEnd();
            }
            return Ok(json);
        }

        [Route("/.well-known/did-configuration.json")]
        public ActionResult GetDidConfiguration()
        {
            var json = "";

            using (StreamReader stream = new StreamReader("./did-configuration.json"))
            {
                json = stream.ReadToEnd();
            }
            return Ok(json);
        }
    }
}
```

## Verified ID 向けのテナントを構成する

### Key Vault の作成
下記のURLからAzure Portalにアクセスし、「リソースの作成」から「Key Vault」を選択します。

https://portal.azure.com/#home

- Key Vault名：任意の名前
- 地域：Japan East
- 価格レベル：標準

他はデフォルトの設定で良いです。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/ff9f04cf-7161-062b-af4e-efb9c7b0f77d.png)


#### アクセスポリシーの設定
Key Vaultリソース作成後、アクセスポリシーを変更します

##### 管理者ユーザー
- Key Vault作成時のユーザーがデフォルトで登録されているため、このユーザーのアクセス許可に下記のアクセスポリシーを追加します
    1. キーの管理操作 > 作成
    1. キーの管理操作 > 削除
    1. 暗号化操作 > 署名
        - デフォルトで登録されているユーザーは1.および2.は既に追加済みのため、3.のみ追加する必要があります。
- Key Vault作成者と環境構築をするユーザーが同じ場合は上記の設定のみで良いですが、別ユーザーが構築する場合は適宜上記の権限を持つユーザーを追加します。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/4b3efd68-caba-66ca-81a9-157491635f83.png)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/0f2c7dc7-5691-8194-bc8f-02f79328921e.png)

### Verified ID
下記の URL から Microsoft Entra 管理センターにアクセスし、「検証済みID > Overview」を選択します

https://entra.microsoft.com/


#### 初期設定
Verified IDの初期設定画面が表示されるため、下記の情報を登録します。

- 組織名：任意の組織名
- ドメイン：`https://` から始まる任意のドメイン
    - 上述の[サービスエンドポイントの準備](#サービスエンドポイントの準備)でアクセスするURLのドメインです。
    - App Serviceでサービスエンドポイントを代替する場合はこちらにApp Serviceのドメイン（`https://xxxxx.azurewebsites.net`の形式）を入力します
        - このドメインは作成したApp Serviceの概要の画面で確認できます。
- キーコンテナー：[Key Vault の作成](#key-vault-の作成)で作成したKey Vault
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/8a9d4bf0-aabb-22d5-bc6c-53d9cff9c9f6.png)


初期設定が完了すると、先ほど作成したKey Vaultのアクセスポリシーにこのようなポリシーが自動的に追加されます。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/e2878820-3241-ef4e-5ffe-4282cc0f1ec6.png)


#### サービスエンドポイントの構成
Verified IDの初期設定が完了したら、次に「検証済みID > ドメイン」の画面を開きます。

「資格情報または確認要求を作成する前に、[登録] で分散化 ID を登録する必要があります」という表記がありますので、こちらを設定していきます。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/8e4f1b69-4a20-df46-0077-6a7dc7377f4a.png)


##### DID登録およびドメインの所有権の確認
下記の設定画面からダウンロードしたJSONファイルを下記のURLに配置し、検証します。

配置後は「検証状態の更新」を行い、状態が「登録済み」になることを確認します。

- DID 登録
    - `https://<Verified IDのドメイン>/.well-known/did.json`
- ドメインの所有権の確認
    - `https://<Verified IDのドメイン>/.well-known/did-configuration.json`
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/f26087bb-287e-911f-40e4-80d94d236888.png)

DID 登録とドメインの所有権の確認の両方が完了していることを確認します。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/f246372c-013f-78a3-8d67-72ae95a42cd0.png)


##### App Service で代替した場合

上述の[サービスエンドポイントの準備](#サービスエンドポイントの準備)で App Service を利用している場合、ダウンロードした 2 点の JSON ファイルを作成したプロジェクトの.csproj ファイルと同じ階層にコピーします。

コピーが完了したら、[App Service の作成](#app-service-の作成)で作成した App Service にデプロイします。

デプロイ後下記の URL でJSON が取得できることを確認し、上述の「DID登録」と「ドメインの所有権の確認」で検証します。

- `https://<Verified IDのドメイン>/.well-known/did.json`
- `https://<Verified IDのドメイン>/.well-known/did-configuration.json`

## Verified ID で証明書を発行する

### 資格情報の作成

1. 「検証済みID > 資格情報」の画面を開き「資格情報の追加」を選択します。
    ![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/0a630f5c-11ab-947b-50e7-2077242ae499.png)

1. 「資格情報の選択」では「カスタム資格情報」し次へ。
    ![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/a0379bfc-0855-7cf0-047e-d168df3cfc81.png)

1. 「新しい資格情報の作成」で下記の資格情報を入力します。
    - 資格情報名：`VerifiedCredentialExpert`
        - こちらは、「ルールの定義」のJSONの`attestations > vc > type`の値と合わせる必要があります。
    - 表示の定義：下記のJSONを貼り付け
        ```json
        {
          "locale": "ja-JP",
          "card": {
            "backgroundColor": "#333c5e",
            "description": "Use your verified credential to prove to anyone that you know all about verifiable credentials.",
            "issuedBy": "VerifiedIDSample",
            "textColor": "#ffffff",
            "title": "Verified ID Sample"
          },
          "consent": {
            "instructions": "Sign in with your account to get your card.",
            "title": "Do you want to get your Verified Credential?"
          },
          "claims": [
            {
              "claim": "vc.credentialSubject.id",
              "label": "ID",
              "type": "String"
            },
            {
              "claim": "vc.credentialSubject.firstName",
              "label": "First name",
              "type": "String"
            },
            {
              "claim": "vc.credentialSubject.lastName",
              "label": "Last name",
              "type": "String"
            }
          ]
        }
        ```
    - ルールの定義：下記のJSONを貼り付け
        ```json
        {
          "attestations": {
            "idTokenHints": [
              {
                "mapping": [
                  {
                    "outputClaim": "id",
                    "required": true,
                    "inputClaim": "$.id",
                    "indexed": true
                  },
                  {
                    "outputClaim": "firstName",
                    "required": true,
                    "inputClaim": "$.given_name",
                    "indexed": false
                  },
                  {
                    "outputClaim": "lastName",
                    "required": true,
                    "inputClaim": "$.family_name",
                    "indexed": false
                  }
                ],
                "required": false
              }
            ]
          },
          "validityInterval": 2592000,
          "vc": {
            "type": [
              "VerifiedCredentialExpert"
            ]
          }
        }
        ```
    ![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/40cbc11d-7ae0-d680-4348-1b95e8da02cf.png)


1. 作成が完了すると、下記のように証明書のプレビューやマニフェストファイルURL等が確認できます。
    ![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/ff13e002-7510-b4f7-1171-6c09e7f2826b.png)


### Azure AD

Microsoft Entra 管理センターの「Azure Active Directory > Applications > アプリの登録」を選択します
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/5ef326f6-6aba-3f78-3651-dfbee67ddbf8.png)


#### アプリの登録

アプリの管理画面から「新規登録」を選択し、下記の設定を入力しアプリを作成します。

- 名前：任意の名前
- サポートされているアカウントの種類：この組織ディレクトリのみに含まれるアカウント (既定のディレクトリ のみ - シングル テナント)
- リダイレクト URI：なし
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/c67a54f3-0ae7-8b96-c76c-ef2f923585b4.png)


#### APIのアクセス許可の追加
1. アプリの作成が完了したら、該当アプリの設定画面の「APIのアクセス許可」から「アクセス許可の追加」を選択します。
    ![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/7509ee2c-c4ab-4e57-bf1c-a893480aa27a.png)

1. 「所属する組織で使用しているAPI」から`Verifiable Credentials Service Request`を検索し、選択します。
    ![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/59924b1b-cd60-2771-e60a-5812d4717830.png)

1. API アクセス許可の要求は「アプリケーションの許可」を選択し、`VerifiableCredential.Create.All`をチェックしアクセス許可を追加します。
    ![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/03f94a98-4f75-3d39-371e-9a9368fa7291.png)

1. 最後に、「<テナント名> に管理者の同意を与えます」を選択し、管理者の同意を与えます。
    ![19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/3833b314-3af8-0f5c-63cb-6e7e312dd24b.png)

1. `Verifiable Credentials Service Request`のアクセス許可の状態が「<テナント名>に付与されました」と表示されていることを確認します。
    ![20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/ea323b38-50e1-cb9c-b228-f1e34c7443bf.png)


#### シークレットの登録
1. 該当アプリの設定画面の「証明書とシークレット」から「新しいクライアントシークレット」を選択します。
    ![21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/ce58a445-fcb2-064f-cde4-36a81c92e6dd.png)

1. シークレットの説明と有効期限を入力し、追加します。
    ![22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/19219563-93ae-757a-6e57-ccf78c4ca41c.png)

1. 登録が完了すると、シークレットの値が表示されます。この「値」を控えておきます。
    * **シークレットの値は必ずこのタイミングで控えておいてください。画面をリフレッシュしたり、他の画面に遷移したりするとシークレットの値は再表示できなくなります。**
    * このシークレットの値は証明書の発行アプリで利用します。
    ![23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/ad616d7d-e6d4-1b15-6b58-6c70b519c5ce.png)


## 最後に
これで環境構築は完了です。

このようにADの設定と、いくつかのAzureリソースを作成するだけで簡単にデジタル証明書の発行や検証を行うための環境が作成できます。

次回はMicrosoft公式で公開されているこちらのサンプルコードを参考に、実際にデジタル証明書を発行、検証するアプリケーションを作成します。

https://github.com/Azure-Samples/active-directory-verifiable-credentials-dotnet

## 関連記事
* 次回の記事
  * [Microsoft Entra Verified ID を使ってみた（②発行編）](https://qiita.com/ToshihiroNozaki/items/ab493131998bcac837c6)
      * 12/7（水）に公開されます。

## 参考資料
* Microsoft公式ブログによるGAのアナウンス
  * [Microsoft Entra Verified ID now generally available](https://techcommunity.microsoft.com/t5/microsoft-entra-azure-ad-blog/microsoft-entra-verified-id-now-generally-available/ba-p/3295506)
    * 分散型IDの仕組みが図解されておりとても分かりやすいです。
* Verified IDの環境構築
  * [Configure your tenant for Microsoft Entra Verified ID](https://learn.microsoft.com/en-us/azure/active-directory/verifiable-credentials/verifiable-credentials-configure-tenant)
  * [Issue Microsoft Entra Verified ID credentials from an application](https://learn.microsoft.com/en-us/azure/active-directory/verifiable-credentials/verifiable-credentials-configure-issuer)
  * [Configure Microsoft Entra Verified ID verifier](https://learn.microsoft.com/en-us/azure/active-directory/verifiable-credentials/verifiable-credentials-configure-verifier)
* Verified IDのドメインをApp Servicesで代用するためのサンプルコード
  * [GitHub](https://github.com/AsukaSeki/verified-id-sample/tree/main/backend/VerifiedIdDomain)