[salesforce]Force.com上からクライアント認証を使ったWebサービスコールアウト

By |3月 23, 2010|salesforce, |


APEXコードを記述することによって、Force.comプラットフォーム上から外部WebサービスへのHTTPコールアウトを実装することができます。HTTPコールアウトを実装することによって、例えばForce.com上で特定のデータ更新がされた際にその情報を外部のWebサービスにも保存したり、Force.com上の特定のページに表示する値を外部のWebサービスから動的に取得する、なんてことが実現できます。

このHTTPコールアウトをよりセキュアに行う方法として、SSLクライアント認証を行うための仕組みがForce.comには用意されています。

参考:Making Authenticated Web Service Callouts Using Two-Way SSL

Force.comから外部WebサービスへHTTPコールアウトする際にSSLクライアント認証を使うための手順は以下のようになります。

  1. [設定]→[セキュリティのコントロール]→[リモートサイトの設定]にコールアウト先のURLを入力する。ポート番号が特別な場合はポート番号も記述す る。
  2. [設定]→[セキュリティのコントロール]→[証明書とキーの管理]から、クライアント証明書発行用のCSR(と秘密鍵)を作成する。
  3. 発行されたCSRを外部Webサービスを管理するサーバに渡して、そのサーバ上でクライアント証明書を作成してもらう。
    この作業は対象のサーバごとに異なりますが、サンプルシナリオではApache Tomcat/Open SSL環境での例が書かれています。
  4. 作成されたクライアント証明書を、[設定]→[セキュリティのコントロール]→[証明書とキーの管理]→[署名済証明書のアップロード]からアップロード する。
    ws000176
  5. 設定完了したクライアント証明書をAPEXコードから使用する。HTTP RequestクラスのsetClientCertificateNameメソッドを使う。サンプルコードを下記しますが、ポイントは35行目のreq.setClientCertificateName(certName)です。これによりHTTPコールアウト時にクライアント証明書を使うようにしています。
    コード例:
    [php]
    public class InvoiceServiceAccountExtension {

    private final String serviceEndpoint =
    ‘http://api.acmecorp.com:8888/InvoiceService/list’;
    private final String certName = ‘csr_test’;

    private final Account acct;

    public class Invoice {
    public Integer invoiceNumber {get;set;}
    public Integer orderNumber {get;set;}
    public Integer contractNumber {get;set;}
    public Date dueDate {get;set;}
    public Double amount {get;set;}
    public String status {get;set;}

    public void from_xml(dom.XmlNode node) {
    invoiceNumber = Integer.valueOf(node.getChildElement(‘invoice-number’,null).getText());
    orderNumber = Integer.valueOf(node.getChildElement(‘order-number’,null).getText());
    contractNumber = Integer.valueOf(node.getChildElement(‘contract-number’,null).getText());
    dueDate = Date.parse(node.getChildElement(‘due-date’,null).getText());
    amount = Double.valueOf(node.getChildElement(‘amount’,null).getText());
    status = node.getChildElement(‘status’,null).getText();
    }
    }

    public List<Invoice> invoices {
    get {
    if(invoices==null) {
    Http h = new Http();
    HttpRequest req = new HttpRequest();
    req.setEndpoint(serviceEndpoint+’?id=’+acct.id);
    req.setMethod(‘GET’);
    if(certName!=null) {
    req.setClientCertificateName(certName);
    }
    HttpResponse res = h.send(req);

    if(res.getStatusCode()>299) {
    System.debug(‘ERROR: ‘+res.getStatusCode()+’: ‘+res.getStatus());
    System.debug(res.getBody());
    } else {
    dom.Document doc = res.getBodyDocument();
    invoices = new List<Invoice>();
    for(dom.XmlNode node : doc.getRootElement().getChildElements()) {
    if(node.getName()==’invoice’) {
    Invoice iv = new Invoice();
    iv.from_xml(node);
    invoices.add(iv);
    }
    }
    }
    }
    return invoices;
    }
    set;
    }

    public InvoiceServiceAccountExtension(ApexPages.StandardController stdController) {
    this.acct = (Account)stdController.getRecord();
    }
    }
    [/php]