[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]