Salesforce OAuth 2.0 JWT Bearer Token Flow を使用する方法
Salesforce OAuth 2.0 JWT Bearer Token Flow を使用する必要がありましたので、備忘録として残します。
JWT 認証用アプリケーション登録 (Salesforce)
設定 -> アプリケーション -> アプリケーションマネージャ
、と辿り、新規接続アプリケーションを選択します。
以下を設定してください。
フィールド | 値 |
---|---|
OAuth設定の有効化 | ON |
コールバックURL | 任意 (今回は https://login.salesforce.com/services/oauth2/callback ) |
デジタル署名を使用 | ON |
選択したOAuth範囲 | ユーザに代わっていつでも要求を実行 |
自己署名証明書を使用する場合、以下で作成できます。
openssl genrsa 2048 > xxx.pem
openssl req -new -key xxx.pem -out xxx.csr
openssl x509 -req -days 365 -in xxx.csr -signkey xxx.pem -out xxx.crt
openssl rsa -in xxx.pem -pubout -out xxx.pub
設定 -> アプリケーション -> 接続アプリケーション -> 接続アプリケーションを管理する
、と辿り、先ほど登録したアプリケーションの編集画面を開きます。
許可されているユーザ
の すべてのユーザは自己承認可能
を 管理者が承認したユーザは事前承認済み
に変更してください。
プロファイルに許可したいユーザを追加します。
JWT 認証用アプリケーション (Python 3.x)
JWT 仕様
ポイントは以下のとおりです。 詳細は、公式ページをご参照ください。
- 署名生成アルゴリズム
- RS256
- ペイロード
- aud:
https://test.salesforce.com
orhttps://login.salesforce.com
- iss: 接続アプリケーションのコンシューマ鍵
- sub: Account ID
- exp: Unix timestamp
- aud:
サンプルコード
JWT 生成のために、PyJWT を使用しました。
事前に pip install pyjwt
でインストールしてください。
import datetime
import requests
import jwt
with open('xxx.pem', mode='r') as f:
# JWT 生成
secret = f.read()
encoded = jwt.encode({
'iss': 'xxx.yyy', # コンシューマ鍵
'aud': 'https://test.salesforce.com',
'sub': '[email protected]', # Account ID
'exp': datetime.datetime.now().timestamp() + (3 * 60) # 現在時刻より3分間有効
}, secret, algorithm='RS256')
# JWT 認証
response = requests.post(
'https://test.salesforce.com/services/oauth2/token',
data={'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer', 'assertion': encoded}
)
print(response.json())
400 Error (user hasn’t approved this consumer)
接続アプリケーションの登録時に、許可されているユーザ
として すべてのユーザは自己承認可能
を設定した場合、事前に以下の URL で承認してください(事前に一回のみ)。
https://test.salesforce.com/services/oauth2/authorize?client_id=<接続アプリケーションのコンシューマ鍵>&redirect_uri=<接続アプリケーションのリダイレクトURL>&response_type=token
JWT OAuth 2.0 ベアラートークンフロー要求は、更新トークンを含むユーザの以前のすべての承認を確認します。 一致する承認が見つかった場合、Salesforce は承認された範囲の値を組み合わせます。 次に、Salesforce はアクセストークンを発行します。 更新トークンまたは承認された使用可能な範囲を含んでいた以前の承認が見つからない場合、要求は未認証として失敗します。
事前に承認していない場合、400 Error が発生します。
$ python jwt-test-new.py
{'error': 'invalid_grant', 'error_description': "user hasn't approved this consumer"}