Salesforce OAuth 2.0 の徹底解説:セキュアなインテグレーションのための技術ガイド

背景と応用シナリオ

現代のエンタープライズアプリケーションは、孤立して機能することはほとんどありません。外部システムとの連携、モバイルアプリケーションのサポート、または顧客向けのカスタムWebポータルの構築など、データ連携は不可欠です。しかし、これらの連携をどのように安全に実現するかが重要な課題となります。ユーザーのSalesforce認証情報(ユーザー名とパスワード)を外部アプリケーションに直接保存することは、セキュリティ上の重大なリスクを伴います。

ここで登場するのが OAuth 2.0 です。OAuth 2.0は、サードパーティアプリケーションがユーザーの代わりに、HTTPサービス上のリソースへ限定的なアクセス権限を取得するための承認フレームワーク(Authorization Framework)です。これは認証(Authentication)プロトコルではなく、承認(Authorization)のための標準仕様です。つまり、「誰であるか」を確認するのではなく、「何をして良いか」を許可する仕組みです。

Salesforceプラットフォームにおいて、OAuth 2.0は外部アプリケーションがSalesforce APIへ安全にアクセスするための標準的な方法として採用されています。具体的な応用シナリオは多岐にわたります。

  • Webアプリケーション連携: 外部のWebアプリケーション(例:経費精算システム)が、Salesforceに保存されているユーザーの取引先責任者情報を参照する。
  • モバイルアプリケーション: カスタムモバイルアプリが、ユーザーのSalesforceアカウントにログインし、ToDoや商談データを表示・更新する。
  • サーバー間連携: 夜間バッチ処理で、外部のデータウェアハウスがSalesforceから日次レポートデータを取得する。このシナリオでは、ユーザーの操作は介在しません。

これらのシナリオにおいて、OAuth 2.0を利用することで、ユーザーは自身のSalesforceパスワードを外部アプリケーションに渡すことなく、安全に必要なデータアクセスのみを許可できます。


原理説明

SalesforceにおけるOAuth 2.0のフローを理解するためには、まずいくつかの重要な登場人物とコンセプトを把握する必要があります。

主要な役割 (Roles)

  • Resource Owner (リソースオーナー): 通常はエンドユーザーです。Salesforceに保存されている自分のデータ(リソース)へのアクセスを許可する権限を持っています。
  • Client (クライアント): Salesforceのリソースにアクセスしようとする外部アプリケーション(Webアプリ、モバイルアプリなど)です。Salesforceでは、クライアントはConnected App (接続アプリケーション)として登録・設定されます。
  • Authorization Server (承認サーバー): Salesforceそのものです。リソースオーナーを認証し、その同意を得た上で、クライアントに対してAccess Token (アクセストークン)を発行します。
  • Resource Server (リソースサーバー): SalesforceのAPIエンドポイントです。アクセストークンを提示したクライアントからのリクエストを受け付け、保護されたリソースへのアクセスを許可します。

主要なコンセプト

  • Connected App (接続アプリケーション): 外部アプリケーションをSalesforceに統合するためのフレームワークです。APIインテグレーションの設定、OAuth 2.0の承認フローの管理、アクセス制御ポリシーの定義などをここで行います。各Connected Appには一意のConsumer Key (コンシューマ鍵) (Client ID)とConsumer Secret (コンシューマの秘密) (Client Secret)が割り当てられます。
  • Access Token (アクセストークン): クライアントが保護されたリソースへアクセスするために使用する、一時的な文字列です。このトークンをAPIリクエストのヘッダーに含めることで、クライアントは承認されていることを証明します。アクセストークンには有効期限があります。
  • Refresh Token (リフレッシュトークン): アクセストークンが失効した際に、ユーザーの再承認なしに新しいアクセストークンを取得するために使用するトークンです。より長い有効期間を持ち、安全に保管する必要があります。
  • Scope (スコープ): クライアントがリソースオーナーに要求するアクセス権の範囲を定義します。例えば、「基本情報へのアクセス(id, profile, email)」、「APIを介したデータアクセス(api)」、「アクセストークン失効後の再取得(refresh_token)」などがあります。最小権限の原則に従い、必要なスコープのみを要求することがベストプラクティスです。

Salesforceがサポートする主要なOAuth 2.0フロー

Salesforceは、様々なユースケースに対応するために複数のOAuth 2.0フロー(Grant Type)をサポートしています。

1. Web Server Flow (Webサーバーフロー)

サーバーサイドの処理能力を持つWebアプリケーションに最も適した、安全性の高いフローです。クライアント(Webアプリケーション)は、Consumer Secretをサーバー側で安全に保持できることが前提です。フローの概要は以下の通りです。

  1. アプリケーションがユーザーをSalesforceの承認エンドポイントへリダイレクトします。
  2. ユーザーはSalesforceにログインし、アプリケーションからのアクセス要求を承認します。
  3. Salesforceは、事前に設定されたコールバックURLへ、一時的なAuthorization Code (認証コード)を付けてユーザーをリダイレクトし返します。
  4. アプリケーションのサーバーは、受け取った認証コードと自身のConsumer Secretを使って、Salesforceのトークンエンドポイントにリクエストを送信します。
  5. Salesforceは認証コードとConsumer Secretを検証し、問題がなければアクセストークンとリフレッシュトークンを返却します。

2. User-Agent Flow (ユーザーエージェントフロー)

デスクトップアプリケーションや、サーバーサイドのロジックを持たないJavaScriptベースのシングルページアプリケーション(SPA)など、Consumer Secretを安全に保管できないクライアント向けです。このフローでは、アクセストークンがコールバックURLのフラグメント(#以降)で直接ブラウザに返されるため、サーバーを介したコード交換が不要です。ただし、セキュリティ上の理由からリフレッシュトークンは発行されません。

3. JWT Bearer Flow (JWT Bearerフロー)

サーバー間連携など、ユーザーの介在なしにAPIアクセスを行いたい場合に利用します。事前にSalesforce側でユーザーによる承認(プロファイルの許可)が必要です。クライアントは、秘密鍵で署名したJSON Web Token (JWT)を生成し、それをSalesforceの承認サーバーに提示することでアクセストークンを取得します。ユーザーのログイン操作が不要なため、自動化されたプロセスに最適です。


サンプルコード

ここでは、最も一般的で安全なWebサーバーフローを例に、具体的なリクエストの流れを解説します。コード例はSalesforceの公式ドキュメントで推奨されているcURLコマンドをベースにしています。

ステップ1: ユーザーを承認のためにリダイレクト

まず、WebアプリケーションはユーザーをSalesforceの承認エンドポイントにリダイレクトさせるURLを構築します。このURLに、どのアプリケーションが、何をしたいのか、という情報を含めます。

https://MyDomainName.my.salesforce.com/services/oauth2/authorize?
response_type=code&
client_id=YOUR_CONSUMER_KEY&
redirect_uri=https://www.myapplication.com/callback&
scope=api%20refresh_token&
state=12345

パラメータ解説:

  • response_type=code: Webサーバーフローであることを示します。認証コードを要求します。
  • client_id: Connected AppのConsumer Key (コンシューマ鍵)です。
  • redirect_uri: 承認後にSalesforceがユーザーをリダイレクトさせる先のURLです。Connected Appで事前に登録したコールバックURLと完全に一致する必要があります。
  • scope: 要求する権限の範囲です。ここでは、APIアクセス(api)とリフレッシュトークンの取得(refresh_token)を要求しています。スコープはスペースで区切りますが、URLエンコードされているため%20になっています。
  • state: CSRF(クロスサイトリクエストフォージェリ)攻撃を防ぐためのオプションのパラメータです。リクエスト時に生成したランダムな値を設定し、コールバック時に同じ値が返ってくることを検証します。

ステップ2: 認証コードをアクセストークンに交換

ユーザーが承認すると、Salesforceはステップ1で指定したredirect_uriに、codeパラメータを付与してリダイレクトします。アプリケーションのサーバーサイドは、この認証コードを受け取り、アクセストークンを取得するためのPOSTリクエストをSalesforceのトークンエンドポイントに送信します。

以下は、Salesforce公式ドキュメントに記載されているcURLコマンドの例です。

curl -X POST https://MyDomainName.my.salesforce.com/services/oauth2/token \
-d "grant_type=authorization_code" \
-d "code=aW50ZWdyYXRpb25fdXNlcl9pZD...Q3QzlB" \
-d "client_id=YOUR_CONSUMER_KEY" \
-d "client_secret=YOUR_CONSUMER_SECRET" \
-d "redirect_uri=https://www.myapplication.com/callback"

パラメータ解説:

  • grant_type=authorization_code: 認証コードを使ってトークンを要求していることを示します。
  • code: ステップ1のコールバックで受け取った認証コードです。
  • client_id: Connected AppのConsumer Keyです。
  • client_secret: Connected AppのConsumer Secretです。この値は決してクライアントサイド(ブラウザなど)に公開してはいけません。
  • redirect_uri: ステップ1で指定したものと同じコールバックURLです。

このリクエストが成功すると、Salesforceは以下のようなJSONレスポンスを返します。

{
    "access_token": "00D...!",
    "refresh_token": "5A...!",
    "signature": "...",
    "scope": "api refresh_token",
    "instance_url": "https://yourInstance.salesforce.com",
    "id": "https://login.salesforce.com/id/00D.../005...",
    "token_type": "Bearer",
    "issued_at": "1573673914563"
}

アプリケーションは、このレスポンスからaccess_tokenrefresh_tokenを抽出し、安全に保存します。

ステップ3: アクセストークンを使用してAPIを呼び出す

取得したアクセストークンを使って、SalesforceのREST APIを呼び出します。AuthorizationヘッダーにBearer {アクセストークン}の形式で指定します。

curl -X GET https://yourInstance.salesforce.com/services/data/v58.0/sobjects/Account -H "Authorization: Bearer 00D...!"

このリクエストは、組織内のすべての取引先オブジェクトの基本情報を取得します。


注意事項

OAuth 2.0を実装する際には、以下の点に注意することが重要です。

Connected Appの正しい設定

Connected Appの設定は、セキュリティの根幹をなします。コールバックURL (Callback URL)は、想定されるリダイレクト先のみに厳密に設定してください。ワイルドカードの使用は避け、可能な限り具体的なURLを指定することが推奨されます。また、選択したOAuth範囲 (Selected OAuth Scopes)は、アプリケーションが必要とする最小限の権限に留めてください。

Client SecretとRefresh Tokenの安全な保管

Consumer Secret (Client Secret)Refresh Tokenは、非常に機密性の高い情報です。これらが漏洩すると、第三者がユーザーに代わってSalesforceデータにアクセスできてしまいます。これらの情報は、必ずサーバーサイドの安全な場所(暗号化されたデータベース、環境変数、シークレット管理サービスなど)に保管し、決してクライアントサイドのコード(JavaScriptやモバイルアプリのバイナリ)にハードコーディングしないでください。

API制限

OAuth 2.0経由で行われるすべてのAPIコールは、Salesforce組織のAPIリクエスト制限の対象となります。大量のデータを扱うインテグレーションを設計する際は、組織のAPI制限を確認し、Bulk APIなど、より効率的なAPIの利用を検討してください。

エラー処理

アクセストークンの有効期限切れ(HTTP 401 Unauthorized)、無効なリクエスト、ユーザーによるアクセス許可の取り消しなど、OAuthフローやAPIコールでは様々なエラーが発生する可能性があります。アプリケーションはこれらのエラーを適切にハンドリングする必要があります。例えば、アクセストークンが失効している場合は、リフレッシュトークンを使って新しいトークンを取得するロジックを実装し、リフレッシュトークンも無効な場合は、ユーザーに再度承認フローを開始するよう促す必要があります。


まとめとベストプラクティス

OAuth 2.0は、Salesforceと外部アプリケーションを安全に連携させるための業界標準フレームワークです。その仕組みを正しく理解し、適切なフローを選択することが、堅牢でセキュアなインテグレーションを構築する鍵となります。

ベストプラクティス:

  1. 適切なフローを選択する:
    • サーバーサイドのロジックを持つWebアプリにはWebサーバーフローを使用します。
    • サーバー間連携にはJWT Bearerフローが最適です。
    • クライアントサイドのみのアプリケーションにはユーザーエージェントフローも選択肢ですが、可能であればPKCE(Proof Key for Code Exchange)付きの認証コードフローを検討し、セキュリティを強化してください。
    • Username-Passwordフローは、信頼できる内部アプリケーションやテスト用途に限定し、可能な限り避けてください。
  2. 最小権限の原則を遵守する: Connected Appで要求するスコープは、アプリケーションの機能に本当に必要なものだけに限定します。
  3. 機密情報を安全に保管する: Consumer Secretとリフレッシュトークンは、サーバーサイドで暗号化して保管します。
  4. `state`パラメータを活用する: Webサーバーフローでは、CSRF攻撃を防止するために必ずstateパラメータを使用し、コールバック時に検証してください。
  5. 常にHTTPSを使用する: すべての通信はTLS/SSLで暗号化されている必要があります。SalesforceのエンドポイントはHTTPSが必須ですが、アプリケーション側のコールバックURLも同様にHTTPSであるべきです。

これらの原則と実践に従うことで、Salesforce技術アーキテクトとして、顧客のデータを保護し、信頼性の高いインテグレーションソリューションを提供することができます。

コメント