Azure-AD-B2Cに電話番号やユーザー名でログインする

Azure AD B2Cではデフォルトでメールアドレスでのログインが可能ですが、
ユーザーフローやカスタムポリシーを編集することでユーザー名や電話番号でのログインも可能です。
今回はユーザーフローとカスタムポリシーの両方でユーザー名と電話番号それぞれでログインを行うための手順をご紹介します。

### 前提（カスタムポリシー）
カスタムポリシーを利用する場合、下記のStarterPackから3つのカスタムポリシーをコピーします。

* TrustFrameworkBase.xml
* TrustFrameworkLocalization.xml
* TrustFrameworkExtensions.xml

Github：https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack/tree/master/SocialAndLocalAccountsWithMfa

#### 【補足】Facebookログインのコメントアウト

今回Facebookログインは利用しないため、上記サンプルポリシーのうちFacebook関連の箇所はコメントアウトしておきます。

1. TrustFrameworkBase.xml
   1. ClaimsProvider
      Domainが`facebook.com`であるClaimsProviderをコメントアウトします。  

        ```xml
        <!-- コメントアウト -->
        <!--
        <ClaimsProvider>
          <Domain>facebook.com</Domain>
          <DisplayName>Facebook</DisplayName>
          ...
        </ClaimsProvider>
        -->
        ```
   1. UserJourney
      Step1, 2の`FacebookExchange`参照している行をコメントアウトします。`SignUpOrSignIn`, `ProfileEdit`のUserJourneyが該当します。

        ```xml
        <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
          <ClaimsProviderSelections>
            <!-- <ClaimsProviderSelection TargetClaimsExchangeId="FacebookExchange" /> --> <!-- コメントアウト -->
            <ClaimsProviderSelection ValidationClaimsExchangeId="LocalAccountSigninEmailExchange" />
          </ClaimsProviderSelections>
          ...
        </OrchestrationStep>

        <OrchestrationStep Order="2" Type="ClaimsExchange">
          ...
          <ClaimsExchanges>
            <!-- <ClaimsExchange Id="FacebookExchange" TechnicalProfileReferenceId="Facebook-OAUTH" /> --> <!-- コメントアウト -->
            <ClaimsExchange Id="SignUpWithLogonEmailExchange" TechnicalProfileReferenceId="LocalAccountSignUpWithLogonEmail" />
          </ClaimsExchanges>
        </OrchestrationStep>
        ```

1. TrustFrameworkExtensions.xml
   1. ClaimsProvider
      DisplayNameが`Facebook`のClaimsProviderをコメントアウトします。

        ```xml
        <!-- コメントアウト -->
        <!--
        <ClaimsProvider>
          <DisplayName>Facebook</DisplayName>
          <TechnicalProfiles>
            <TechnicalProfile Id="Facebook-OAUTH">
              ...
            </TechnicalProfile>
          </TechnicalProfiles>
        </ClaimsProvider>
        -->
        ```

## ユーザー名でのログイン

### ログインの流れ
基本的な流れは下記の通り、メールアドレスのログインとほぼ同じです。

![スライド1-a092fb96-d71b-46dd-9cbc-625e60b077c5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/fcedb059-5dc5-7a97-3868-9ab0be876aeb.png)

### ユーザーフロー
1. B2C管理画面のIDプロバイダーの画面でローカルアカウント > Usernameをチェックし保存します。
    ![image-c277deee-1b46-4a9a-8a30-c67e72da814b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/995345d2-67ce-6789-b477-e53cf418aad9.png)
1. 「サインアップとサインイン」のユーザーフローを追加します
    ![キャプチャ2-da07e1d9-0c44-4887-9ef4-da46d4021861.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/26871cb0-5828-0708-d435-3c236b5e8455.png)
1. IDプロバイターはローカルアカウントの「User ID signup」を選びます。
    ![キャプチャ3-0f07f3b3-bc58-472a-a9e3-ed9e7d52faa8.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/2dfb27db-1cf3-480e-5cb5-5cd7ca234a02.png)


### カスタムポリシー
Githubにユーザー名でログイン・ユーザー登録するカスタムポリシーのサンプルコードがありますので、そちらを利用します。
上述のカスタムポリシーに加え、下記のGithubのカスタムポリシーをコピーします。

Github：https://github.com/azure-ad-b2c/samples/tree/master/policies/username-signup-or-signin

補足として、上述のTrustFrameworkLocalization.xmlの以下の箇所を`Username`に変えておきます。
ログイン画面でユーザー名を入力するよう促す文言です。

  ```xml
  <LocalizedResources Id="api.signuporsignin.en">
    <LocalizedStrings>
      <LocalizedString ElementType="ClaimType" ElementId="signInName" StringId="DisplayName">Username</LocalizedString>
      <LocalizedString ElementType="UxElement" StringId="local_intro_generic">Sign in with your Username</LocalizedString>
      ...
    </LocalizedStrings>
    ...
  </LocalizedResources>
  ```

### 実行結果
1. ユーザーフローやカスタムポリシーを実行すると、メールアドレス同様にログイン画面が表示されます。
   ![ユーザー名_実行2-84ee50bf-3942-4088-8c03-9c0e92c77b65.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/00561557-348e-0b93-d484-60a1b4fd0036.png)

1. 「Sign up now」のリンクをクリックするとユーザー登録画面が表示されます。
   ![ユーザー名_実行-ecea9a28-9cec-4972-9c8f-8097714bc7c2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/256ae18f-042d-711b-3bcc-3f8563b92aee.png)

※今回は省略しますが、上記サンプルポリシーの「PasswordReset.xml」を適用することでログイン画面の「パスワードを忘れた場合」も動作できます。


## 電話番号でのログイン

### ログインの流れ
基本的な流れについては下記の通りです。ポイントは電話番号を入力後にSMSや電話の発信を行い電話番号を認証する箇所になります。

![スライド2-5415be58-3eb3-4e1f-b14e-23b38103412b.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/972bd96d-c2c8-7171-c321-323c94199b8b.png)


### ユーザーフロー
1. B2C管理画面のIDプロバイダーの画面でローカルアカウント > Phoneをチェックし保存します。

    ![image-798f15de-e91e-4861-909c-89b7dc30458d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/5aaa3f55-5b3f-f728-d07b-219c633a8ab2.png)

1. 「サインアップとサインイン」のユーザーフローを追加します

    ![キャプチャ2-da07e1d9-0c44-4887-9ef4-da46d4021861.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/0ee3568d-4c88-72bb-62c6-eadaa1f63a49.png)

1. IDプロバイターはローカルアカウントの「Phone signup」を選びます。

   ![image (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/82dcc6c0-1b48-b690-ec56-b38c91b13786.png)


### カスタムポリシー
Githubにユーザー名でログイン・ユーザー登録するカスタムポリシーのサンプルコードがありますので、そちらを利用します。
上述のカスタムポリシーに加え、下記のGithubの`policy/phone-signup-signin.xml`のみコピーします。

Github：https://github.com/azure-ad-b2c/samples/tree/master/policies/signup-signin-with-phone-number

また、日本の電話番号を登録できるよう、`policy/phone-signup-signin.xml`に記載されている`nationalNumber`の正規表現を`^[0-9]{1,10}$`から`^[0-9]{1,11}$`に変更します。

```xml
<ClaimType Id="nationalNumber">
  <DisplayName>Enter Phone Number</DisplayName>
  <DataType>string</DataType>
  <UserHelpText>Enter Phone Number</UserHelpText>
  <UserInputType>TextBox</UserInputType>
  <Restriction>
    <Pattern RegularExpression="^[0-9]{1,11}$" HelpText="" /> <!-- ここの正規表現を更新 -->
  </Restriction>
</ClaimType>
```

### 実行してみる
1. ユーザーフローやカスタムポリシーを実行すると、メールアドレス同様にログイン画面が表示されます。
    ※カスタムポリシーの場合デフォルトの国コードがSwedenになっているため、日本に切り替えます
![電話_zikkou-292e91c1-28fd-41d1-a7da-59581a4b9e74.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/dfdd46ed-56d0-7acb-b58c-ea4ce13e6b32.png)

1. ログインボタンを押下すると、このようにSMSまたは通話による確認画面が出てくるため、どちらかを選択し認証します。
   ![電話_実行2-76a6b32c-d8b1-42c2-8941-0c0587c32b91.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/0e8fa74f-fadc-ad32-d666-39479271365f.png)

1. 認証が成功すると、ログインが完了しトークンが取得できます。
   ![test-fbef28fa-997c-45e0-b5c9-2f1a25b91587.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/962964/51837cb4-aba0-2f61-c12b-d7eb2a7e8586.png)


## 制限事項
現状、メールアドレス/ユーザー名/電話番号でB2Cに登録したアカウントは、それぞれ別アカウント扱いとなります。
そのため、例えばTwitterのようにユーザー名とメールアドレスを統合させ同一アカウントとしてログインさせるといったことはできません。
電話番号に関しても同様で、MFAに使う電話番号と電話番号ログインに使う番号が同じであっても同一アカウントとして扱われません。


## まとめ
今回はメールアドレスだけでなく、ユーザー名や電話番号でB2Cにログインする方法をそれぞれご紹介しました。
また、Azure AD B2CではTwitterやGoogleなどの外部IDプロバイダーとの連携もサポートされており、GoogleやFacebookなどのアカウントでもログインが可能です。
こちらの記事ではLINEアカウントでのログインを記載していますので、合わせてご覧ください。

* [Azure AD B2CにLINEアカウントでログインする](https://qiita.com/AsukaSeki/items/c00087dfd04949ae6115)


## 関連記事
* [AD B2C記事まとめ](https://qiita.com/AsukaSeki/items/46afb6846cb4057b8050)