背景と適用シナリオ
Salesforce 連携エンジニアとして、私たちは日々、様々な外部システムと Salesforce を安全かつ効率的に接続するという課題に取り組んでいます。顧客管理システム (CRM)、基幹業務システム (ERP)、マーケティングオートメーションツールなど、連携対象は多岐にわたります。これらの連携を実現する上で、最も重要な基盤技術の一つが OAuth 2.0 (オーオース 2.0) です。
OAuth 2.0 は、パスワードを直接共有することなく、特定のリソースへの限定的なアクセス権をサードパーティアプリケーションに付与するための、業界標準の認可フレームワークです。ユーザーの認証情報を連携先システムに保存する必要がないため、セキュリティが大幅に向上します。例えば、以下のようなシナリオで OAuth 2.0 は不可欠です。
- Webアプリケーション連携: 外部のWebサーバーアプリケーションが、ユーザーの代理として Salesforce の取引先責任者データを取得・更新する。
- サーバー間連携: 夜間バッチ処理で、ユーザーの操作を介さずに ERP システムから Salesforce へ自動的に注文データを同期する。
- モバイルアプリケーション: スマートフォンアプリが、Salesforce の承認プロセス情報を取得し、ユーザーにプッシュ通知を送信する。
- デスクトップアプリケーション: PCにインストールされたツールが、Salesforce のレポートデータにアクセスして分析レポートを生成する。
本記事では、Salesforce 連携エンジニアの視点から、Salesforce が提供する主要な OAuth 2.0 フローの原理を解き明かし、各シナリオに最適なフローの選定方法、そして具体的な実装例までを詳しく解説します。
原理説明
OAuth 2.0 のフローを理解する前に、まず登場する4つの役割を把握することが重要です。
- Resource Owner (リソースオーナー): 通常はエンドユーザー。保護されたリソース(例:Salesforce の取引先データ)の所有者。
- Client (クライアント): Resource Owner のデータにアクセスしようとするアプリケーション(例:外部のWebシステム)。Salesforce では、これは Connected App (接続アプリケーション) として表現されます。
- Authorization Server (認可サーバー): Resource Owner を認証し、同意を得た上で Client に Access Token (アクセストークン) を発行するサーバー。Salesforce の場合、
login.salesforce.com
や My Domain の URL がこれに該当します。 - Resource Server (リソースサーバー): Access Token を受け取り、保護されたリソースへのアクセスを許可するサーバー。Salesforce の API エンドポイント(例:
MyDomainName.my.salesforce.com/services/data/vXX.X/
)がこれにあたります。
OAuth 2.0 の基本的な流れは、「Client が Resource Owner の許可を得て Authorization Server から Access Token を取得し、そのトークンを使って Resource Server にアクセスする」というものです。Salesforce は、連携のユースケースに応じて複数のフローを提供しています。
1. Authorization Code and Credentials Flow (認可コードおよび資格情報フロー)
サーバーサイドの処理を持つ Web アプリケーション向けの、最も標準的で安全なフローです。ユーザーのブラウザを介したリダイレクトが伴います。
流れ:
- ユーザーが Client アプリケーション上の「Salesforceでログイン」ボタンをクリックします。
- Client はユーザーを Salesforce の認可サーバーへリダイレクトします。
- ユーザーは Salesforce にログインし、Client へのデータアクセスを許可(同意)します。
- Salesforce は、ユーザーを指定されたリダイレクトURIに戻し、その際に一時的な認可コードを渡します。
- Client のバックエンドサーバーが、受け取った認可コードと自身の Client Secret (クライアントの秘密) を使って、Salesforce の認可サーバーに直接リクエストを送信します。
- Salesforce は認可コードと Client Secret を検証し、問題がなければ Access Token と Refresh Token (更新トークン) を返却します。
2. JWT (JSON Web Token) Bearer Flow (JWT ベアラーフロー)
ユーザーの操作を介さないサーバー間連携に最適なフローです。事前に Client アプリケーションを承認しておくことで、実行時にユーザーの介入なしで Access Token を取得できます。連携エンジニアがバッチ処理などを実装する際に最も頻繁に利用します。
流れ:
- 管理者は、事前に Salesforce 側で Connected App を作成し、デジタル証明書をアップロードします。また、関連するプロファイルや権限セットに対して、この Connected App の利用を許可します。
- Client アプリケーションは、自身の秘密鍵を使って、ユーザー名などを含む署名付きの JWT (JSON Web Token) を生成します。
- Client はこの JWT を Salesforce のトークンエンドポイントに送信します。
- Salesforce は JWT の署名を、登録されている証明書を使って検証し、正当性を確認します。
- 検証に成功すると、Salesforce は Access Token を返却します。
3. Username-Password Flow (ユーザー名パスワードフロー)
非推奨ですが、特定の状況下で使用されることがあるフローです。Client アプリケーションがユーザーの Salesforce ユーザー名とパスワードを直接収集し、それらを使って Access Token を取得します。
注意: このフローは、ユーザーの認証情報を Client 側で保持する必要があるため、セキュリティリスクが非常に高いです。Salesforce 自身が Client を所有している場合や、他のフローが技術的に利用不可能なレガシーシステムとの連携など、極めて限定的な状況でのみ使用を検討すべきです。
4. Refresh Token Flow (更新トークンフロー)
これは独立したフローではなく、Authorization Code Flow などで取得した Refresh Token を使って新しい Access Token を取得するためのプロセスです。Access Token は通常、有効期限が短く設定されています(例:2時間)。トークンが失効するたびにユーザーに再ログインを要求するのは非現実的です。そこで、有効期限の長い Refresh Token を使って、バックグラウンドで新しい Access Token を再取得します。これにより、ユーザーは一度ログインすれば、長期間サービスを継続して利用できます。
示例代码
ここでは、サーバー間連携で最も重要な JWT Bearer Flow の実装例を見ていきます。この例では、cURL を使って Salesforce のトークンエンドポイントにリクエストを送信する方法を示します。実際のアプリケーションでは、各言語のライブラリ(Java の `nimbus-jose-jwt`、Python の `PyJWT` など)を使用して JWT を生成し、HTTPリクエストを送信します。
ステップ1:JWT の生成
まず、JWT を生成する必要があります。JWT はヘッダー、ペイロード、署名の3つの部分から構成されます。
- ヘッダー: アルゴリズム(例:RS256)とトークンタイプ(JWT)を指定します。
- ペイロード(クレーム): 以下の情報を含みます。
iss
: Connected App の Consumer Key (コンシューマーキー)。sub
: 連携処理を実行する Salesforce ユーザーのユーザー名。aud
: オーディエンス。本番環境ではhttps://login.salesforce.com
、Sandbox ではhttps://test.salesforce.com
。exp
: トークンの有効期限(Unix タイムスタンプ)。通常は発行から数分以内に設定します。
- 署名: ヘッダーとペイロードをエンコードした文字列を、Connected App に登録した証明書に対応する秘密鍵で署名します。
ステップ2:アクセストークンのリクエスト
生成した JWT を使って、Salesforce のトークンエンドポイント(/services/oauth2/token
)に POST リクエストを送信します。
以下のコードは、Salesforce の公式ドキュメントに記載されている cURL コマンドの例です。
curl https://MyDomainName.my.salesforce.com/services/oauth2/token -d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" -d "assertion=base64_encoded_jwt"
コードの解説:
https://MyDomainName.my.salesforce.com/services/oauth2/token
: Salesforce 組織のトークンエンドポイントの URL です。My Domain の設定が必要です。-d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer"
: grant_type (許可種別) を指定します。JWT Bearer Flow を使用することを示しています。この値は固定です。-d "assertion=base64_encoded_jwt"
: assertion (アサーション) パラメータに、ステップ1で生成した JWT を Base64 URL エンコードした文字列を設定します。
ステップ3:レスポンスの処理
リクエストが成功すると、Salesforce は以下のような JSON レスポンスを返します。
{ "access_token": "00D...!", "scope": "web api refresh_token", "instance_url": "https://yourInstance.salesforce.com", "id": "https://login.salesforce.com/id/00D.../005...", "token_type": "Bearer" }
このレスポンスに含まれる access_token
を、後続の Salesforce REST API へのリクエストの Authorization
ヘッダーに `Bearer [access_token]` の形式で含めることで、API へのアクセスが可能になります。
注意事項
Connected App (接続アプリケーション) の設定
OAuth フローを正しく機能させるためには、Connected App の設定が非常に重要です。特に Scopes (スコープ) の設定には注意が必要です。スコープは、Client が取得した Access Token で何ができるかを定義します。例えば、`api` は API アクセス全般を許可し、`refresh_token, offline_access` は Refresh Token の発行を許可します。最小権限の原則に従い、連携に必要なスコープのみを付与するようにしてください。
セキュリティ
Client Secret や JWT 生成に用いる秘密鍵は、システムの最も重要な機密情報です。これらをソースコードにハードコーディングすることは絶対に避けてください。AWS Secrets Manager, Azure Key Vault, HashiCorp Vault などのシークレット管理ツールや、環境変数を利用して安全に管理する必要があります。
API 制限
OAuth 経由での API コールも、Salesforce 組織の API リクエスト制限の対象となります。大量のデータを扱うバッチ処理などを設計する際は、API コール数を考慮し、Bulk API の利用を検討するなど、効率的な連携方式を選択することが重要です。
エラー処理
連携処理では、堅牢なエラーハンドリングが不可欠です。トークン取得リクエストが失敗した場合、Salesforce は `error` と `error_description` を含む JSON を返します。例えば、JWT の有効期限が切れている場合は `invalid_grant`、署名検証に失敗した場合は `invalid_grant` といったエラーが返されます。これらのエラーコードを適切にハンドリングし、リトライ処理や管理者への通知を行うロジックを実装する必要があります。
まとめとベストプラクティス
OAuth 2.0 は、現代の Salesforce 連携において不可欠なセキュリティ基盤です。連携エンジニアとして、各フローの特性を深く理解し、要件に最も適したフローを選択する能力は極めて重要です。
フロー選択の指針:
- ユーザーの操作を伴う Web アプリケーション (サーバーサイド) → Authorization Code Flow を選択します。最も安全で標準的な方法です。
- ユーザーの操作を介さないサーバー間連携 (バッチ処理など) → JWT Bearer Flow を選択します。事前に承認を設定しておくことで、セキュアで自動化された連携が可能です。
- ブラウザベースのシングルページアプリケーション (SPA) → Authorization Code Flow with PKCE (Proof Key for Code Exchange) を利用します。PKCE は Client Secret を安全に保持できないパブリッククライアント向けの拡張機能です。
- レガシーシステムやテスト目的など、やむを得ない場合 → 限定的に Username-Password Flow を検討しますが、セキュリティリスクを十分に評価した上で使用してください。
ベストプラクティス:
- 常に最も安全なフローを選択する: 可能であれば常に Authorization Code Flow または JWT Bearer Flow を使用し、Username-Password Flow は避けてください。
- Refresh Token を活用する: 長期間にわたる連携では、Refresh Token を使用してセッションを維持し、ユーザー体験を損なわないようにします。
- 最小権限の原則: Connected App のスコープは、連携に必要な最小限の権限に限定します。
- 機密情報を安全に管理する: Client Secret や秘密鍵は、専用のシークレット管理サービスで厳重に保護します。
これらの知識とベストプラクティスを実践することで、私たちはよりセキュアで、スケーラブルかつ信頼性の高い Salesforce 連携システムを構築することができるでしょう。
コメント
コメントを投稿