Mark Hammer's Blog

SalesforceやTrailheadに関する情報を投稿しているブログです。

Salesforce MFAの紐づけをシステム管理者が代行する方法を考えてみた

(この投稿はSalesforce Advent Calendar 2021の12日目です) qiita.com

どうも、Mark Hammerです。
そういえば今日はSalesforce ハッカソン 2021の発表日ですね。
どういった成果物が出てくるのか楽しみに見たいと思います。

developer.salesforce.com

はじめに

2021年、Salesforce界隈を騒がせたMFA必須化。
皆さん2022/2/1の必須化開始に向けてアプリのインストールや機器の購入、社内調整等で大変かと思います。

私はTrailblazer CommunityのMFAに関するグループをたまに眺めているのですが、そこで出てくるのが「ユーザがMFAアプリを登録するのではなくシステム管理者が登録することはできないのか」という質問。
ちなみにSalesforce AuthenticatorやGoogle Authenticator等サードパーティアプリを使用する場合、以下の流れになります。

  1. 事前にSalesforceの私の設定画面でSalesforce AuthenticatorかGoogle Authenticator等サードパーティアプリの紐づけを行う。
  2. Salesforceログイン時にMFAを必須にする設定を行う。
  3. 2.設定後にSalesforceにログインした際に表示される認証画面で紐づけしたアプリを使用して認証する。

ここで必ずユーザが実施しなければならない作業が1.の紐づけなのですが、これをシステム管理者が代行できるとすれば、以下の要件を満たす必要があると考えます。

  1. ユーザの持つアプリを特定できる情報をSalesforce側にインポートできる。
  2. 1.でインポートした際にユーザの持つアプリに自動でSalesforce認証用情報が登録される。

しかし1.のインポートといっても、Salesforce Authenticator紐づけの際は英単語2個、サードパーティアプリ紐づけの際はSalesforce側に表示されるQRコードか認証コードを用いる必要があるため、アプリ側の情報をSalesforce側にインポートできるように見えません。
2. に至ってはアプリ側の操作なしに自動でSalesforce認証用情報が登録されるというのは無理があるように見えます。
よって、「頑張ってユーザに紐づけ操作してもらってください。」というのが今までの認識でした。

Secretコードによる認証アプリの紐づけ

この認識が変わったのは2021/11/4に行われたMFA FAQの更新です。(日本語版FAQには投稿時点で未反映)
「What are third-party TOTP authenticator apps?」にて、Salesforceにハードウェアトークンを登録できるとの情報が記載されました。
そこに記載されていた説明文では、データローダ等でTwoFactorInfoオブジェクトに対しSecretコードをインポートできるとの記載がありました。

To associate a hardware token with a user, insert a TwoFactorInfo object into the database, as described in the Salesforce Object Reference. You need to provide the Secret, the user's ID, and specify the Type field as 'TOTP'. You can use the Data Loader, Workbench, or custom Apex to insert TwoFactorInfo objects into the database.

おそらくハードウェアトークンであればSecretコードは製品のどこかに記載があるのだと思います。
ではアプリ紐づけの際に使えるSecretコードを取得することはできないのだろうか、と情報を探しました。
そして、ApexのSessionManagement クラスにて、 getQrCode() 関数の存在を知りました。

Apex 開発者ガイド:SessionManagement クラス より抜粋

getQrCode()
多要素認証 (MFA) 用の認証アプリケーションまたはデバイスを設定するための、QR (Quick Response) コードと時間ベースのワンタイムパスワード (TOTP) の共有秘密への URL が含まれる対応付けを返します。

これで、特定のSecretコードを認証アプリに登録するためのQRコードを発行できるURLを入手できました。

(匿名 Apex コード)
Map<String, String> codeResult = Auth.SessionManagement.getQrCode();
String result = 'URL: '+codeResult.get('qrCodeUrl') + ' SECRET:  ' + codeResult.get('secret');
System.debug(result);

(Output)
USER_DEBUG [3]|DEBUG|URL: https://sampledomain.my.salesforce.com/secur/qrCode?w=200&h=200&t=tf&u=sample%40example.com&s=3C2IC7JFL7SXMGSQSMLTJKFIZSXJOXG0 SECRET:  3C2IC7JFL7SXMGSQSMLTJKFIZSXJOXG0

このURLの secret 部分は英数字であれば書き換えても利用可能です。
これを利用して、Salesforceへの認証アプリ登録をシステム管理者が実施することが可能になりました。

システム管理者が認証アプリを紐づけする手順

データローダでの作業

※作業前に、システム管理者に「API で多要素認証を管理」権限を付与する必要があります。
この権限は「システム管理者」標準プロファイルにはないため、カスタムプロファイルか権限セットで付与してください。

UserId Type SharedKey
005xxYYYYYzzzzz*1 TOTP 0Z1Z2Z3Z4Z5Z6Z7Z8Z9Z0Z1Z2Z3Z4Z5Z*2
  • データローダ等を用いて「2要素情報(TwoFactorInfo)」オブジェクトにInsertを行う。
    • データローダ利用の際はオブジェクト選択時に「Show all Salesforce objects」にチェックを入れること。
    • Insert成功時、紐づけ先ユーザには「Salesforce アカウントに新しい検証方法が追加されました」というメールが届くため、事前にユーザに説明が必要。

ユーザへのQRコード提示

上記作業はあくまでSalesforce側への登録のため、これだけではユーザが持つアプリにSalesforce認証用の情報が入りません。
そのため、以下URLやSecretコードを連携してアプリに登録してもらいます。

メリットとデメリット

この方法のメリットとデメリットは以下の通りです。

  • メリット
    • ユーザが行うのは認証アプリでのQRコードの撮影、またはコード入力のみ。Salesforceの画面操作は不要。
    • QRコード撮影による登録の場合、アプリに表示する識別用文字列を自由に変更できる。*3
    • 極論、端末さえ貸してもらえればユーザのパスワードやメールで届く認証コードなしで多要素認証のアプリ紐づけが可能なのでシステム管理者のみの作業で済む。
  • デメリット
    • ユーザがアプリへの紐づけ登録を行わずに多要素認証を有効化した場合、Salesforceにログインできない状況が発生する。
      • この場合は一旦システム管理者がSalesforce側のアプリ接続を削除するしかない。
    • ユーザがアプリへの紐づけ登録をしたか否かはシステム管理者含む他の人には分からない*4ので、いちいちユーザに登録状況を確認する必要があり、面倒。
    • この方法で登録できるのはワンタイムパスワード認証(TOTP)のみで、Salesforce Authenticatorやセキュリティキーの登録はできない。

個人的には、この方法は「システム管理者が登録を代行したい」という要望がなければ考えない方法であり、あまり有用とは思っていません。
ただ、「こういう方法もあるよ」ということで今回投稿してみました。

悪い例:セキュリティ強度が落ちる紐づけ

通常、TwoFactorInfoオブジェクトに登録する SharedKey (Secretコード)はユーザごとに異なるのですが、 SharedKey 項目にはユニーク制約がないので、複数のユーザに同じSecretコードを設定することができます。
また、複数の認証アプリに同じSecretコードを設定すると、(当然ながら)同じ6桁の認証コードが表示されます。

つまり、以下のような設定も可能なわけです。

  • TwoFactorInfoオブジェクトへのインポートで、全ユーザに同じ SharedKey (Secretコード)を設定する。
  • ユーザのアプリ紐づけ用QRコードのURL、コードを1つ作成し、全ユーザに連携する。
    • URLの u パラメータは会社名などにする。
  • 全ユーザの認証アプリに表示される認証コードは同一のため、自分の端末を失くしても他の人の端末(認証アプリ)があれば認証できる。

…まぁこれは多要素認証の意味がなくなる設定なので、やったらダメですよ。

おわりに

TwoFactorInfoオブジェクトの存在から、MFAの紐づけをシステム管理者がどこまで代行できるか考えてみましたが、最終的なアプリの紐づけはユーザに実施してもらう必要がある*5以上、従来通りSalesforceの「私の設定」から紐づけしてもらうのが一番楽ではないか、という結論になりました。
ただ複数の方法を知っていることは何かの役に立つかもしれませんので、この投稿が(悪い例以外で)お役に立てれば幸いです。

追記:代理ログインによるMFA紐づけ代行

今回の調査を行った後に、システム管理者が他のユーザに代理ログインし、アプリ紐づけができるか試したところできることが分かりました。なので、この方法でもユーザのパスワードなしでMFA紐づけを代行することは可能です。
ただ、代理ログインでのアプリ紐づけの場合、ユーザ確認として確認コードのメール送信か、既に紐づけ済みのアプリによる認証が行われます。
通常アプリ紐づけは初回になるかと思いますので、ユーザに確認コードのメールを転送してもらう必要があります。

*1:紐づけしたいユーザID

*2:Secretコード

*3:従来のSalesforce画面で登録する場合、識別用文字列はユーザ名固定

*4:レポートやユーザ画面ではSalesforce上の紐づけ状況しか確認できないので、今回の方法ではアプリ紐づけ状況が分からない

*5:前述の通り端末を貸してもらえればユーザのパスワードなしに紐づけ代行はできますが、そこまでするシステム管理者はいないと思います