レベル: 中級 Indran Naick (indrann@us.ibm.com), e-business Architect, FIT Team, IBM China Development Lab Reema Gupta, e-business Architect, FIT Team, IBM China Development Lab
2002年 3月 01日 このDragonSlayテクニカル・コンサルティング・チームについての連載第16回目では、Indran NaickとReema Guptaが、顧客からの支払を集金するためのアプリケーションをどういう手順で作り上げたのかを解説します。Go-ForIt.comの実行時アーキテクチャーとIBM WebSphere Payment Managerのセットアップ方法が紹介されます。またSOAP (Simple Object Access Protocol) サーバーの環境やSOAPクライアント、さらにはセキュリティー関係についても少し言及します。
はじめに
この回顧録の第15回では、Go-ForItでオンライン支払処理システムを組み立てるときの、いろいろな選択肢について説明しました。ユーザーがフォームにデータを入力してから実際のSOAP呼び出しを行う手順までの制御の流れを紹介しました。さらにWebSphere Payment Managerで必要となるJavaアプリケーションの説明も行いました。
図1は、Go-ForIt支払処理システム全体の実行時アーキテクチャーを示しています。WebSphere Application Server 4.0上で稼働するGo-ForItアプリケーションには、ネットワークを介してSOAP呼び出しを行うChargeCC() というメソッドが用意されています。この呼び出しに対して、SOAPサーバーは、AcceptPayment.javaを呼び出すことでサービスを行います。AcceptPayment.javaは、Payment Managerに対する呼び出しに含まれているパラメーターを実行します。Payment Managerは、WebSphere Application Server 3.5上で実行されるサーバー・アプリケーションです。
図1. 実行時アーキテクチャー
今回は、以下のことについて解説します。
- 支払処理を実現するためにセットアップした実行時インフラストラクチャー
- Payment Managerサーバーのインストールと構成
- Payment Managerサーバーに接続するためにコーディングしたSOAPクライアント
- セキュリティー関係
SOAPの実行時インフラストラクチャーのセットアップ
図1に示したように、Payment ManagerをWebSphere 3.5上で稼働させました。SOAPサーバーとしては、以下の選択肢を検討しました。
- alphaWorksのWeb Services Toolkitを使用する。
- WebSphere 4.0をインストールして、それに内蔵されているSOAPサポート機能を利用する。この選択肢の場合、同じマシン上にWebSphereの3.5と4.0の両方を稼働させることになります。
- TomcatとApacheのSOAP実装を利用する。
いずれの選択肢も妥当性がありますが、実装が最も簡単なのは選択肢3でした。実稼働環境の場合、これが最善の選択肢ということではないかもしれませんが、選択肢1のセットアップを行い、その説明をするのは、この記事の趣旨から外れることになると考えました。選択肢2は容易でしょうが、さほど重要でもない機能のために、アプリケーション・サーバーを重複させることになります。
選択肢3のセットアップを行うにあたっては、Graham Glassの連載 「Web servicesの進化と革命」 (developerWorks、2000年11月) の手順に従いました。ソフトウェアや関連するjarファイルについては、この記事に出てくるものよりも新しいものを使用しましたが、セットアップの手順については、この記事に従いました。
さらに、SOAPサーバーにAcceptPaymentアプリケーションを登録あるいは配備する必要もありました。これも、大した作業ではありませんでしたが。私たちは、試験的なJavaクライアントを作成し、それをリモートから実行することで、セットアップを試験し、いろいろなテストケースを実行しました。
WebSphere Payment Managerのセットアップ
私たちは、IBM WebSphere Payment Manager V2.2を使用しました。これはWebSphere Application Server V3.5をベースにしていますので、WebSphere Application Server 3.5とDB2を搭載する別個のマシンにインストールしました。Payment Managerをインストールするには、まず、それに使用するデータベースを作成する必要があります。Payment ManagerエンジンとWASを始動しておけば、Payment Managerのユーザー・インターフェースはhttp://"hostname"/PaymentManager/ からアクセスできるようになります。ここで "hostname" は、Payment Managerをインストールしたマシンです。
管理者としてPayment Managerにログインしたら、Payment Managerの構成の設定を開始します。すなわち、マーチャントを作成し、そのマーチャントを認証して、支払カセットを使用できるようにします。(私たちがPayment Managerを使用する主たる目的は、統合機能であり、支払処理機能ではありません。)私たちは、Payment Managerに付属するOfflineCardカセットを使用しました。これは、Payment Manager Frameworkを使ってインストールしたりアンインストールすることができます。OfflineCardカセットは受動カセットで、トランザクションはPayment Managerデータベースでのみ記録され、保守されます。受動カセットの場合、バックエンドの金融システムとはまったく交信しません。
これまでのところ、マーチャントを1つ定義し、支払カセットを1つ有効にしました。Merchant管理者としての次なる作業は、OfflineCardカセット用のアカウントを設定することです。アカウントとは、マーチャントとそのマーチャントのトランザクションを処理する金融機関との間の関係のことです。支払カセットごとに複数のアカウントを設けることができます。私たちは、OfflineCardカセットに対してGo-ForItと呼ばれるアカウントを1つ作成しました。
次にGo-ForItアカウントのブランドを作成します。ブランドとは、VISAやMasterCardなどのクレジット・カードの種類のことです。アカウントに対するブランド(群)は、マーチャントによって定義されるアカウントの条件にしたがって定義します。Go-ForItプロジェクトでは、Visa、Master Card、American Express、およびDiscoverのカードを受け付けるようにしますので、Go-ForItアカウントに、これらのブランドを作成しました。
OfflineCardカセット
OfflineCardカセットを使用することで、マーチャントは以下のことが可能になります。
- それぞれのマーチャントのオンライン・ストアの標準的な購入ページを使って、Payment Managerでクレジット・カードやデビット・カードの情報を収集する。この情報は、AcceptPaymentコマンドを使ってPayment Managerに入力されます。AcceptPaymentコマンドは、データを新しいOrderオブジェクトに格納します。
- 手作業でクレジット・カードの処理を行うためのクレジット・カードやデビット・カードの情報をPayment Managerから読み出す。
- 手作業によるクレジット・カード・トランザクションの状態をPayment Managerに記録する。たとえば、マーチャントは、OrderウィンドウにApprove (承認)ボタンを設けることもできるでしょう。トランザクションの記録は、支払、クレジット、およびバッチ型のすべての処理について実行することができます。
- Payment Managerのバッチ機能およびレポート機能を使って、日々のバッチ処理を管理する。
- これらすべての処理を、マーチャントがオンライン・トランザクションに使用するものと同じインターフェースを使って実行する。
通常のOfflineCardカセット処理では、買物客がマーチャントのオンライン・ストアで品物を購入する際、購入ページが表示され、買物客のクレジット・カード情報が収集されます。買物客がこの情報をサブミットすると、マーチャントのソフトウェアは、AcceptPaymentコマンドをPayment Managerにサブミットします。支払方法としてOfflineCardが選択されていますので、OfflineCardカセットを呼び出して、プロトコルに対応した情報 (すなわち、PAN、Expiry、およびBrand) を処理し、それを新しいOrderオブジェクトとともにPayment Managerデータベースに記録します。これで、買物客の支払情報は記録され、後でマーチャントがそれを利用できるようになります。1日が終わると、マーチャントはPayment Managerを使って、その日に受けたOfflineCard支払によるすべてのオンライン注文を確認します。いずれの作業でも、マーチャントは、クレジット・カードの情報を入力し、手作業で承認コードまたは拒否コードを受信し、OrderウィンドウにあるApprove ボタンを使って (このボタンがApproveコマンドを発行する) Payment Managerにこれらの情報を記録します。対応する承認 / 拒否コードを記録するための入力フィールドが用意されています。買物が承認された場合は、マーチャントは買物客が注文した品物を梱包し、出荷し、対応するPayment ManagerウィンドウにあるDeposit ボタンを使ってDepositコマンドを発行します。
マーチャントが支払とクレジットの処理を終え時点で、日々のバッチ処理は、時刻に基づいて、金融機関によって休止されます。このことを記録するために、マーチャントは、BatchウィンドウにあるSettle ボタンを使うか (このボタンがBatchCloseコマンドを発行する)、カセットがAccountオブジェクトに用意しているBatchCloseTime構成パラメーターを使うかして、バッチが閉塞したことを明示的に記録することができます。私たちの場合、登録サーブレットから直接AcceptPaymentコマンドを呼び出すのではなく、支払ごとの情報をSOAPサーバーに送信することで、SOAPサーバーがAcceptPaymentコマンドを呼び出すようにしています。
注文を受けた場合、Payment Managerのインターフェースを使って次のことが可能です。すなわち、注文の承認、注文の処理のために金融機関に処理を開始させるためのバッチ停止、クレジットの発行、および他の支払に関連した機能です。以下の図2 は、Payment Managerのインターフェースを示したものです。
図2. WebSphereのPayment Manager
注文の詳細は、注文番号をクリックすることで、図3 のような形で確認することができます。
図3. 注文の詳細
SOAPクライアント・コード
次は、クライアント・コードです。前回の記事で、実際にコードを統合している部分、すなわちメソッドchargeCC() について説明しました。このコードを使用して、SOAPエンベロープを「構成」し、インフラストラクチャーへの呼び出しを行います。このクライアントのコードは、非常に単純なものでした。呼び出しを行うには、使用すべきすべてのクラスをカバーするために、パッケージをいろいろとインポートする必要がありました。mail.jar、activation.jar、soap.jar、xerces.jar を用意しておく必要があります。いずれもダウンロードが可能です。正しいバージョンを使っているか確認してください。
必要なパッケージのインポート
import java.net.*;
import java.util.*;
import org.apache.soap.*;
import org.apache.soap.rpc.*;
|
次に、URLが有効かどうかを、クライアント側からチェックします。
URLのチェック
Check the URL
URL url = null;
try {
url = new URL("http://9.3.99.91:8070/soap/servlet/rpcrouter");
} catch (MalformedURLException e) // call could not be sent properly
{
System.out.println("URLException= " + e + ", " + e.getMessage());
}
|
以下のコードは、デフォルトのエンコード方式を、標準のSOAPエンコード方式としています。これは、XMLスキーマの型付けに基づくものです。
SOAPサーバーの場所を調べ、エンコード方式を設定し、サービス呼び出しの準備を行い、ターゲット・オブジェクトのURIを設定する
Call call = new Call();
String urn = "urn:demo1:acceptpayment";
Call.setTargetObjectURI(urn);
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
|
以下のコードは、オブジェクトのインターフェースに対して呼び出しを行いたいメソッドの名前を設定しています。
呼び出したいメソッドの名前を指定する
call.setMethodName("makePmt");
|
次に、パラメーター・ベクトルのセットアップを行います。この呼び出しオブジェクトは、パラメーターのベクトルを取ります。それぞれのパラメーターは、呼び出されるメソッドへの引数を表します。これらのパラメーターは、それぞれのパラメーターがとるオブジェクトの型にしたがってシリアライズを行うマッピング・システムを使って「送信用に」シリアライズされます。上で設定された「デフォルト」のエンコード方式とは別のエンコード方式を、個々のパラメーターごとに設定することもできます。パラメーター・リストにシリアライザーが認識できない型の変数が含まれていることが型マッピング・システムによって検出された場合には、例外がスローされます。たとえば、パラメーターのラベルをLiteral XMLのエンコード方式で指定しながらStringオブジェクトとして渡している場合、Literal XMLエンコード方式は「Element」型の値を予期していますので、「String」を認識できません。
パラメーターの設定
Vector params = new Vector();
params.addElement(new Parameter("pan", String.class, user.getCcnum(),
Constants.NS_URI_SOAP_ENC));
params.addElement(new Parameter("brand", String.class, user.getCctype(),
Constants.NS_URI_SOAP_ENC));
StringTokenizer st = new StringTokenizer(user.getExpdate().toString(), "-");
String strDate = st.nextToken() + st.nextToken();
params.addElement(
new Parameter("expiry", String.class, strDate, Constants.NS_URI_SOAP_ENC));
params.addElement(
new Parameter("street", String.class, user.getStreet1(),
Constants.NS_URI_SOAP_ENC));
params.addElement(new Parameter("city", String.class, user.getCity(),
Constants.NS_URI_SOAP_ENC));
params.addElement(new Parameter("state", String.class, user.getState(),
Constants.NS_URI_SOAP_ENC));
params.addElement(new Parameter("zipcode", String.class, user.getZip(),
Constants.NS_URI_SOAP_ENC));
Now, we add the parameter to the call object:
call.setParams(params);
|
URLオブジェクトは、リクエストを受信することになるSOAPエンドポイントを表します。通常 (少なくともApacheのSOAPサーバーでは)、1個のSOAPエンドポイントで、複数のオブジェクトのインターフェースやメソッドの呼び出しを処理することができます。
メソッドの呼び出しと例外処理
try {
Response response = call.invoke(url, ""); // invoke the service
if (!response.generatedFault()) {
Parameter result = response.getReturnValue();
}
else {
throw new CreditCardNotAuthorizedException();
// Note: We should write an unique Exception class for this exception
}
} catch (SOAPException e) {
throw new CreditCardNotAuthorizedException();
}
|
SOAPのクライアント・コードでは、手近な作業だけを行えばよく、トランスポート・レベルのこまごましたことまでタッチする必要はありません。外部のプロバイダーを使用している場合のサービスを利用できるまでの手順、セキュリティー、サービス・レベル・アグリーメントなど、当然起こってくる問題がいくつかあります。これらの問題が関係してくるかどうかは、解決しようとしている問題によって違ってきます。
セキュリティー関係
私たちの環境では、セキュリティー関係のことは何も組み込みませんでした。ここでは、私たちが気付いた問題と、そうした問題の解決に利用できるいくつかの解決策を簡単に紹介しておきます。私たちのシナリオでセキュリティーが必要であると認められたことに、以下の2つがあります。
- Webサーバーとユーザーとの間。データ、とくにクレジット・カード番号やパスワードが暗号化されないまま送信されることがないようにする。
- Go-ForItのサーバーとSOAPサーバーの間。SOAPサーバーに対してなされる呼び出しを安全・確実なものにする。
1番目のセキュリティーの要件は、広く使用されているSSLを利用し、フォームを保証し、送信データを暗号化することで、簡単に満足させることができます。
これに対して2番目のセキュリティーの要件は、もっとずっと難しい問題で、これについては、羽田知史著の「SOAPセキュリティ拡張:電子署名」で詳しく扱われています。ここでは、概略のみを紹介しておきます。これらの問題の詳細については、羽田知史氏の記事を参照してください。
私たちの場合、Go-ForItのサーバーもPaymentサーバーも同じイントラネット内にありました。完全なセキュリティーを確保するわけではありませんが、簡単な解決策として、SOAPサーバーの実行されるポートを変更し、それに合わせてクライアントのコードを変更することが考えられます。そして、このポート経由での呼び出しができないようにファイアウォールを設定します。もちろん、これが素晴らしい解決策だというわけではありません。
サーバーについて言えば、羽田知史氏の記事で説明されているように、SOAPサーバーが確実に本物のメッセージを受信するようにし、また、そのメッセージを送信しているユーザーをSOAPサーバーが認証できるようになればよいでしょう。
さらに、会計検査を行うために、否認不可性 (non-repudiation) を確保することが求められるでしょう。否認不可性が必要なのは、悪意をもつ送信者がいるかもしれないことからです。否認不可性は、悪意のある送信者が、メッセージを作成し送信したことを後で否認できないようにするものです (つまり、否認不可性によって、メッセージの送信者がそのメッセージの作成者と同一人物であることを保証するということです)。そのためには、以下の3つのことが必要となります。
- メッセージの認証
- 送信者 / 受信者の認証
- 否認不可性
メッセージの認証
メッセージの認証に使用されるテクノロジーには、メッセージ認証コード (Message Authentication Code: MAC) とディジタル署名 (Digital Signatures) があります。SOAPセキュリティー拡張のもともとの動機: ディジタル署名 (SOAP-DSIG) のもともとの動機は、SOAPメッセージにディジタル署名を付加することでした。SOAP-DSIGでは、SOAPメッセージにXML署名を付加するためのデータ・フォーマットが定義されます。ディジタル署名は、公開鍵暗号方式に基づいていますので、一般に、ディジタル署名を計算するのに、非公開の共通鍵を使用するMACよりもずっと多くの時間を要します。ただし、(MACの場合のように) 送信者も受信者も共通鍵を共有する必要がなくなったわけですので、メッセージの作成者を識別することができます。すなわち、署名人が作成者であることが保証されます。
(訳注:2002年4月11日に、IBM・マイクロソフト・ベリサインは共同でSOAPのセキュリティ拡張の仕様WS-Security を発表しました。WS-Securityは、「SOAPセキュリティー拡張:デジタル署名」に代わる仕様と位置付けられています。)
送信者/受信者の認証
送信者 / 受信者の認証によく使用されるテクノロジーは、パスワード認証とSSLサーバー / クライアント認証の2つです。パスワード認証の例としては、HTTP基本認証とフォームによる認証があります。HTTPのクライアントは、自身のIDおよびパスワードを送信することで (通常SSLを使って)、HTTPサーバーに対して自分自身の認証を行うことができます。このSSLサーバー・クライアント認証では、HTTPのサーバーおよびクライアントのIDを、公開鍵証明書を使って、相互に認証します。
否認防止
否認不可性は、今Go-ForItで必須だというわけではありませんが、たぶん、こうしたソリューションの多くで、これが必要となるでしょう。これを実現するためには、上記のテクノロジーを組み合わせて使用する必要があります。SOAPセキュリティ拡張:電子署名では、SOAP-DSIGとSSLを使って否認不可性を実現することが提案されており、この問題を解決する上でのこれら2つのテクノロジーの利用方法が余さず説明されています。
次回も請うご期待
Go-ForIt物語の次回をご期待ください。次回は、Go-ForItアプリケーションをWebSphere Application Serverバージョン3.5.4からバージョン4.0に移し変える話です。私たちの竜退治 (dragonslaying) のお話の前回までの記事は、overview (概要)から参照できます。いずれ、安全な支払トランザクションを確保するための環境を作り上げる方法についても紹介する予定です。
参考文献
著者について  | 
|  | Indran Naickは、米国テキサス州オースチンにあるIBM Developer Relations Technical Consulting (IBMのビジネス・パートナーへの教育、補助、相談を行う組織) 勤務のe-businessアーキテクトです。氏には、14年以上の業界経験があり、1990年から南アフリカIBMに勤務するようになりました。オースチンに転勤するまでは、数多くの金融機関、政府機関に対するSoftware Solutions Architectコンサルティングを行っていました。南アフリカWitwatersrand大学卒で、執筆も数多く行っています。 |
 | |  | Reema Guptaは、米国テキサス州オースチンにあるIBM Developer Relations Technical Consulting (IBMのビジネス・パートナーへの教育、補助、相談を行う組織) 勤務のe-businessアーキテクトです。女史は、IBM and GE Capital Information Technology Solutionsでの7年間の経歴の中で、いろいろなe-businessアーキテクチャーやソフトウェアの開発を行ってきました。IBM認定のe-businessソリューション・デザイナー、IBM認定のe-businessソリューション・テクノロジスト、およびIBM認定の スペシャリスト (これら3つはWebSphere Commerceスイート) でもあります。 |
記事の評価
|