[Salesforce] OAuthを利用する「認証プロバイダ」を作成して、指定ログイン情報と外部データソースを定義したい

Salesforce では、Apexなどで利用できる[指定ログイン情報](https://help.salesforce.com/articleView?id=named_credentials_about.htm&type=5)をはじめ、[外部オブジェクト(Salesforce Connect)](https://developer.salesforce.com/docs/atlas.ja-jp.object_reference.meta/object_reference/sforce_api_objects_external_objects.htm)や[Files Connect](https://help.salesforce.com/articleView?id=collab_admin_files_connect.htm&type=5)などなど、シングルサインオンや外部Webシステムへと接続するための[認証プロバイダ](https://help.salesforce.com/articleView?id=sso_authentication_providers.htm&type=5)という機能を提供しています。認証に携わる部分を集約することで、管理の一元化と単純化につながりお便利です。

なんですが、OAuth での接続をする場合に少しだけくせがあるので、その設定について説明します。今回は例として、Salesforceクロス組織接続のケースです。無償で提供される、Salesforceの開発環境が二つあれば実現できますよと言うことです。みなさん、どうぞお使いください。

手順としてはこうなります。

1. (接続される側)接続アプリケーションの作成
2. (接続する側)認証プロバイダの作成
3. (接続される側)接続アプリケーションの編集
4. (接続する側)指定ログイン情報/外部データソースの作成

という手順になります。行ったり来たりになるのは理由があるからなんですΩ ΩΩ< な、なんだってー!!

# 1. (接続される側)接続アプリケーションの作成

まずは接続される側で[接続アプリケーション](https://help.salesforce.com/articleView?id=connected_app_overview.htm&type=5)を作成します。データアクセスを提供する側のSalesforceが、アクセス可能なユーザの制御や、利用できるAPIなどの制御を行うための設定です。まずこれがないと話になりません。

Salesforceの[設定](https://trailhead.salesforce.com/ja/content/learn/modules/starting_force_com/starting_tour?trail_id=force_com_admin_beginner)ページから操作します。`クイック検索`から「アプリケーション」とかで検索するか、`アプリケーション`カテゴリから、`アプリケーションマネージャ`をクリックします。

![Screen Shot 2020-12-30 at 10.59.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/2341fdca-f4eb-5174-11b1-b94ce525a963.png)

おもむろに右上の`新規接続アプリケーション`をクリックしましょう。もう一つある`新規Lightningアプリケーション`ではありません。あしからず。`新規接続アプリケーション`です。右側です。

![Screen Shot 2020-12-30 at 11.01.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/4980c639-7f0b-8ab6-cf0e-524b741014a0.png)

## 新規接続アプリケーション作成時の入力項目

`OAuth`で接続される場合には、基本情報の入力必須項目以外に`OAuth 設定の有効化`が必要です。逆に言えば、そこさえ設定すれば良いです。

|設定項目|設定する内容|
|---|---|
|接続アプリケーション名|人様が識別するための名前です。分かれば何でも良いです。識別できれば|
|API 参照名|APIで参照するときに使う名前です。必ず英語です。アンスコも使えます。数字もいけた気がします|
|取引先責任者 メール|この接続アプリを管理する人のメアド入れておきます。なんかあると通知されます|
|コールバック URL|今は何でもいいです。`https://` で始まる何か適当なURLをいれます|
|選択した OAuth 範囲|利用させるOAuthのスコープを定義します。考えるのが面倒なテストの時は`full`と`refresh_token`があれば良いです。`refresh_token`は`full`に含まれないのでぜったに設定が必要です|

![Screen Shot 2020-12-30 at 11.05.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/9f1788c3-0496-8a69-8753-4f273e851e3c.png)

あとはひとまずデフォルトで良いです。なお、`Salesforce Connect`を利用する場合の最低限のOAuthスコープは、ここにもあるとおり次の四つです。

1. Web 経由のデータへのアクセスを提供 (web)
2. データへのアクセスと管理 (api)
3. 基本情報へのアクセス (id, profile, email, address, phone)
4. **ユーザに代わっていつでも要求を実行** (refresh_token, offline_access)

**refresh_token** は重要です。ここまで入力したら「保存」します。サーバ上で設定が有効になるまで2〜10分待てと出てきますが、大抵すぐ使えます。たまにめっちゃ時間かかります。

## 設定に必要な項目のメモ(コピペする用)

あとで、認証プロバイダを作成するときに必要な次の項目をメモしておきます。どっかに一時的にペーストしておいときましょう。便利なことに、いずれも`コピー`ボタンがついてます。素晴らしい。

1. コンシューマ鍵
2. コンシューマの秘密 (クリックしないと出てきません)

![Screen Shot 2020-12-30 at 11.14.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/5fac18c6-1079-44f9-6067-a3cf569c26cf.png)

## アクセスするユーザの追加

この「接続アプリケーション」を通じてアクセス可能なユーザを定義します。`Manage`ボタンをクリックして「接続アプリケーションの詳細」が表示されたら｀ポリシーを編集`ボタンを押します。

この中の「OAuth ポリシー」ないの "許可されているユーザ" を "管理者が承認したユーザは事前承認済み" へ変更して保存します。

![Screen Shot 2020-12-30 at 11.18.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/7bf9b031-0812-23a2-821e-c252802a531e.png)

すると、下の方に「プロファイル」と「権限セット」という関連リストが追加されています。ここで脇目も振らず一心不乱に「プロファイルを管理する」ボタンをクリックします。次のような「アプリケーションプロファイルの割り当て」画面が表示されます。ここで、この接続アプリケーションを通じてアクセスさせたいユーザの持つプロファイルを選択します。一般的に専用のAPIユーザを準備したり、システム管理者を利用するでしょう。そのユーザに与えているプロファイルを選択します。そのプロファイルを持つユーザしかアクセスできません。

![Screen Shot 2020-12-30 at 11.20.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/e5c6be0f-8774-0377-413a-56f87bd4e4a4.png)

# 2. (接続する側)認証プロバイダの作成

さあて、今度は接続したい側、先ほど接続アプリケーションを作成したSalesforceの組織へアクセスする側の組織で設定します。Salesforceの設定画面から「認証プロバイダ」へアクセスします。設定の下、相当下、思ったよりも下にある「ID」カテゴリ内に「認証プロバイダ」があります。クイック検索した方が早いです。

![Screen Shot 2020-12-30 at 11.26.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/c17f08fe-46ff-b597-a798-42785c46238f.png)

そちらをクリックしたならば、すぐさま「新規」です。`プロバイダタイプ`の設定画面のみがありますので、ここから「Salesforce」を選択します。ご覧いただければ分かるとおり、2020年12月現在、次の10のプロバイダに対応しています。これ以外のプロバイダを利用したい場合は、[カスタム認証プロバイダ](https://help.salesforce.com/articleView?id=sso_provider_plugin_custom.htm&language=ja&type=5)を自作することも可能です。拙作[[Salesforce] カスタム認証プロバイダの作り方 ~Client Credentials 編~](https://qiita.com/sho7650/items/f3287819fbcfe0473a6a)もご覧いただけると幸いです。これみて気がつきましたが、Azureどこいった。

![Screen Shot 2020-12-30 at 11.28.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/27e224bf-7b69-507a-01fd-223aa99254b1.png)


|設定項目|設定内容|
|---|---|
|名前|人様が認識するために必要なだけの名前です。何でもいい|
|URL 接尾辞|承認に必要なさまざまなURLの最後に付与されるものですが、これもAPI識別子みたいなものです。ユニークな英語なら何でもどうぞ|
|コンシューマ鍵|先ほどコピペしろといった`コンシューマ鍵`です|
|コンシューマの秘密|同じく`コンシューマの秘密`です|
|承認エンドポイント URL|私のドメインが設定されているはずなので、それを指定する方が連携は容易です。デフォルトのままでもいけますが、ホスト名の後ろは必ず `/services/oauth2/authorize` です|
|トークンエンドポイント URL|上記通りですが、こちらはホスト名以後は `/services/oauth2/token`に必ずなります|
|デフォルトの範囲|最重要ポイントです。ここで必ず`refresh_token`が入らねばなりません。それ以外に必要なOAuthスコープを入れます|

![Screen Shot 2020-12-30 at 11.34.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/1a29d06f-28c8-31c3-f2a5-101dde3c0de9.png)

ここまで設定できたら「保存」しますね。この後にも重要なポイントがあります。保存された後の画面にある `コールバック URL` の URLをコピペしてメモしておきます。下の方の `Salesforce 設定`内にありますよね。

![Screen Shot 2020-12-30 at 11.34.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/55f1e858-d0da-a0ff-67a4-f48f5e9c4b4f.png)

### `デフォルトの範囲` について

Salesforce の認証プロバイダでは、デフォルトのOAuthスコープに`refresh_token`の含まれない`full`がハードコードされているようです。接続される側でいくら`refresh_token`と`full`を指定してあげても、`refresh token`を取得しません。なので必ず、OAuth で`refresh token`が必要な場合には、ここで`refresh_token`を指定しなければなりません。これは、あなた方の義務です。使命です。

なお`refresh_token`を指定せず、デフォルトの空欄にしたまま、「外部データソース」や「指定ログイン情報」を設定するとどうなるか。認証自体は通るのですが、このようなメッセージが出て`refresh token`が取得できなかったことが分かります。注意勧告程度のメッセージに見えますが、はっきり言って利用できません。`refresh_token`を定義しないと、この認証プロバイダは利用できないに等しいです。

![Screen Shot 2020-12-30 at 11.48.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/74e5acb2-0ae1-8859-e12c-571747e43ce2.png)

検索用: 認証プロバイダが更新トークンを提供しませんでした。アクセストークンの有効期限が切れると、組織からこの外部データソースにアクセスできなくなります。

# 3. (接続される側)接続アプリケーションの編集

さて、またアクセスされる側に戻ります。先ほど適当に定義した`コールバックURL`を設定します。先ほど作成した「接続アプリケーション」を開き直して「編集」します。そして、先ほど雑に入力した「コールバック URL」部分を、認証プロバイダで定義された「コールバック URL」で上書きして保存してあげます。これで、受け入れ完了です。

![Screen Shot 2020-12-30 at 11.36.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/3e5449f1-3ab1-218b-4991-d176f14f6299.png)

# 4. (接続する側)指定ログイン情報/外部データソースの作成

あとは利用するアプリケーションに従って、認証プロバイダを利用するように定義します。主に「指定ログイン情報」と「外部データソース(Salesforce Connectを使用する場合)」でしょう。いずれも設定方法はだいたい同じです。いずれも設定を保存すると、Salesforce の認証画面が表示されますので、該当するユーザでログインしてあげれば設定完了です。やったぜ(๑•̀ㅂ•́)و✧

なお、ログイン先のURLを指定しなかったり、設定しなかったりしているような場合で、かつ `https://login.salesforce.com` からのログインが禁止されているとログインできません。URLを指定するか、認証時に「カスタムドメインを使用」として、ドメインを指定してログインしましょう。

![Screen Shot 2020-12-30 at 12.04.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/2e6a5f3b-3ad1-6c15-f912-f1e4c7966626.png)

## 指定ログイン情報の場合

|設定名|設定内容|
|---|---|
|表示ラベル|なんでもいい(ry|
|名前|APIとは書いてませんが、これもAPIでアクセスする際の識別子なので、英語で指定します|
|URL|接続する先のSalesforceのログインURLを指定します。`login.salesforce.com`でもいける気がするけど、私のドメインで設定したカスタムドメインの方が悔いがありません|
|ID 種別|`ユーザ`とするとこのプロバイダを利用するユーザごとにログインするユーザを指定できます。`指定ユーザ`にすると、ここで指定したユーザですべてのユーザは外部システムへアクセスするようになります|
|認証プロトコル|今回のケースでは、もちろん`OAuth 2.0`を指定します|
|認証プロバイダ|さきほど作成した認証プロバイダにします。変な名前にすると、こんなことになるのでオススメしません|
|範囲|認証プロバイダで指定した範囲をより狭めて利用したい場合にはここで定義します|

![Screen Shot 2020-12-30 at 11.57.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/80732db8-072e-c844-3b96-57dc2625b8fa.png)

指定ログイン情報を設定すると、[Apexでのコールアウト](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_callouts_named_credentials.htm)や[外部サービス](https://help.salesforce.com/articleView?id=external_services.htm&type=5)で利用できます。

## 外部データソースの場合

|設定名|設定内容|
|---|---|
|外部データソース|なんでもいい(ry|
|名前|APIとは書いてませんが、これもAPIでアクセスする際の識別子なので、英語で指定します|
|種別|Salesforce Connect が利用する相手先の種類を指定します。今回のケースだと`Salesforce Connect: クロス組織`一択です|
|接続先|対象となるSalesforceの環境に合わせて、Production や Sandbox を指定します。カスタムドメインを利用している場合には、このように`Custom URL`にしてURLを定義するが吉です|
|URL|`Custom URL`とした場合には、接続先のURLを指定します|
|APIバージョン|なるべく最新を。あえて昔のAPIを利用したい場合などには、ここで制御します|
|ID 種別|`ユーザ`とするとこのプロバイダを利用するユーザごとにログインするユーザを指定できます。`指定ユーザ`にすると、ここで指定したユーザですべてのユーザは外部システムへアクセスするようになります|
|認証プロトコル|今回のケースでは、もちろん`OAuth 2.0`を指定します|
|認証プロバイダ|さきほど作成した認証プロバイダにします。変な名前にすると、こんなことになるのでオススメしません|
|範囲|認証プロバイダで指定した範囲をより狭めて利用したい場合にはここで定義します|

![Screen Shot 2020-12-30 at 12.02.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/c2f24151-17fe-f104-4f5f-2502d97142df.png)

外部データソースを設定すると、接続されている側のSalesforceのオブジェクトへアクセスが可能になります。保存した後、「検証して同期」ボタンをクリックすると「外部オブジェクト」として利用したいオブジェクトの選択画面になります。次のように「Account(取引先)」オブジェクトを選択して「同期」すると外部オブジェクトとして、相手先の取引先オブジェクトをカスタムオブジェクトのように利用できるようになります。

![Screen Shot 2020-12-30 at 12.24.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/929319fa-0a33-8642-244d-6013fd1145eb.png)

へぇ.