Salesforce 指定ログイン情報:Apex コールアウトのセキュリティと管理を簡素化する開発者ガイド

背景と利用シーン

Salesforce 開発者として、私たちは日常的に外部システムと連携するための Apex Callout を実装します。例えば、外部の REST API からデータを取得したり、SOAP Web サービスに情報を送信したりするケースです。従来、このような連携を実装する際には、いくつかの課題がありました。

最も一般的な問題は、エンドポイント URL や認証情報(API キー、ユーザー名、パスワードなど)の管理です。これらの情報を Apex コード内にハードコーディングすることは、セキュリティ上の重大なリスクであり、メンテナンス性を著しく低下させます。例えば、API キーが変更された場合、コードを修正し、テストを行い、再度デプロイする必要が生じます。

この問題を回避するために、カスタムメタデータ型やカスタム表示ラベルに認証情報を保存する方法もありますが、これも完璧な解決策ではありません。依然として認証情報の管理が煩雑であり、特に OAuth 2.0 のような複雑な認証フローを Apex で手動で処理するのは、多大な労力と深い知識を要します。

ここで登場するのが Named Credentials (指定ログイン情報) です。Named Credentials は、Salesforce プラットフォーム上で外部システムの API エンドポイントと認証情報を一元的に、かつ安全に管理するための仕組みです。開発者は、認証プロセスの複雑な詳細を意識することなく、わずか数行のコードで安全なコールアウトを実装できます。これにより、開発者はビジネスロジックそのものに集中できるようになります。

主な利用シーン:

  • 外部 REST/SOAP API との連携: 天気情報 API、株価情報 API、社内基幹システム(ERP)など、あらゆる外部サービスとのデータ連携を簡素化します。
  • セキュリティの強化: コードやカスタムメタデータから認証情報を分離し、Salesforce の堅牢なセキュリティ基盤で管理します。
  • 環境ごとの設定管理: Sandbox 環境ではテスト用のエンドポイント、本番環境では本番用のエンドポイントを、コードを変更することなく切り替えられます。
  • Salesforce Connect: 外部オブジェクトを利用して外部データを Salesforce 内のオブジェクトのように扱う際、その接続設定の基盤として Named Credentials が使用されます。

原理説明

Named Credentials の中核的な思想は「抽象化」です。開発者がコールアウトを行う際に必要となる「どこに(エンドポイント)」と「どのように(認証)」という二つの要素を、Salesforce の設定画面から管理できる一つのレコードに集約します。

Apex コードから Named Credential を参照する際には、特別な callout: プレフィックスを使用します。例えば、My_API という名前の Named Credential がある場合、コード内ではエンドポイントを callout:My_API/path/to/resource のように指定します。Salesforce プラットフォームは、このリクエストを受け取ると、以下の処理を自動的に実行します。

  1. My_API という名前の Named Credential の設定を検索します。
  2. 設定されているベース URL と、コードで指定されたパス(/path/to/resource)を結合して、完全なリクエスト URL を生成します。
  3. 設定されている Authentication Protocol (認証プロトコル) に基づいて認証処理を実行します。例えば OAuth 2.0 が設定されていれば、Salesforce は保存されているトークン(必要であればリフレッシュトークンを使って新しいアクセストークンを取得)を自動的に取得し、HTTP リクエストの Authorization ヘッダーに付与します。
  4. 認証情報が付与されたリクエストを、最終的なエンドポイントに送信します。

この仕組みの最大の利点は、開発者は認証情報の生成、管理、更新といった複雑なフローを一切気にする必要がないことです。すべてプラットフォームが裏側で処理してくれます。

主要な設定項目:

  • URL: 連携先 API のベースとなる URL です(例: https://api.example.com)。
  • Authentication Protocol (認証プロトコル): 連携先の認証方式を選択します。
    • No Authentication: 認証が不要な公開 API などで使用します。
    • Password Authentication: Basic 認証(ユーザー名とパスワード)を使用します。
    • OAuth 2.0: 最も一般的な認証方式の一つで、Auth. Provider (認証プロバイダー) と連携してアクセストークンを管理します。
    • JWT: JSON Web Token を使用したサーバー間認証です。
    • AWS Signature Version 4: Amazon Web Services (AWS) の API と連携する際に使用します。
  • Principal Type (プリンシパル種別): 認証を誰の権限で行うかを定義します。
    • Named Principal (指定ログイン情報): システム全体で共有される一つの認証情報(例:インテグレーション専用ユーザー)を使用します。全てのユーザーが同じ認証情報で API を呼び出します。
    • Per User (ユーザーごと): API を呼び出す Salesforce ユーザーごとに個別の認証を行います。各ユーザーは外部システムに対して自身の OAuth 認証を行う必要があります。

また、Named Credentials を使用する大きなメリットの一つに、Remote Site Settings (リモートサイトの設定) が不要になるという点があります。通常、Apex から外部サイトへコールアウトを行うには、その URL をリモートサイトの設定に登録する必要がありますが、Named Credentials 経由のコールアウトではこの登録が免除されます。これにより、環境管理が一層簡素化されます。


コード例

ここでは、My_Awesome_API という名前の Named Credential を使用して、外部の REST API から商品情報を取得する簡単な Apex コードを示します。この Named Credential は、URL として https://api.example.com が設定され、認証方式として OAuth 2.0 が構成されていると仮定します。

このコードは、Salesforce Developer Guide の標準的なコールアウトの例に基づいています。

// 商品情報を取得する Apex クラス
public class ProductService {

    // 商品 ID を受け取り、外部 API から商品情報を取得するメソッド
    public static String getProductInfo(String productId) {

        // HttpRequest オブジェクトをインスタンス化
        HttpRequest req = new HttpRequest();

        // setEndpoint メソッドでリクエストの送信先を指定します。
        // 'callout:' プレフィックスに続けて Named Credential の API 参照名、
        // その後に API のリソースパスを指定します。
        // Salesforce は 'My_Awesome_API' の設定に基づき、
        // ベース URL (https://api.example.com) とこのパスを結合し、
        // 完全な URL (https://api.example.com/products/productId) を生成します。
        req.setEndpoint('callout:My_Awesome_API/products/' + productId);

        // HTTP メソッドとして 'GET' を指定
        req.setMethod('GET');

        // ヘッダーを設定(ここでは JSON 形式のレスポンスを要求)
        req.setHeader('Content-Type', 'application/json;charset=UTF-8');

        // Http オブジェクトをインスタンス化してリクエストを送信
        Http http = new Http();
        HttpResponse res = null;

        try {
            // send メソッドを実行すると、Salesforce はバックグラウンドで
            // Named Credential の認証情報を自動的にヘッダーに付与し、リクエストを送信します。
            res = http.send(req);

            // レスポンスのステータスコードを確認
            if (res.getStatusCode() == 200) {
                // 成功した場合、レスポンスボディを返す
                return res.getBody();
            } else {
                // エラーが発生した場合、ログに記録し、エラー情報を返す
                System.debug('Request failed with status code: ' + res.getStatusCode());
                return 'Error: Unable to fetch product info. Status: ' + res.getStatus();
            }

        } catch(System.CalloutException e) {
            // コールアウト自体に失敗した場合(例:接続タイムアウト)、
            // CalloutException をキャッチしてエラーを記録します。
            System.debug('Callout error: '+ e.getMessage());
            return 'Error: Callout failed. ' + e.getMessage();
        }
    }
}

ご覧の通り、コード内には認証に関する記述が一切ありません。req.setEndpoint('callout:My_Awesome_API/...') という一行だけで、Salesforce が OAuth トークンの管理とヘッダーへの設定をすべて代行してくれるのです。これにより、コードは非常にクリーンで、本質的なビジネスロジックに集中できています。


注意事項

Named Credentials は非常に強力なツールですが、利用する上でいくつか注意すべき点があります。

権限 (Permissions)

Named Credentials を利用したコールアウトを実行するためには、実行ユーザーのプロファイルまたは権限セットで、対象の External Credential (外部ログイン情報) へのアクセスが許可されている必要があります。管理者は、インテグレーションを実行する必要があるユーザーにのみ、この権限を付与するように注意してください。また、Named Credentials 自体を作成・編集するには、「アプリケーションのカスタマイズ」権限が必要です。

API 制限 (API Limits)

Named Credentials を使用したコールアウトも、Salesforce のガバナ制限の対象となります。具体的には、1 トランザクションあたりのコールアウト回数(同期 Apex では 100 回)、累積タイムアウト時間(120 秒)などの制限が適用されます。大量のデータを扱うバッチ処理などでコールアウトを行う際は、これらの制限に抵触しないように設計する必要があります。

エラー処理 (Error Handling)

コード例で示したように、堅牢なエラー処理は不可欠です。コールアウトは外部システムに依存するため、常に成功するとは限りません。

  • System.CalloutException ネットワークの問題やタイムアウトなど、コールアウトそのものが失敗した場合にスローされます。必ず try-catch ブロックで捕捉してください。
  • HTTP ステータスコード: コールアウトが成功しても、API がエラーを返す場合があります(例:404 Not Found, 500 Internal Server Error)。HttpResponse.getStatusCode() を必ずチェックし、2xx 以外のコードに対する処理を実装してください。
  • 認証エラー: Named Credential の設定が間違っている、または外部システム側で認証情報が無効になった場合、401 Unauthorized や 403 Forbidden といったステータスコードが返されます。これらのエラーを適切にログに記録し、管理者に通知する仕組みを検討することが重要です。

URL のエンコーディング

エンドポイントのパス部分に日本語や特殊文字を含むパラメータを渡す場合、EncodingUtil.urlEncode(stringToEncode, 'UTF-8') を使用して適切にエンコードすることを忘れないでください。これを怠ると、予期せぬエラーの原因となります。


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

Named Credentials は、Salesforce 開発者にとって、外部システム連携を実装する際のデファクトスタンダードと言うべき機能です。認証情報のハードコーディングを排除し、セキュリティを向上させ、環境間の移行を劇的に簡素化します。

ベストプラクティス:

  1. 常に Named Credentials を使用する: Apex からのコールアウトには、原則として常に Named Credentials を使用してください。リモートサイトの設定が不要になるというメリットだけでも、採用する価値は十分にあります。
  2. 命名規則を定める: Named Credential の API 参照名には、分かりやすい命名規則を適用しましょう(例:Google_Maps_API_PROD, SAP_ERP_UAT)。これにより、どのシステムに、どの環境で接続しているのかが一目瞭然になります。
  3. 適切なプリンシパル種別を選択する: システム間連携のように、特定のユーザーに依存しない場合は「Named Principal」を、ユーザー自身の権限で外部サービスを利用させたい場合(例:ユーザー個人の Google Drive に接続)は「Per User」を選択します。
  4. 環境ごとに設定を分ける: Sandbox と本番環境で同じ名前の Named Credential を作成し、それぞれのエンドポイント URL を各環境に合わせて設定します。これにより、コードを変更することなく、環境の移行が可能になります。
  5. 権限を最小限に抑える: Named Credential を利用できるユーザーを、プロファイルや権限セットで厳密に管理し、最小権限の原則に従ってください。

開発者として、Named Credentials の仕組みを深く理解し、正しく活用することで、より安全で、保守性が高く、拡張性のあるインテグレーションを迅速に構築することが可能になります。これは、現代の Salesforce 開発における必須のスキルセットの一つです。

コメント