MotionBoardの多要素認証
最近ではWEBアプリケーション利用時にMFA(多要素認証)を行なうことが一般的になっています。WEBアプリケーションの利用が日常的になるにつれてパスワード漏洩による不正ログインの影響が大きくなっており、場合によってはMFAの利用が必須のものもあります。
当社のMotionBoard Cloudでも、現在はEメールで送信する認証コードを使った二要素認証に対応しています。
しかし、Eメールだけではなく、SMSや認証アプリを使ったMFAを使いたい、使わなければならないという要件も当然あると思います。
この記事では、AWS Cognitoを使ってそれらのMFAを実装する方法について解説します。
AWS Cognitoとは?
AWS Cognitoの深い説明は他の記事に譲りますが、いわゆる認証基盤として使えるものと捉えていただいて大丈夫です。
二要素認証を行なう設定
ユーザープールの作成
コンソールからCognitoにアクセスしてユーザープールを作成します。
アプリケーションのリソースを設定する
まずアプリケーションを設定します。
○SMSを使った多要素認証をしたい場合
「phone_number」を設定してください。
○Eメールか認証アプリを使った多要素認証をしたい場合
「email」を設定してください。
○MotionBoardのユーザーIDとしてメールアドレスを使いたい場合
「email」を設定してください。
○MotionBoardのユーザーIDとして任意のユーザーIDを使いたい場合
「name」を設定してください。
なにが超重要かというと、必須属性として「phone_number」を設定してこのあとのSMS設定を構築した場合、認証方式がSMSに限定され、Eメールや認証アプリが使えなくなります。
そんな馬鹿な……という感じですが、どうも間違いなさそうで、以下のMFA判定ロジックに明記があるほか、AWSサポートにも個別に確認し回答を得ています。少なくとも現時点ではCognitoの仕様がそうだということになります。
今回はSMS固定で構わないので、「phone_number」と、ユーザーIDとして任意の文字列を使用したいので「name」を必須属性として設定します。
一回作成してみて使用感が違ったらもう一度ユーザープールの作成からやり直せば解決するので、そんなに深刻ということでもありません。
なお、ここで解説している内容はMotionBoard Cloudだけでなく、オンプレのMotionBoardにも適用可能です。ただし、リターンURLにはhttpsしか許可されていないことに注意してください。自社サーバーでMotionBoardを構築している場合は、httpsのURLでアクセスできる経路が必要です。

ユーザープール作成後の画面です。アプリケーションに適用するためのサンプルコードが提示されています。
今回はMotionBoard側で予め機能が用意されているので、利用しません。
ページ最下部の「概要へ移動」を押してください。
ユーザープールの設定

作成したユーザープールの設定を行ないます。
左側のペインから各メニューを見てみましょう。
アプリケーションクライアント

先ほど作成した「アプリケーションクライアント」です。
アプリケーションのクライアントIDとクライアントシークレットはここから確認します。
ユーザー管理

(この)Cognitoユーザープールでのユーザーを管理します。
ユーザーを作成しましょう。

書かれている内容は難しくないはずです。
仮パスワードは、今回はCognitoに自動で作成させていますが、任意の値を設定することもできます。
なお、この登録画面には必須属性として設定したはずの「name」の入力欄がありません。
どうやら管理者がコンソールでユーザーを作成する際には必須入力にはならないようです。
作成したユーザーを選択し、属性の編集で「name」属性を追加して、MotionBoardで登録したいユーザーIDを入力しておいてください。
認証方法

認証方法の設定では、「Eメール」「SMS」ごとに必要な設定を行ないます。
Eメール

Eメールは、ユーザーの登録の招待、パスワードリセット、多要素認証の要素として使用します。
Eメールプロバイダーには、Amazon SESを使うかCognitoに内包された設定を使うかを選べますが、後者はテスト用のため、1日50通に限定されるようです。SESの構築はやや敷居が高いので、検証目的や小規模の場合は「CognitoでEメールを送信」のほうが断然簡単です。
ただし、ここも重要です。
まず、多要素認証の要素として使う場合、すなわちメールアドレスあてに認証コードを送信してほしい場合、SESの設定が必須です。
また、「送信者の名前 – オプション」とあるのは、状況によってはオプションではなく必須入力項目になります。
おそらくですが、SESでEメールアドレスの検証を済ませていれば、「送信元のEメールアドレス」にそれを設定すればよいのですが、ドメインのみ検証している場合は、「送信元のEメールアドレス」に設定できるのはドメインだけです。その場合に、別途送信元のメールアドレスを設定する必要があり、それを「送信者の名前 – オプション」に設定しなければならないということだと思います。
正しく設定されていないと、次のエラーが発生します。
(なお、このエラーは昔の設定画面だと、違うメッセージで、ユーザープール作成の際のいちばん最後で発生していたため、原因を掴みづらかったです。私はそれで30分無駄にしたことがあります……。)
SMS
こちらはSMSを使った多要素認証で必要です。
Amazon SNSを使用するわけですが、SESよりは敷居が低く、SNSが許可されたIAMロールが既存で存在しない場合は、この画面で作成することもできます。必要な設定も明示的に書かれていて、しかも「 現時点でこれを完了しない場合は、後ほどリマインダーを表示します。」とのこと。
ただし、設定は直感的でも、設定の結果起こることは直感的ではありません。
上述したように、ユーザーの属性に「phone_number」が登録されていて、かつこのSMS設定を終わらせると、MFAの認証方式が自動的にSMSに固定され、他の方法を選択できません。
サインイン

サインインで必ず設定しなければいけないのは、多要素認証です。
多要素認証
多要素認証をするためのCognitoなので、ここは「MFAを必須にする」を確実に選択してください。
「MFAの方法」は好きなものを選べばいいのですが、SMSメッセージが選択状態のままグレーアウトしていることがおわかりいただけるでしょうか。
これが先ほどから繰り返し述べている「認証方式がSMSで固定される状態」の一因です。この状態でユーザーの属性に電話番号が登録されている場合、たとえEメールメッセージにチェックを入れていたとしても確認することなくSMSに認証コードを送りつけてきます。
試しに「Authenticateアプリケーション」「Eメールメッセージ」両方ともチェックを入れておきましょうか。
ユーザーアカウントの復旧を編集
こちらは任意です。
いわゆる、「パスワードを忘れた方はこちら」を有効化するか無効化するかを設定します。無効化した場合、パスワードのリセット操作などは全てCognito管理者が行なうことになります。
ONにしておきます。
サインアップ

認証基盤として使う以上、サインアップも考える必要があります。
セルフサービスのサインアップ
管理者以外の任意のユーザーが自分でサインアップ(ユーザー登録)できるようにするか否かを設定します。Cognitoでサインアップすると、後で操作するMotionBoardの設定によっては自動的にMotionBoardにもユーザーが作成されます。
仮にユーザーアカウントが自動作成されたとしても、MotionBoardの場合は別途指名ユーザーの登録をする必要があるので、これをONにしたからといって自動的にMotionBoardにログインできるようになるわけではありません。
そのため仮に第三者がCognitoにアクセスできる設定にしていたとしてもそれが即秘密情報の漏洩には繋がるわけではありませんが、必要と思わなかったらOFFにしておきましょう。
自己登録が有効ではない場合はCognito管理者がユーザーIDの管理を行なうことになります。
属性検証とユーザーアカウントの確認
セルフサービスのサインアップを有効にする場合は、Cognitoにどの程度属性の検証を任せるかを設定できます。
ユーザーが入力したメールアドレスや電話番号に発信してCognito側で検証フローを完了するか、Cognito管理者が一つひとつ検証して承認するかです。
好きなほうを選んでください。
ドメイン

Cognitoへのログインのためのドメインを設定します。
ユーザープールIDとリージョンの固有値、およびサービス名を組み合わせたドメインが最初から登録されています。
もしログインページの要件でドメインが指定されている場合は、カスタムドメインを設定することもできます。
カスタムドメインの設定には、当然ながら証明書とDNSレコードが必要です。
AWS Cognitoで設定してほしい内容は以上です。
次に、MotionBoardの設定に移ります。
MotionBoardの設定
ドメインの作成
MotionBoardでは、まずは[管理]-[システム設定]-[接続/認証]-[認証]から、ドメインを作成してください。
「外部認証名」は任意の名称で大丈夫です。
「外部認証タイプ」は「OpenID」を選択してください。
さらに、[ドメイン設定]で「新規作成」し、ドメインを追加します。ドメインIDは自動的に「openid」になるはずです。
シングルサインオンの設定
シングルサインオンは、[管理]-[システム設定]-[接続/認証]-[シングルサインオン]で設定します。
[OpenID連携]にチェックの上、以下を設定します。

<cognitoドメイン>/login
を入力します。
今回は
https://ap-northeast-1oen0zvnk9.auth.ap-northeast-1.amazoncognito.com/login
です。
<cognitoドメイン>/oauth2/token
を入力します。
今回は
https://ap-northeast-1oen0zvnk9.auth.ap-northeast-1.amazoncognito.com/oauth2/token
です。
この2つはアプリケーションクライアントの設定にありましたね。

署名鍵は[認証]ー[ソーシャルプロバイダーと外部プロバイダー]にあります。
「署名証明書を表示」から.crtとしてダウンロードしてください。
初期設定では「sub」となっています。
「sub」はCognitoのコンソールでユーザー情報を確認するとわかります。
OpenIDで標準で用いられる一意のIDと思いますが、その値から特定個人を特定するのが難しいので、ここは「name」で設定しています。このため、必須属性に「name」を追加したわけです。
ここにチェックを入れると、MotionBoardのドメイン「openid」に、Cognitoでログインしたユーザーが自動的に追加されます。
ドメインマッピングは、MotionBoardのドメインと、外部認証システムのドメインをマッピングする設定です。
MotionBoardの「openid」ドメインと、Cognitoの「ap-northeast-1oen0zvnk9.auth.ap-northeast-1.amazoncognito.com」をマッピングしてください。
ユーザーの作成
最後に、MotionBoardのユーザーを作成します。
ドメイン「openid」にユーザーを作成してください。
ユーザーIDは、先にname属性で設定した値にします。
最後に、指名ユーザーの設定を行ないます。
指名ユーザーの設定が行なわれていないと、MotionBoardへのSSO時に403エラーが発生します。
ここはエラーの原因がわかりづらいので、指名ユーザーの設定は忘れないようにしてください。

指名ユーザーの設定をしていないと403エラーが返ります
指名ユーザーの設定を行なえば、全ての設定が完了です。
お疲れ様でした。
動作確認
シングルサインオン
動作確認しましょう。
次のURLにWEBブラウザでアクセスしてください。
https://cloud.motionboard.jp/motionboard/sso/openid?tenant=<テナントID>
Cognitoのデフォルトのログイン画面にリダイレクトされます。
Cognitoで設定したIDとPWを入力してください。

Sing inすると、次にSMSでメッセージが送信されます。

SMSで届いたコードを入力して再度Sing inをクリックすることで、MotionBoard Cloudにログインされます。

Cognitoのログイン画面でサインアップ
CognitoでサインアップしてMotionBoardにユーザーが追加される挙動を確認しましょう。
ログイン画面でSing inではなく、Create an accountをクリックします。

必要な属性を入力してSign upを選択します。
なお、Phone numberとNameの入力欄があるのはこれらを必須属性として設定しているからです。
電話番号の確認プロセスがあります。
SMSに届いたコードを入力すると、そのままサインインプロセスが始まり、

指名ユーザーが設定されていないので403的な画面が返されますが、

MotionBoardのopenidドメインにはユーザーが追加されています。
おわりに
以上の設定でSMSを使った二要素認証がMotionBoard Cloudで行なえるようになります。認証要件にMotionBoardの機能だけで対応できなくても、MotionBoardの利用を諦める必要はありません。
皆様もぜひよきデータ分析ライフをお過ごしください。
おまけ
おまけ1
任意のユーザーがCognitoにサインアップする際に、Lambdaでカスタムアクションの設定をすることも可能です。これを使えば、たとえばサインアップ時にユーザー入力値の有効性を判定して、MotionBoardの指名ユーザーの設定その他をAPI実行できるので、サインアップからシームレスにMotionBoardのログインを行なわせることもできそうです。
おまけ2
Cognitoのユーザープール作成時、「Phone_number」を必須属性にせず、「email」を必須属性にした場合、EメールでのMFAが実施できるほか、ユーザーが自分自身で「SMS」か「認証アプリ」のどちらがいいかを選択させることもできます。
必須属性を「email」にしたユーザープール作成後、多要素認証で「SMS」「Authenticatorアプリケーション」の2つを選んでください。ユーザーのログイン時に、MFAの構成画面に遷移します。
