Salesforce 指定ログイン情報(Named Credentials): 安全な API 連携のための完全ガイド

背景と適用シナリオ

Salesforce プラットフォーム上で外部システムとの連携を開発する際、最も重要な課題の一つが「認証情報の管理」です。外部サービスの API を呼び出す (Callout) には、API キー、ユーザー名とパスワード、あるいは OAuth 2.0 のアクセストークンといった認証情報が必要になります。

従来、これらの認証情報を管理する方法にはいくつかの課題がありました。

従来の認証情報管理方法とその問題点

  • コードへのハードコーディング: Apex コード内に直接パスワードや API キーを書き込む方法です。これは最も危険な方法であり、セキュリティリスクが非常に高く、認証情報が変更されるたびにコードの修正と再デプロイが必要になります。
  • カスタム設定 (Custom Settings) / カスタムメタデータ (Custom Metadata): コードへのハードコーディングよりは優れていますが、依然として課題は残ります。これらの場所に保存された認証情報は、適切な権限を持つユーザーには参照可能であり、平文で保存されている場合はセキュリティ上のリスクとなります。また、環境ごとに認証情報を手動で更新する必要があり、管理が煩雑になりがちです。
  • メンテナンスの複雑さ: 外部システムの認証情報(特にパスワード)は定期的に変更されることがあります。また、開発 (Sandbox) 環境と本番 (Production) 環境ではエンドポイント URL や認証情報が異なるのが一般的です。これらの変更に対応するために、複数の場所で設定を更新する必要があり、ヒューマンエラーの原因となります。

これらの課題を解決するために Salesforce が提供する標準機能が Named Credential (指定ログイン情報) です。Named Credential は、API 連携におけるエンドポイント URL と認証情報を一元的に、かつ安全に管理するための仕組みです。Apex コードから認証情報を完全に分離することで、セキュリティを向上させ、メンテナンス性を劇的に改善します。

具体的な適用シナリオとしては、以下のようなケースが挙げられます。

  • Google Maps API や天気予報 API などの公開 Web サービスとの連携
  • SAP や Oracle などの基幹システム (ERP) とのデータ同期
  • 社内のマイクロサービスアーキテクチャで構築された別システムとの連携
  • OAuth 2.0 フローを利用して、ログインユーザーのコンテキストで外部サービスを操作する機能

原理説明

Named Credential (指定ログイン情報) は、単なる認証情報のコンテナではありません。これは、コールアウトのエンドポイント URL と認証プロトコルを抽象化し、Apex コードから透過的に利用できるようにするための強力なフレームワークです。

その中核となるコンセプトは「関心の分離」です。開発者は Apex コード内で「どの外部サービスを呼び出すか」だけを意識すればよく、「どのように認証し、どの具体的な URL に接続するか」という詳細は Named Credential に任せることができます。

主要な構成要素

Named Credential の設定は、主に以下の要素で構成されます。

  1. 名前 (Label/Name): この Named Credential を一意に識別するための表示ラベルと API 参照名です。Apex コードからはこの API 参照名を使って呼び出します。
  2. URL: 呼び出す外部サービスのベース URL です。例えば、`https://api.example.com/v1` のような形式です。Apex コード内で指定するパスは、この URL の後ろに結合されます。
  3. External Credential (外部ログイン情報): 認証の具体的な設定を定義します。Winter '23 以降、認証に関する部分は External Credential に分離され、より再利用しやすくなりました。Named Credential はこの External Credential を参照する形になります。
  4. Principal (プリンシパル): 外部サービスに誰として接続するかを定義します。External Credential 内で設定されます。
    • Named Principal (指定ユーザ): 組織全体で単一の認証情報セット(例: システムアカウントのユーザー名とパスワード)を使用します。システム間連携で一般的に利用されます。
    • Per User (ユーザごと): コールアウトを実行する Salesforce ユーザーごとに個別の認証情報を使用します。主に OAuth 2.0 で利用され、各ユーザーは外部サービスへのアクセスを一度許可する必要があります。Salesforce がユーザーごとの認証フローとトークン管理を代行します。
  5. Authentication Protocol (認証プロトコル): External Credential で設定される認証方式です。
    • No Authentication: 認証が不要な公開 API などで使用します。
    • Password Authentication: Basic 認証(ユーザー名とパスワード)を使用します。
    • OAuth 2.0: 最も広く使われている認証方式の一つです。Authorization Code フローや JWT Bearer フローなど、様々なフローをサポートします。
    • AWS Signature Version 4: Amazon Web Services (AWS) の API へのアクセスに使用します。

Apex からの利用方法

Apex コードから Named Credential を利用する際は、特別な `callout:` プレフィックスを使用します。

例えば、`My_External_Service` という名前の Named Credential があり、その URL が `https://api.example.com` に設定されているとします。このサービスの `/users/123` というパスにアクセスしたい場合、Apex コードではエンドポイントを以下のように指定します。

`'callout:My_External_Service/users/123'`

このリクエストが実行されると、Salesforce プラットフォームは以下の処理を自動的に行います。

  1. `My_External_Service` という Named Credential の設定を読み込みます。
  2. 設定された認証プロトコル(例: Password Authentication)に基づき、保存されているユーザー名とパスワードを取得し、`Authorization` ヘッダーを自動的に生成・付与します。
  3. `callout:My_External_Service` の部分を、設定されている URL (`https://api.example.com`) に置き換えます。
  4. 最終的に、適切な認証ヘッダーが付与された状態で `https://api.example.com/users/123` に対して HTTP リクエストが送信されます。

この仕組みにより、Apex コードには認証情報が一切含まれず、エンドポイントの具体的な URL もハードコーディングされません。その結果、本番環境の認証情報を開発者が知る必要がなくなり、セキュリティが大幅に向上します。また、外部サービスの URL やパスワードが変更された場合でも、コードを修正することなく、Salesforce の設定画面で Named Credential を更新するだけで対応が完了します。


示例代码 (サンプルコード)

ここでは、`Password Authentication` を使用する Named Credential を介して、外部の REST API からデータを取得する簡単な Apex の例を示します。

前提条件

  1. Named Credential の作成:
    • 名前 (Label): My External Service
    • API 参照名 (Name): My_External_Service
    • URL: `https://api.example.com`
    • External Credential: 新規作成し、認証プロトコルとして `Password Authentication` を選択。外部システムのユーザー名とパスワードを設定します。

以下の Apex コードは、上記の Named Credential を使用して API コールアウトを実行します。このコードは Salesforce の公式ドキュメントで推奨されている標準的な形式です。

// 外部サービスからデータを取得するメソッド
public class ExternalServiceCaller {
    public static String getSomeData() {
        // HttpRequest オブジェクトをインスタンス化
        HttpRequest req = new HttpRequest();

        // エンドポイントを設定
        // 'callout:' プレフィックスと Named Credential の API 参照名、
        // そして、ベース URL に続く相対パスを指定する。
        // ここでは '/path/to/resource' が相対パスにあたる。
        req.setEndpoint('callout:My_External_Service/path/to/resource');

        // HTTP メソッドを GET に設定
        req.setMethod('GET');

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

        try {
            // send() メソッドでリクエストを送信し、レスポンスを受け取る
            // Salesforce が裏側で認証ヘッダーを自動的に付与してくれる
            res = http.send(req);

            // レスポンスのステータスコードをチェック
            if (res.getStatusCode() == 200) {
                // 成功した場合、レスポンスボディを返す
                return res.getBody();
            } else {
                // エラーが発生した場合、ステータスコードとメッセージをログに出力
                System.debug('Error from callout. Status: ' + res.getStatus());
                System.debug('Status Code: ' + res.getStatusCode());
                System.debug('Response Body: ' + res.getBody());
                return 'Error: ' + res.getStatusCode();
            }
        } catch(System.CalloutException e) {
            // コールアウト自体に失敗した場合 (例: タイムアウト、名前解決不可)
            System.debug('Callout error: '+ e);
            return 'Callout Error: ' + e.getMessage();
        }
    }
}

このコードからわかるように、開発者は認証情報の詳細(ユーザー名、パスワード、ヘッダーの形式など)を一切意識する必要がありません。`setEndpoint` で `callout:` スキームを使うだけで、残りの複雑な処理はすべて Salesforce プラットフォームが担ってくれます。


注意事項

Named Credential は非常に強力な機能ですが、利用にあたってはいくつかの重要な点を理解しておく必要があります。

権限 (Permissions)

  • Named Credential の作成・編集: システム管理者は「アプリケーションのカスタマイズ」権限を持っている必要があります。
  • Per User 認証の利用: `Per User` (ユーザごと) の認証方式を使用する場合、コールアウトを実行するユーザーは、関連する External Credential (外部ログイン情報) へのアクセス権を持っている必要があります。この権限は、Permission Set (権限セット) または Profile (プロファイル) を通じて付与します。ユーザーがこの権限を持っていない場合、コールアウトは認証エラーで失敗します。

API 制限 (API Limits)

Named Credential を使用しても、Salesforce の Governor Limits (ガバナ制限) が免除されるわけではありません。

  • トランザクションあたりのコールアウト回数(同期 Apex では 100 回)
  • コールアウトのタイムアウト(最大 120 秒)
  • ヒープサイズや CPU 時間などの標準的な制限

これらの制限は通常通り適用されるため、大量のデータを扱う連携処理では、非同期処理 (Future, Queueable, Batch Apex) の利用を検討する必要があります。

エラー処理 (Error Handling)

API 連携にはエラーがつきものです。Named Credential を利用したコールアウトでも、堅牢なエラーハンドリングは不可欠です。

  • `System.CalloutException` の捕捉: ネットワークの問題やタイムアウト、DNS 解決の失敗など、HTTP レスポンスを受け取る前に発生した問題は `CalloutException` としてスローされます。必ず `try-catch` ブロックで捕捉してください。
  • HTTP ステータスコードの確認: 認証情報の誤り (401 Unauthorized)、アクセス権の不足 (403 Forbidden)、リソースが見つからない (404 Not Found)、サーバー内部エラー (500 Internal Server Error) など、API から返されるステータスコードを必ず確認し、コードに応じて適切な処理分岐を行う必要があります。

リモートサイトの設定 (Remote Site Settings)

Named Credential の最大の利点の一つは、Remote Site Settings (リモートサイトの設定) が不要になることです。`callout:` スキームを使用して指定されたエンドポイントは、Salesforce によって自動的に信頼されるため、別途リモートサイトに URL を登録する必要がありません。これにより、環境構築の手間が大幅に削減され、デプロイ時の設定漏れを防ぐことができます。


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

Named Credential (指定ログイン情報) は、Salesforce から外部システムへの API コールアウトを実装する上で、現代の標準的な手法であり、セキュリティ、メンテナンス性、俊敏性の観点から強く推奨されるベストプラクティスです。

以下に、効果的に活用するためのベストプラクティスをまとめます。

  1. 常に Named Credential を使用する: 認証情報を Apex コード、カスタム設定、カスタムメタデータに保存することは避け、必ず Named Credential を利用してください。これがセキュリティとメンテナンス性を確保するための第一歩です。
  2. 環境ごとに設定を分離する: 開発、テスト、本番といった各環境用に、それぞれ異なる Named Credential を作成します (例: `MyAPI_DEV`, `MyAPI_UAT`, `MyAPI_PROD`)。Apex コードからは、カスタム表示ラベルやカスタムメタデータを使って、現在の環境に応じた Named Credential 名を動的に取得するように実装すると、コードを変更することなく環境を切り替えられます。
  3. 適切な Principal を選択する:
    • システム間連携のように、単一の ID で API を呼び出す場合は Named Principal (指定ユーザ) を使用します。
    • ユーザーの代理として外部サービスの操作を行う場合は、セキュリティの観点から Per User (ユーザごと) の OAuth 2.0 認証を選択します。
  4. 最小権限の原則を適用する: Per User 認証を利用する際は、本当にその機能が必要なユーザーにのみ、権限セットを通じて External Credential へのアクセスを許可してください。
  5. 最新の機能を活用する: Winter '23 で導入された External Credential の仕組みを理解し、認証設定とエンドポイント設定を分離することで、より再利用性が高く管理しやすい構成を目指しましょう。

Named Credential を正しく活用することで、開発者は認証という複雑な処理から解放され、ビジネスロジックの実装に集中できます。これにより、より安全で、保守しやすく、変化に強い Salesforce アプリケーションを構築することが可能になります。

コメント