Salesforceの指定ログイン機能を用いたOAuth2.0クライアント設定 - JWT Bearer Token Flow編

SalesforceはOAuth2.0に対応し、サーバ(認可サーバ、リソースサーバ)としてもクライアントとしてノーコードで認証フローを実現できます。JWT Bearer Token Flowをサーバ側、クライアント側両方ともSalesforceで行った場合の設定等のサンプルを紹介します。

# やっていること
クライアントをSalesforce A、認可サーバ、リソースサーバをSalesforce Bとします。Salesforce　Aで指定ログイン機能の設定を行い、匿名APEXコードでSalesforce Bに認証し、Rest APIを実行できていることを確認します。

認可サーバ、リソースサーバとなるSalesforce Bの設定方法、は[こちら](https://qiita.com/daisuke180/items/b1846f2325a95f9cd20e)で解説しています。

- Rest　APIをノーコードで呼び出す方法、
- 認証フローをAuthorization Code Flow(Webサーバフロー)にする方法

は別記事で解説予定です。

# 手順
”2.認可サーバ(Salesforce B)へのクライアント証明書の登録”以外はすべて、クライアントであるSalesforce Aでの作業です。

## 1. クライアント証明書の作成
 「設定」→「セキュリティ」→「証明書と鍵の管理」から、「自己署名証明書の作成」ボタンで証明書を作成します。表示ラベル、一意の名前は、適当に設定し（本記事では"myCert"）、その他はデフォルト値をそのまま使用します。
![スクリーンショット 2023-03-14 20.01.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3282138/5773999f-1032-e9f8-a844-6c798b21bd05.png)

作成した証明書を選択し「証明書のダウンロード」ボタンで証明書をダウンロードします。
![スクリーンショット 2023-03-14 20.02.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3282138/98395c3b-ce36-ffc7-60fb-5fee7f444cd0.png)

## 2. 認可サーバ(Salesforce B)へのクライアント証明書の登録
認可サーバ側にダウンロードした証明書を登録します。（登録方法は別記事での解説予定）

## 3. 外部ログイン情報の設定
### 3.1. 外部ログイン情報の作成
外部ログイン情報は、認証サーバに関する設定です。
 「設定」→「セキュリティ」→「指定ログイン情報」から、「外部ログイン情報」タブを選択、「新規」ボタンを押下し、外部ログイン情報を作成します。

| 設定項目 | 設定値 | 説明 |
| :---- | :--- | :---- |
| 表示ラベル | JwtBearerExtCert(任意値) | お好みの値を設定 |
| 名前 | JwtBearerExtCert(任意値) | お好みの値を設定 |  
| 認証プロトコル | OAuth2.0 | OAuth2.0で認証するための設定 |  
| 認証フロー種別 | JWTベアラーフロー | OAuth2.0のJWT Bearer Token Flowを利用するための設定 | 
| IDプロバイダURL | https://login.salesforce.com/services/oauth2/token (認証サーバ指定値)| トークンエンドポイントを設定。認証サーバがSandboxの場合は、https://test.salesforce.com/services/oauth2/token |  
| 証明書の署名 | myCert | 手順1で作成し、認証サーバに登録した証明書を指定 |  

![スクリーンショット 2023-03-14 20.06.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3282138/309f2386-2c6a-0b2a-8930-ae5ef1489c3f.png)

### 3.2. JWTクレームの設定
作成した外部ログイン情報の下にある[JWTクレーム]の「編集」ボタンを押下し、以下3つのログイン情報を設定します。接続先の認証サーバにより設定は異なるので、その辺は読み替えて設定してください。

| 設定項目 | 設定値 | 説明 |
| :---- | :--- | :---- |
| iss | 3MVG9n_HvETG.... (認証サーバ指定値)| Salesforce Bで接続したい接続アプリケーションのコンシューマキーを設定。右の値をそのまま設定しないように |
| sub | testuser@cunning-impala-mqsqh.dev (認証サーバ指定値)| Salesforce Bに登録されているRest API実行可能なユーザ名を指定。右の値をそのまま設定しないように | 
| aud | https://login.salesforce.com (認証サーバ指定値)| 認証サーバを指定。認証サーバがSandbox場合は https://test.salesforce.com | 

![スクリーンショット 2023-03-17 18.04.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3282138/1c49f0fd-b3e2-297d-731f-df4f177906fc.png)
 
### 3.3. 権限セットの作成と割り当て
作成した外部ログイン情報を利用するユーザに割り当てる権限セットを作成します。本設定では"ExtCredAccess"としてます。
![スクリーンショット 2023-03-17 18.10.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3282138/74ea4ae2-4bc5-ca54-8d80-bca02f4f7b8c.png)

作成した外部ログイン情報の下にある[権限セットの対応づけ]の[新規]ボタンを押下し、作成した権限セットを割り当てます。ID種別は「指定ユーザ」にします。
![スクリーンショット 2023-03-17 18.37.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3282138/48fa7526-65aa-69a0-735e-34530ca2b3ef.png)

## 4. 指定ログイン情報の設定
指定ログイン情報は、リソースサーバに関する設定です。
 「設定」→「セキュリティ」→「指定ログイン情報」から、「指定ログイン情報」タブを選択、「新規」ボタンを押下し、指定ログイン情報を作成します。

| 設定項目 | 設定値 | 説明 |
| :---- | :--- | :---- |
| 表示ラベル | SampleNmdCred (任意値) | お好みの値を設定 |
| 名前 | SampleNmdCred (任意値) | お好みの値を設定 | 
| URL | https://cunning-impala-mqswh-dev-ed.trailblaze.my.salesforce.com (リソースサーバ指定値) | リソースサーバのエンドポイントを指定。リソースサーバであるSalesforce Bの「私のドメイン」を指定。 | 
| 外部ログイン情報 | JwtBearerExtCert | 手順3.で作成した外部ログイン情報を設定 | 

![スクリーンショット 2023-03-17 18.40.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3282138/72353154-316d-5a97-6b7d-03dc6bad7d40.png)

## 5. 匿名APEXコードでのテスト
最初にログインしているユーザに作成した権限セット"ExtCredAccess"を割り当てておきます。
「右上のギアアイコン」→「開発者コンソール」で開発者コンソールを開き、「Debug」→「Open Anonymous Window」にて、以下テストコードをコピペして実行します。うまくいけば、通信しているようなログが出力されて正常終了します。

~~~apex:anonymous window
HttpRequest req = new HttpRequest();
req.setEndpoint('callout:SampleNmdCred/services/data/v57.0/');
req.setMethod('GET');
Http http = new Http();
HTTPResponse res = http.send(req);
System.debug(res.getBody());
~~~

![スクリーンショット 2023-03-17 19.05.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3282138/3348cb45-d937-0ebc-3d9e-a09ce770f374.png)
![スクリーンショット 2023-03-17 19.07.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3282138/81c22e53-886f-0c9b-2417-b6b10c67e403.png)

# 参考情報
- [Salesforceヘルプ:指定ログイン情報](https://help.salesforce.com/s/articleView?id=sf.named_credentials_about.htm&type=5)
- [Salesforceヘルプ:サーバ間インテグレーション用の OAuth 2.0 JWT ベアラーフロー
](https://help.salesforce.com/s/articleView?id=sf.remoteaccess_oauth_jwt_flow.htm&type=5)
- [Apex開発者ガイド:コールアウトエンドポイントとしての指定ログイン情報](https://developer.salesforce.com/docs/atlas.ja-jp.240.0.apexcode.meta/apexcode/apex_callouts_named_credentials.htm)
- [Qiita:Salesforce で外部サービスを使うときには「指定ログイン情報」を使いましょう](https://qiita.com/sho7650/items/577e54f390bc97e8d751)

# 関連記事
- [SalesforceのOAuth2.0サーバ設定（接続アプリケーション） - JWT Bearer Token Flow編](https://qiita.com/daisuke180/items/b1846f2325a95f9cd20e)

今後もう少し追加する予定