Azure ADをAWS Cognito Federated IdPに追加して、Amplify+Vueアプリでログインする（模索中）

#はじめに

Amplify + Vueで作ったアプリをAzure ADでログインする方法を模索した記録です。
初回認証後、CognitoのUserPoolに自動でプロビジョニングしてくれるみたいです。やったー。

しかしながら、フロントエンドの実装については未だに模索中です。。。

Amplify Libraryを使ってちゃんと実装したいのですが、今のところ見つけられてません。
\#ご存じの方がいらっしゃれば、アドバイスいただけますと幸いです(；´Д｀)

#登場人物と認証方式

Azure ADとCognito間がSAML、Cognitoとアプリ間がOAuthという間柄になります。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/459773f0-301c-694a-7380-1480bd1e151f.png)


#実際の手順
##1. AmplifyでUserPoolを設定

amplifyコマンドを実行して、UserPoolを設定します。
いったんおためしなので、リダイレクトURLはlocalhostにしました。設定後、amplify pushしておきます。

```terminal
$ amplify add auth
(省略）
 Do you want to use an OAuth flow? Yes
 What domain name prefix you want us to create for you? saml-app-login
 Enter your redirect signin URI: http://localhost:8080/
? Do you want to add another redirect signin URI No
 Enter your redirect signout URI: http://localhost:8080/
? Do you want to add another redirect signout URI No
 Select the OAuth flows enabled for this project. Authorization code grant
 Select the OAuth scopes enabled for this project. Email, OpenID, Profile, aws.cognito.signin.user.admin
 Select the social providers you want to configure for your user pool: 
? Do you want to configure Lambda Triggers for Cognito? No
Successfully added resource auth locally

```

##2. Azure ADでSAML設定

Azure Active Directory >> エンタープライズアプリケーションを選択し、New applicationをクリックします。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/0dc56759-41c8-9f41-60fe-1f3550ef83c1.png)


ギャラリー以外のアプリケーションを選択し、アプリケーションをAddします。
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/6f385dfe-e211-a69f-4423-6d6c848af3ec.png)

作成したアプリケーションのシングルサインオンを選択し、SAMLをクリックします。
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/ee3db2e5-d16f-d200-676d-5c8dcc9b5c8f.png)


基本的なSAML構成の編集アイコンをクリックして、以下を入力します。
識別子のフォーマット: urn:amazon:cognito:sp:**UserPoolID**
応答URLのフォーマット: https://**yourDomainPrefix**.auth.**yourRegion**.amazoncognito.com/saml2/idpresponse

![図4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/4724f812-1a3d-bc51-cba9-ec5cbe061354.png)

SAML署名証明書で、アプリのフェデレーション メタデータURLをコピーしておきます。
![図5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/a435382a-2b3c-d60e-deef-97e41cfc8fbb.png)

アプリを利用するユーザをアサインします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/a1daaed5-557e-9b2e-4e3b-db001a8b6bcc.png)

##3. CognitoコンソールからIdP設定

AWS Cognitoコンソールからユーザープールを選択します。
フェデレーション >> IDプロバイダー >> SAMLを選択して、プロバイダーを作成します。メタデータドキュメントは、先ほどコピーしたAzure ADのメタデータURLをセットします。
![図6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/4b437147-80d3-41aa-4275-4bc5d0cf1213.png)

属性マッピングで、Emailを設定します。
SAML属性は、以下を設定します。
http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress
![図7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/058cc536-1ce5-2efa-f9ba-864ca03d84f5.png)

アプリ統合 >> アプリクライアントの設定を選択して、有効な ID プロバイダをAzure ADにします。
![図8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/09d85048-fa1d-d61c-6c48-793dcc2c6a5e.png)


##4. 動かしてみる

ここまでで、認証基盤の設定は完了です。以下のURLを叩くと、動作確認できます。

https://**your_domain**/login?response_type=code&client_id=**your_app_client_id**&redirect_uri=**your_callback_url**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/5e299b7d-a59d-8c4e-c559-0443d1bbd286.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/645c9c41-4f4a-6b48-29bb-10867ddd1b57.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/3c786cb5-8fdb-0b57-1790-3bf6042e1243.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/0183ef9d-df37-5ba9-c4c3-9ed14ef2bd31.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/f72e2867-1c8b-2b57-eff5-47b06c74b056.png)

localhostにリダイレクトされます。今アプリは動いてないので、何も表示されなくてOKです。
URLの後ろに、認可コードが付与されていれば認証成功です。

AWS Cognitoコンソールから、ユーザーとグループを確認します。EXTERNAL_PROVIDERでユーザーが登録されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319797/c5df9155-f9c5-c39c-76c6-3725d297463a.png)

##5.フロントエンドで認証処理を実装する

あとは、認証を作り込むだけ！
なのですが、冒頭で書いたとおり、Amplify Libraryを使った実装方法が全くわからずorz

GitHubを見ると、[Enabling federation to AWS via Cognito User Pool using AD, ADFS, and SMAL2](https://github.com/aws-amplify/amplify-js/issues/1824)というIssueがあがっていました。こちらでも会話されていますが、フロントエンドのURLにリダイレクトされた後、Amplifyにログイン状態をセットする手立てがない？ようにみえます。

ちなみに、こんな感じで認証できないか試して見たのですが、リダイレクトループにハマってしまいました。
時折、ログインセッションがセットされるのですが、なんにせよ動きが非常に怪しいです。

```js
if (!currentUser) {
  // Hosted UIのソースをまねて呼んでみる
  window.location.href = 'https://hoge.auth.ap-northeast-1.amazoncognito.com/oauth2/authorize?identity_provider=AzureAD&redirect_uri=http://localhost:8080&response_type=CODE&client_id=xxxx&scope=aws.cognito.signin.user.admin email openid profile';
  /* or */
  // Amplify Libraryでそれっぽく呼んでみる
  Auth.federatedSignIn({provider: 'AzureAD'})
}

```

それ以外では、力技で乗り切る方法があります。

リダイレクト後に渡される認可コードを使って、自前でトークンエンドポイントとUSERINFOエンドポイントを呼び出し、ログイン情報をローカルストレージに保存する、という方法です。

こちらの記事を参考にさせていただきました！詳細は、こちらをご確認ください。
[【AWS】CognitoでGoogleソーシャルログイン。Amplifyと連携してVue.jsアプリケーションに組み込む](https://qiita.com/chitamano/items/d28f205ece7cbe46c02a)

* [トークンエンドポイント](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/token-endpoint.html)
* [USERINFO エンドポイント](https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/userinfo-endpoint.html)

#さいごに
Azure ADをCognito Federated IdPに追加してログインする方法についてまとめました。
認証は非常に重要なので、ある程度オフィシャルな情報を元に実装したく、Amplify Libraryの動きをウォッチしながら、何か分かれば続編を書きたいと思います。