Azure AD B2CにLINEアカウントでログインする

Azure AD B2Cでは、OpenID ConnectやSAML等のプロトコルで外部IDプロバイダーと連携することにより、FacebookやTwitter等のソーシャルアカウントでのログインが可能です。

参考：https://docs.microsoft.com/ja-jp/azure/active-directory-b2c/add-identity-provider

この記事ではOpenID Connectを使い、LINEアカウントでAD B2Cにログインする方法をご紹介します。

## Open ID Connectの設定（LINE）
参考：https://developers.line.biz/ja/docs/line-login/integrate-line-login/

### プロバイダーおよびチャネルの作成
1. [LINE Developers Console](https://developers.line.biz/console/)にアクセスし、新規プロバイダーを作成します。
   ![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/383dd7f2-607a-ce72-8722-0b7e15914474.png)

1. プロバイダーのチャネル設定から「LINEログイン」を選択します。
   ![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/ec9f3d05-11a7-edea-3f00-3cfdf03bdfb4.png)

1. チャネル名や管理者のメールアドレスなどの情報を入力し、作成します。
    * アプリタイプは「ウェブアプリ」を選択します。
      ![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/e65cfc07-9745-b9c8-1f58-78dec29dd974.png)
      ![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/6281d973-2d8a-01c8-6041-0df559ef0e00.png)

1. チャネル作成後、基本設定画面から以下の値を控えておきます。
    * チャネルID
    * チャネルシークレット
      ![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/063548f0-cd51-80fa-1974-f845dcd9ccb5.png)
      ![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/fbe6b459-9cf9-fb77-a563-1455e4d49a0b.png)

      
### [コールバックURLの作成](https://developers.line.biz/ja/docs/line-login/integrate-line-login/#setting-callback-url)
1. LINEログイン設定タブを表示し、「コールバックURL」に`https://your-tenant-name.b2clogin.com/your-tenant-name.onmicrosoft.com/oauth2/authresp`を設定します。
    * `your-tenant-name`の箇所はお使いのB2Cテナント名に置き換えてください。
  ![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/94f8da98-4b17-effe-d990-aea881d5d9d3.png)


### チャネルを公開する
チャネルは、デフォルトでは非公開の状態となっています。

非公開の場合、LINEログインできるユーザーはチャネルに招待済みのユーザーのみに限定されるため、他のLINEアカウントでログインするにはチャネルを公開する必要があります。

参考：https://developers.line.biz/ja/docs/line-login/getting-started/#step-6-publish-channel

チャネルの設定画面から、「非公開」のステータスを選択することで公開ができます。

※チャネルは公開から非公開には戻せないため、もし再度非公開にする場合はチャネルを作り直す必要があります。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/dd0f88f5-e014-36e6-4ab7-d30e6e362b65.png)


### [【補足】メールアドレスの取得権限の申請](https://developers.line.biz/ja/docs/line-login/integrate-line-login/#setting-callback-url)
LINEでは、Google等同様にログインユーザーのメールアドレスを取得し、B2Cに連携することが可能です。

ただしドキュメント内の以下の引用の通り、メールアドレスの取得にはメールアドレスの取得・利用について記載された文面を別途用意する必要があるとのことですので、今回は省略します。

> 申請条件に同意して、メールアドレスの取得と利用についてユーザーに提示する文面のスクリーンショットをアップロードします。

## カスタムIDPの設定（AD B2C）
B2Cの管理画面でLINEログインの設定を行います。
[汎用OpenId Connect](https://docs.microsoft.com/ja-jp/azure/active-directory-b2c/identity-provider-generic-openid-connect?pivots=b2c-user-flow)の設定を参考に、ユーザーフローおよびカスタムポリシーでの設定をご紹介します。

### ユーザーフロー
1. B2Cの管理画面のメニューから「IDプロバイダー」を選択し、「新しいOpen ID Connectプロバイダー」を選択します。
1. 設定画面で以下の情報を入力し保存します。
    * 名前：`LINE`（任意の名前で問題無し）
    * メタデータURL：`https://access.line.me/.well-known/openid-configuration`
    * クライアントID：[プロバイダーおよびチャネルの作成](#プロバイダーおよびチャネルの作成)で生成されたチャネルID
    * クライアントシークレット：[プロバイダーおよびチャネルの作成](#プロバイダーおよびチャネルの作成)で生成されたチャネルシークレット
    * スコープ：`openid profile`
    * 応答の種類：`code`
    * 応答モード：`form_post`
    * ユーザーID：`sub`
    * 表示名：`name`

     ![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/973f8f2f-8016-63f9-e866-c126d56f24b5.png)

1. 「サインアップとサインイン」のユーザーフローを作成します。
   ![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/2cb77ba4-2b4f-fd23-174b-ae3b94b4407e.png)


1. ユーザーフロー作成画面の「カスタムIDプロバイダー」は先ほど追加したIDプロバイダーを選択します。
   ![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/868be458-4201-878f-b3ba-d047631ea91a.png)


### カスタムポリシー
前提として、カスタムポリシーは下記URLの「SocialAccounts」のポリシーをベースとして説明します。

※下記のポリシーはFacebookログインを前提としておりますので、そちらの設定はあらかじめコメントアウトしてください。

https://github.com/Azure-Samples/active-directory-b2c-custom-policy-starterpack


1. B2C管理画面のポリシーキー設定から、以下のキーを追加します。
    * オプション：手動
    * 名前：`LINESecret`
    * シークレット：[プロバイダーおよびチャネルの作成](#プロバイダーおよびチャネルの作成)で生成されたチャネルシークレット
    * アクティブ化する日を設定する：未チェック
    * 有効期限を設定する：未チェック
    * キー使用法：署名

    ![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/25e0f443-9bf7-6122-6cf0-80cb9d1fc267.png)

1. ポリシーキーの一覧に「`B2C_1A_{シークレット名}`」が追加されるため、キー名を控えておきます。
    ![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/777c552b-b4e4-baa3-bb9f-e665979810b6.png)

1. カスタムポリシー`TrustFrameworkBase.xml`の`ClaimsProviders`配下に、LINEのIDプロバイダーを追加します。
    * `{クライアントID}`には、[プロバイダーおよびチャネルの作成](#プロバイダーおよびチャネルの作成)で生成されたチャネルIDを設定します。
    * `{シークレットキー名}`には、1.で追加したポリシーキー名を設定します。
    
    ```xml
    <ClaimsProvider>
      <Domain>line.me</Domain>
      <DisplayName>Login with LINE</DisplayName>
      <TechnicalProfiles>
        <TechnicalProfile Id="LINE-OpenIdConnect">
          <DisplayName>LINE</DisplayName>
          <Description>Login with your LINE account</Description>
          <Protocol Name="OpenIdConnect"/>
          <Metadata>
            <Item Key="METADATA">https://access.line.me/.well-known/openid-configuration</Item>
            <Item Key="client_id">{クライアントID}</Item>
            <Item Key="response_types">code</Item>
            <Item Key="scope">openid profile</Item>
            <Item Key="response_mode">form_post</Item>
            <Item Key="HttpBinding">POST</Item>
            <Item Key="UsePolicyInRedirectUri">false</Item>
          </Metadata>
          <CryptographicKeys>
            <Key Id="client_secret" StorageReferenceId="{シークレットキー名}" />
          </CryptographicKeys>
          <OutputClaims>
            <OutputClaim ClaimTypeReferenceId="issuerUserId" PartnerClaimType="sub"/>
            <OutputClaim ClaimTypeReferenceId="tenantId" PartnerClaimType="tid"/>
            <OutputClaim ClaimTypeReferenceId="givenName" PartnerClaimType="given_name" />
            <OutputClaim ClaimTypeReferenceId="surName" PartnerClaimType="family_name" />
            <OutputClaim ClaimTypeReferenceId="displayName" PartnerClaimType="name" />
            <OutputClaim ClaimTypeReferenceId="email" PartnerClaimType="email" />
            <OutputClaim ClaimTypeReferenceId="authenticationSource" DefaultValue="socialIdpAuthentication" AlwaysUseDefaultValue="true" />
            <OutputClaim ClaimTypeReferenceId="identityProvider" DefaultValue="line.me" />
          </OutputClaims>
          <OutputClaimsTransformations>
            <OutputClaimsTransformation ReferenceId="CreateRandomUPNUserName" />
            <OutputClaimsTransformation ReferenceId="CreateUserPrincipalName" />
            <OutputClaimsTransformation ReferenceId="CreateAlternativeSecurityId" />
            <OutputClaimsTransformation ReferenceId="CreateSubjectClaimFromAlternativeSecurityId" />
          </OutputClaimsTransformations>
          <UseTechnicalProfileForSessionManagement ReferenceId="SM-SocialLogin" />
        </TechnicalProfile>
      </TechnicalProfiles>
    </ClaimsProvider>
    ```
1. カスタムポリシー`TrustFrameworkBase.xml`の`UserJourney`にIDプロバイダーを設定します。
    * UserJourneys配下の、`SignUpOrSignIn`のうち、Step1の`ClaimsProviderSelections`、Step2の`ClaimsExchanges`配下に、IDプロバイダーの設定を追加します。
    
        ```xml
        <UserJourney Id="SignUpOrSignIn">
          <OrchestrationSteps>
            <OrchestrationStep Order="1" Type="CombinedSignInAndSignUp" ContentDefinitionReferenceId="api.signuporsignin">
              <ClaimsProviderSelections>
                <ClaimsProviderSelection TargetClaimsExchangeId="LINEExchange" />
                ...
              </ClaimsProviderSelections>
              ...
            </OrchestrationStep>
            <OrchestrationStep Order="2" Type="ClaimsExchange">
              ...
              <ClaimsExchanges>
                <ClaimsExchange Id="LINEExchange" TechnicalProfileReferenceId="LINE-OpenIdConnect" />
                ...
              </ClaimsExchanges>
            </OrchestrationStep>
          </OrchestrationSteps>
          ...
        </UserJourney>
        ```

1. 以下の順にカスタムポリシーをアップロードします。
    1. TrustFrameworkBase.xml
    1. TrustFrameworkLocalization.xml
    1. TrustFrameworkExtensions.xml
    1. SignUpOrSignin.xml


### 動作確認
これでLINEログインの設定は完了です。

ポリシーを実行してみます。

1. フローを実行すると、LINEログイン画面が表示されます。
   ![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/abc47ea2-ac39-d134-bb9d-c7340cf529bd.png)


1. QRコードログインを試してみます。
   ![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/85a8a900-5574-bb2f-c761-2834ee47fc05.png)


1. LINEアプリで画面に表示された本人確認のコードを入力します。
   ![16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/000743fe-293b-24f5-edb6-dd1111c9c1de.png)


1. 初回ログイン時はB2C側の画面に遷移し、ユーザー情報の入力画面になります。
    * 「ユーザー名」の箇所は、LINEのユーザー名になっていることがわかります。

     ![17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/bef860ff-c8c4-1335-f6ab-509a69fb97fb.png)

1. Createボタンを押すと認証完了です！このようにトークンが発行されました。
   ![18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398865/4be054c8-9221-bcf8-128c-09f9d17c8452.png)


## まとめ
今回はOpenID Connectを利用し、LINEアカウントでAzure AD B2Cにログインする方法をご紹介しました。

また、B2C側では汎用OpenID Connectの設定を行っているため、OpenID Connectがサポートされている他の外部IDプロバイダーでも同様の方法で連携が可能です。

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