[小ネタ] Auth0で初回からメールをMFAファクターとして利用できないか検証してみる

2020.01.09

こんにちは、森です。

多要素認証(MFA)はもはや認証において不可欠なものとなっています。ただ、端末をなくしてしまったり、充電がなくなってMFAコードの確認ができずアプリにログインできなくなったということもあるかと思います。

このような時のためにAuth0は昨年EmailによるMFAをサポートしました。

No Phone? No Problem! Email MFA Is Here

現状、EmailによるMFAはバックアップMFA要素としてサポートされており、単体では使用できませんが、単体で使用することができるようにAuth0ロードマップにはあるとのことです。

EメールMFAを使用する条件

Auth0でEメールMFAを使用するにはいくつか条件があります。

ドキュメント上では

ユーザーは、メールMFAに明示的に登録する必要はありません。確認済みの電子メールがあると、使用できるようになります。これは、電子メール検証フローを完了したとき、Management APIを使用してemail_verifiedフィールドを更新したとき、または検証済み電子メールを提供する接続(Googleなど)でログインしたときに発生します。

と書かれていますが、実践上、他のMFAでログインしないとメールMFAの選択ができませんでした。

今回は、いきなりメールをMFAとして使用することができないか検証していきたいと思います。 尚、Auth0のアプリケーション、ユーザー登録に関しては、すでにあるものとします。

やってみる

公式ドキュメントの Associate an Email Authenticator を参考にしていきます。

前提

今回はトークン要求の際、リソース所有者パスワード付与(ROPG)フロー(ユーザーのユーザー名とパスワードがアクセストークンと直接交換される)を使ってAPIアクセスを行います。

  • Auth0でAPIを登録する
    • APIの登録 を参考に作成しておきます
    • 識別子、scopeが必要になります
  • テナント設定->General->API Authorization Settingsで、Default AudienceDefault Directoryを設定します
    • Default Audience: 作成したAPIの識別子
    • Default Directory: Username-Password-Authentication
  • オーセンティケーターの関連付けを行なっていないユーザーを用意する

1. メール認証システムを有効にする

Auth0ダッシュボードの [多要素認証]セクションで有効にします。

尚、この状態でEmailのみを有効にしようとすると、以下のエラーが出ます。

Error! Please disable the email factor before disabling One-time Password.

同ページにある [Always require Multi-factor Authentication] も有効にしておきます。

2. MFAトークンを取得する

認証APIを使用し、MFAトークンを取得します。

以下の例では、パスワードを付与してログインを試みています。

$ curl --location --request POST 'https://onefit.auth0.com/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'username=[login_user_name]' \
--data-urlencode 'password=[login_passwd]' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'audience=[前提で作成したAPIの識別子]' \
--data-urlencode 'client_id=[your_application_client_id]' \
--data-urlencode 'client_secret=[your_application_client_secret]' \
--data-urlencode 'scope=[前提で作成したAPIのscope]'

実行後、

Grant type 'password' not allowed for the client.

というエラーが出た場合は、Auth0のダッシュボードで、アプリケーションの詳細設定>Grant Types を選択して、 Passwordにチェックを入れてください。この後に必要になるので、MFAにもチェックを入れます。

上記エラーが解消されていると、以下のようなレスポンスが返ってきます。MFAを有効にしているので、このエラーが出ます。

{
    "error": "mfa_required",
    "error_description": "Multifactor authentication required",
    "mfa_token": "Fe26.2~~~~"
}

mfa_tokenを次の手順以降に使用します。

3. 認証システムの関連付けを要求する

MFA APIを使い、Emailをオーセンティケーターとして関連付けるようにします。

$ curl --location --request POST 'https://[your_domain]/mfa/associate' \
--header 'authorization: Bearer [2で返却されたMFA Token]' \
--header 'Content-Type: application/json' \
--data-raw '{"authenticator_types": ["oob"], "oob_channels": ["email"], "email": "[MFAで使用したいEmail]"}'

成功すると、

{
    "authenticator_type": "oob",
    "binding_method": "prompt",
    "recovery_codes": [
        "***********************"
    ],
    "oob_channel": "email",
    "oob_code": "Fe26.2~~~~~~~"
}

が返却されます。

oob_codeを次の手順以降に使用します。

初めて要求した場合は、recovery_codesが返却内容に含まれます。

このrecovery_codesは必ず控えておきましょう。

4. 認証システムの登録を完了させる

3の関連付けが終わっていると、指定したメールアドレスにMFAのコードが届いでいるはずです。それを使って再度認証してみます。

$ curl --location --request POST 'https://[your_domain]/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=http://auth0.com/oauth/grant-type/mfa-oob' \
--data-urlencode 'mfa_token=[2で返却されたMFA Token]' \
--data-urlencode 'oob_code=[3で返却されたoob Code]' \
--data-urlencode 'binding_code=[メールに送られてきたMFA Code]' \
--data-urlencode 'client_id=[your_application_client_id]' \
--data-urlencode 'client_secret=[your_application_client_secret]'

認証に成功すると、

{
    "access_token": "eyJ~~~~~~~~~",
    "scope": "read:sample",
    "expires_in": 86400,
    "token_type": "Bearer"
}

アクセストークンを含む結果が返ってきます。

Auth0のダッシュボードで、今回検証を行なったユーザーを確認してみます。 Users & Roles > Users > 対象ユーザー > Details をみると Multi-Factor Authentication の欄に先ほど関連付けを行なったEmailとRecovery codeが表示されていることがわかります。

5. ブラウザからログインを試みてみる

MFA Emailの関連付けを終え、認証を一回完了しているので、ブラウザを立ち上げてWebUIでEmail MFAが使えるようになっているか確認してみます。

まずはAuth0で作ったアプリケーションにログインします。 成功すると、、、

MFA用に登録したメールアドレスで認証ができるようになっていました。あとはメールに送られてきたコードを確認したら、通常どおり認証を続行するだけです。

まとめ

初回の認証時からEmailをMFAファクターとして使えないか検証してみました。結果として、APIを利用することにより可能となりましたが、

Auth0のEmail MFAは現状、MFAファクターのバックアップ目的になっております。他のMFAファクターと組み合わせて使うことをお勧めします。

参考