.NET MAUIでAzure AD B2Cで認証する(Googleアカウント認証追加してみる)

# はじめに
前回MicrosoftアカウントにてアプリにAzureActiveDirectoryB2Cの認証機能を追加しましたので、今回は他のプロバイダーのアカウントを認証できるようにしていきます。

今回追加するアカウントはおそらく認証アカウントで一番多いであろうGoogleの認証について紹介していきます。

# サブスクリプションにAD B2Cの権限を追加
サブスクリプションの機能にAzureActiveDirectoryの権限を追加する必要があります。

Azureポータルから「サブスクリプション」→使用したいサブスクリプション名をクリックして、右側のメニューから「リソースプロバイダー」を選択し、「Microsoft.AzureActiveDirectory」を見つけ、クリック、上部の登録ボタンを押して、サブスクリプションに権限を追加します。
![サブスクリプション.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/a9a40a55-c009-fcda-3891-b96984a534f3.png)


# Azure Active Directory B2Cのテナントを作成
まず、AD B2C用のテナントを用意します。
前回、AzureのアカウントにAD B2Cを作りましたが、多くのプロバイダー認証が必要な場合、テナントを作成してそのうえで認証アプリを作成する必要があります。

まず、ポータル画面からリソースの追加ボタンを押します。
![リソースの作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/3c01ca3b-df2d-9b13-8918-2a540c4c1369.png)

次に検索窓で「azure active directory b2c」と検索し、出てきた「Azure Active Directory B2C」を選択します。
![AzureActiveDirectoryB2C.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/fa9dd422-19b2-f712-ee4c-0de389049cd0.png)

「新しいAzure AD B2Cテナントを作成する」をクリックします。
![新規テナント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/97ad2624-b5a1-b1b7-52ac-4d0c60072698.png)

テナントの情報を入力します。
「組織名」・・・テナントの名前です。
「初期ドメイン名」・・・テナントの初期ドメインです。わかりやすいドメインを設定しましょう。
「国/地域」・・・所属している国を指定します。私は今日本にいるので日本としました。
「サブスクリプション」・・・Azureに登録しているサブスクリプション名を選択します。
「リソースグループ」・・・リソースグループの選択をします。この時新規で作成することも可能です。
入力が完了したら「確認及び作成」でテナントを作成しましょう。
![テナント作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/78b759a9-71a0-672c-fcdb-864e04618d05.png)

作成完了後、テナントのページへ移動します。

# アプリケーションの登録
前回同様、AzureADB2Cにアプリを登録していきます。
右側メニューの「アプリ登録」→「新規作成」で作成ページへ移動し、以下のように情報を入力します。

「サポートされているアカウントの種類」では一番下の「任意のIDプロバイダーまたは組織ディレクトリ内のアカウント(ユーザーフローを使用したユーザーの認証用)」を選択。
登録を押します。

![アプリケーション登録.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/32ab5533-3661-ee73-ece6-996354657a69.png)

リダイレクトURLも前回の方法と同様に設定を行ってください。

# ユーザーフローの設定
アプリを登録したら、認証作業の設定です。
この設定では、どのような認証画面でどのような入力フォームを作成するのかを設定します。

「AzureADB2C」の画面に戻り、左側のメニューから「ユーザーフロー」を選択、上部の「新しいユーザーフロー」を選択します。
![ユーザーフロー選.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/04574656-82dc-5874-5d4c-6663e338db1e.png)

ユーザーフロータイプはサインアップとサインインを選択し、バージョンは推奨を設定し作成を押します。
![ユーザーフロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/76d2010c-cf86-026b-7796-5135f51c47e9.png)

ユーザーフローの作成画面になります。
見切れていますが、
1.「名前」ではユーザーフローの名前を設定します。（今回は"SignUp-anyProvider"としました。）
2.「IDプロバイダー」は「Email signup」を選択します。
3.「多要素認証」では「メール」、「オフ」を選択し、
4.「条件付きアクセス」ではチェックを入れなくてもよいです。
5.「ユーザー属性とトークン」はとりあえず「名」にそれぞれチェックを入れました。
全て記入を終えたら作成を押します。
![ユーザーフロー作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/91edfccb-facb-b8de-ed1e-778ca80c615a.png)

# Googleプロバイダーの設定
ユーザーフローの作成が終了したら、右側の「IDプロバイダー」を開きます。
すると多くのプロバイダーの名前が書かれていて、これについて設定していくと認証でそれらのアカウントを使用することができるようになります。
今回はGoogle認証を追加するのでGoogleを選択します。
右側の項目が出てくるので、上部のリンクからチュートリアルを開き、チュートリアル通りに空欄を埋めることで、認証プロバイダーとして登録することができます。
![Googleprovider.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/38731f64-75cb-70ed-a2a4-b770296a14d7.png)

それではリンク先のチュートリアルを参考に以下の方法で記入する要素を作っていきます。

## 1.GoogleDeveloperConsoleにプロジェクトを登録
まず、[Google Developers Console](https://console.developers.google.com/)を開きます。
メイン画面から上部「プロジェクトの選択」をクリックすると、ダイアログが出てくるので「新しいプロジェクト」を選択します。
![GoogleProject選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/15901ea8-3375-7732-057f-ab87815c43e2.png)
新しいプロジェクトは以下のように設定し作成してください。
![プロジェクト作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/c02266f8-4813-f517-de6a-6a79e2bd20a5.png)

## 2.OAuth設定
次に左側のメニューから「OAuth同意画面」を選択し、「外部」にチェックを入れて作成します。
![OAuth外部.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/4aebabec-8f0f-49d9-e696-daae80f28ddc.png)

見切れていますが、アプリ名、ユーザーサポートのメールアドレスを入力します。
アプリのドメインは入力しなくて問題ないです。
承認済みドメインには「b2clogin.com」と入力します。
デベロッパーの連絡先も任意で登録しておきます。
![GoogleOAuth設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/4b52f49e-3675-dd09-b7b7-f8402b27f6aa.png)

スコープやテストユーザーの設定はする必要がないので飛ばして保存しましょう。
![スコープ無し.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/62839d30-6b6c-2855-6f0d-6f77f10b8cf5.png)

OAuthを設定すると、下のような画面が出ます。
テスト状態になっていますので、「アプリを公開」を押して公開しましょう。
![apurikoukai.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/81a18417-77db-5d54-23f0-b33d00030213.png)

## 3.認証情報
次に認証情報を設定します。
右側のメニューから「認証情報」を選択し、上部タブの「+認証情報を作成」→プルダウンメニューから「OAuthクライアントID」を選択します。
![認証情報を作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/63bce6bb-db7d-b092-a73b-e372b1f29406.png)

1.作成画面ではまずプルダウンメニューから「アプリケーションの種類」を選びます。
モバイルアプリやデスクトップアプリであっても認証作業はブラウザを開き、ウェブ上で行うため、「ウェブアプリケーション」を選択します。

2.「名前」にはアプリの名前を登録します。

3.「承認済みのJavaScript生成元」では「+URIを追加」を押して以下のように入力します。
[https://your-tenant-name.b2clogin.com]をコピペし、「your-tenant-name」の部分はAzureのテナントの名前に書き換えます。
私が作ったテナントの名前は「nmauihs」なのでそれに書き換えています。


4.「承認済みリダイレクトURI」では同様に「+URIを追加」を押し、
[https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/oauth2/authresp]をコピペ、「your-tenant-name」を自分のテナント名に書き換えます。
※your-tenant-nameが2つあるので2つとも書き換えを行う。

これで「作成」ボタンを押します。

![webクライアント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/569e3343-b96b-24e7-068c-94841d7200b3.png)

これでGoogleのクライアントIDとシークレットIDが生成されます。

![クライアント作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/27229f28-8886-1a1c-1fbd-ad876caae900.png)

# Azureに登録
Googleの情報をAzureのIDプロバイダーに紐づけます。
生成したクライアントIDとシークレットIDをIDプロバイダーの項目の部分にコピペします。
「名前」の部分は単純に「Google」とかでOKです。
記入が済んだら上部の「保存」を押して登録します。

![ソーシャルprovider作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/24f04bd3-826c-2032-eccc-672b81b330e2.png)

再度、左側メニューの「ユーザーフロー」から使用したいユーザーフローを選択します。
![IDプロバイダー追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/464669af-c747-8e60-65ab-2d546a191c90.png)

設定画面が開くので「ID プロバイダー」を選択
![IDプロバイダー追加tui.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/9a6a109f-3d4e-ca17-f166-f5cdb259aba4.png)

「ソーシャルIDプロバイダー」の欄にGoogleが追加されているのでこれにチェックを入れて保存します。
![Googlepr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/7bd2b547-a15f-e9ad-8c5f-674f585aa563.png)

これでAzureでの設定は完了になります。

# プログラム
Azureの設定が終わったのでプログラムにAzureADB2Cの認証ができるように書き換えていきます。
以前作成した「Models」フォルダの「Constansクラス」を開き以下のように追加します。
```cs
public static class Constants
    {
        //↓Azure AD B2CのクライアントIDをコピペ
        public static readonly string ClientId = "adcd...";//←今回新しくアプリを登録したのでそのクライアントIDを変更する

        public static readonly string[] Scopes = new string[] { "openid", "offline_access" };

        //B2CIDproviderを使う場合に追加するもの
        //テナントの名前
        public static readonly string TenantName = "nmauihs";//←作成したテナント名。私は「nmauihs」でテナントを作ったのでこの名前
        //テナントのID({変数}で入力されるため書き換え不要)
        public static readonly string TenantId = $"{TenantName}.onmicrosoft.com";
        //サインインポリシー(今回はユーザーフローに名前をつけたのでその名前を記入)
        public static readonly string SignInPolicy = "B2C_1_SignUp-anyProvider";//ユーザーフローの名前を付けるとき、「SignUp-anyProvider」とつけたのでそれを入力した
        //認証のベース({変数}で入力されるため書き換え不要)
        public static readonly string AuthorityBase = $"https://{TenantName}.b2clogin.com/tfp/{TenantId}/";
        //認証サインイン({変数}で入力されるため書き換え不要)
        public static readonly string AuthoritySignIn = $"{AuthorityBase}{SignInPolicy}";
    }
```

そして「Services」フォルダの「AuthenticationService」に.WithB2CAuthorityを追加します。
```cs
public partial class AuthenticationService
    {
        private readonly IPublicClientApplication authenticationClient;

        //失敗または成功のトークンを受け取るためのリダイレクトURLを提供します
        public AuthenticationService()
        {
            authenticationClient= PublicClientApplicationBuilder
                .Create(Constants.ClientId)
                .WithRedirectUri($"msal{Constants.ClientId}://auth")

#if ANDROID
                .WithParentActivityOrWindow(() => Platform.CurrentActivity)
#elif IOS
                .WithIosKeychainSecurityGroup("com.microsoft.adalcache")
#endif 
                .WithAuthority(AzureCloudInstance.AzurePublic, "common")
                .WithB2CAuthority(Constants.AuthoritySignIn)//←これだけ追加
                .Build();
        }
```

また、AndroidマニュフェストやiOSマニュフェストにも古いクライアントIDを入力していたところがあったと思うので、今回作ったクライアントIDに書き換えます。

これで実行するとLoginボタンで画面にGoogleAccount認証画面が出てきてGoogleAccountで認証できるようになります。

![Google追加.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007605/295ce1b0-74d9-7bad-85aa-ab4984e6a408.png)

# さいごに
Google認証をアプリに登録することについて紹介しました。
そのほかのプロバイダーの追加については、ユーザーフローの各プロバイダーの項目のところにチュートリアルのリンクがあると思うので、そちらを参考にして追加していってください。

テナント無しの時はMicrosoftアカウントは何もせずとも使えたのにテナント作る場合は使えなくなるのはちょっと残念ですね、、、