[salesforce]Force.com上からクライアント認証を使ったWebサービスコールアウト
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クライアント認証を使うための手順は以下のようになります。
- [設定]→[セキュリティのコントロール]→[リモートサイトの設定]にコールアウト先のURLを入力する。ポート番号が特別な場合はポート番号も記述す る。
  
- [設定]→[セキュリティのコントロール]→[証明書とキーの管理]から、クライアント証明書発行用のCSR(と秘密鍵)を作成する。
  
- 発行されたCSRを外部Webサービスを管理するサーバに渡して、そのサーバ上でクライアント証明書を作成してもらう。
 この作業は対象のサーバごとに異なりますが、サンプルシナリオではApache Tomcat/Open SSL環境での例が書かれています。
- 作成されたクライアント証明書を、[設定]→[セキュリティのコントロール]→[証明書とキーの管理]→[署名済証明書のアップロード]からアップロード する。
  
 
- 設定完了したクライアント証明書を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]

