Topics
Enterprise Architecture
Oracle WebLogic Server 9.2によるWebサービスの保護
ページ:
1,
2,
3
次に、メッセージへの機密保護の追加について見ていきます。つまり、ここではクライアントとサーバー間のメッ セージ(SOAP本文)の暗号化をおこなうこととなります。この処理の基本的な手順はメッセージへの整合性の追加と同じで、サービスにアノテーションをつ けて再生成してからクライアントを更新します。
WTPで
HelloWorldService.javaを開きます。以下のスクリプトで
ハイライトされているアノテーションを追加します。
@Policies({
@Policy(uri="policy:Sign.xml")
,
@Policy(uri="policy:Encrypt.xml"
)
})
(
Sign.xmlアノテーションのうしろには、かならずカンマを追加してください。)
このアノテーションにより、クライアントとサーバーで暗号化が使用されるように指定されます。デフォルトでは、 暗号化は双方向(クライアントからサーバー、およびサーバーからクライアントの両方)に設定されています。一方向の暗号化のみが必要な場合は、アノテー ションにオプション属性の
directionを追加することで対応できます。
ここで、サービスを再構築する必要があります。コマンド・シェル・ウィンドウから、
antコマンドを実行します。前述の手順の場合と同様に、
BUILD SUCCESSFULメッセージが表示されます。
次に、クライアントの更新をおこないます。まず、前の項でおこなったように、ブラウザからWSDLファイルを取得して保存します。保存したファイルをエディタで開きます。ファイルには、新しい要素
wssp:Confidentialityが追加されています。これは、クライアントに対し、暗号化が使用されることを示すヒントとなります。また、以下のスクリプトからもわかるように、
Encypt.xmlポリシーも含まれています。
<wsp:Policy s0:Id="Encrypt.xml">
...
</wsp:Policy>
...
<portType name="HelloWorldPortType" wsp:PolicyURIs="#Sign.xml #Encrypt.xml">
..
</portType>
このWSDLファイルは、新しいデプロイメントによって生成されたものであるため、モニター用のポート番号をもう一度更新する必要があります。このWSDLファイルの最後に近い部分に、次のような行があります。
<s2:address location="http://localhost:7001/HelloWorldService/HelloWorldService"
以下のように、この行のポート番号を7002に変更します。
<s2:address location="http://localhost:
7002/HelloWorldService/HelloWorldService"/>
WSDLファイルを保存してから終了します。次に、コマンド・シェルでコマンド
ant -buildfile gen-client.xmlを実行します。
BUILD SUCCESSFULメッセージが表示されます。これで、クライアントのプロキシが更新されました。
次のステップは何でしょうか。実質的には、これ以上変更をおこなう必要はありません。クライアントでは、メッ セージが暗号化されるようにするためにコードを追加する必要はなく、更新されたクライアント・プロキシによって、すべての暗号化処理がおこなわれます。こ れはWebサービスのセキュリティ・メカニズムを利用することの大きな利点の1つで、これにより、開発者は暗号化のコードを1行も書く必要がなくなりま す。
HelloWorldClientを実行します。レスポンスとして、前の手順と同じあいさつが表示されます。何が変わったのでしょうか。一見したところ、何も変わっていないように見えます。しかし、TCP/IPモニターを確認すると、以前にチェックしたときは特定できた
<name>要素を見つけることができないはずです。つまり、リクエストとレスポンスの両方が暗号化されていることがわかります。<name>要素があった場所には、暗号化されたテキストと一緒に
<CipherData>要素が表示されています。ただし、暗号化されているのは、メッセージの本文(リクエストの場合は
name要素、レスポンスの場合は
return要素)だけで、メッセージのヘッダーはすべて暗号化されずにそのままとなっています。また、
ns1:EncryptedKey要素がセキュリティ・ヘッダー(
wsse:Security)に追加されています。
これで、メッセージの機密保護がサービスに追加されました。
次に、Webサービスへの認可メカニズムの追加をおこなうことができます。簡単にいえば、クライアント側に SOAPリクエストでユーザー名とパスワードを含めるように強制することができます。WebLogic Serverのユーザー・レジストリ内にそのユーザー名とパスワードがない場合は、サーバーからサービスへのアクセスを拒否されます。これにより、ある種 のアクセス制御が可能となります。これは、メッセージの整合性についての識別部分とは異なることに注意してください。メッセージの整合性では証明書を使用 してクライアントのIDをアサートしますが、認証においては、サービスを呼び出すための実際の認可レベルをクライアントが保有しているかどうかが問題とな ります。WebLogic Serverのユーザー・レジストリに対する認証に成功していないクライアントがサービスを呼び出そうとすると、サーバーによりサービスへのアクセスが拒 否されます。
この項のチュートリアルでは、WebLogic Serverのユーザー・レジストリにユーザーを追加し、クライアントで強制的に認証がおこなわれるようにサービスを変更します。そのあと、クライアントを使用して、変更したサービスに対するテストをおこないます。
まず最初に、WebLogic Serverのユーザー・レジストリでユーザーを作成します。デフォルトでは、ユーザー・レジストリとして、WebLogic Serverに同梱されている埋込みLDAPサーバーが指定されていますが、WebLogic Serverの管理コンソールを使用すると、このレジストリにユーザーを追加することができます。サーバーが実行中であることを確認し、ブラウザを使用し てhttp://localhost:7001/consoleに移動します。ユーザー名に
weblogic、パスワードに
passwordを使用してログインします。管理コンソールが開きます。
左側のDomain Structureペインで、「 Security Realms」をクリックします。右側のペインで、「 myrealm」をクリックします。この myrealmには、WebLogic Serverの現在のセキュリティ構成が示されています。この構成に、テスト・ユーザーを追加していきます。「 Users and Groups」タブをクリックします。「 New」ボタンをクリックします。
Nameに、
suzieと入力します。
Descriptionに、
An authenticated Web service userと入力します。
Passwordフィールドと
Confirm Passwordフィールドには、
munchkinと入力します。「
OK」をクリックします。
WebLogic Serverのユーザー・レジストリに新しいユーザーが作成されました。これで、サービスを編集し、すべてのクライアントでユーザー名とパスワードを入力 して認証がおこなわれるように設定することができます(使用するユーザー名とパスワードは、レジストリに登録されているユーザーと一致する必要がありま す)。WTPで、
HelloWorldService.javaを開き、以下のスクリプトで
ハイライトされているアノテーションを追加します。
@Policies({
@Policy(uri="policy:Sign.xml"),
@Policy(uri="policy:Encrypt.xml")
,
@Policy(uri="policy:Auth.xml"
,direction=Policy.Direction.inbound)
})
この新しいアノテーションにより、認可ポリシーがインバウンド・トラフィックだけに適用されるように指定されます。(この例では、クライアント側に対する認証をサーバーに求めるのは意味がありません。)
ファイルを保存します。このコードにはエラーはないはずです。これで、サービスを構築してデプロイすることができます。コマンド・シェル・ウィンドウから、
antコマンドを実行します。前述の手順の場合と同様に、
BUILD SUCCESSFULメッセージが表示されます。
これでサービスの再生成が完了したため、前述の手順と同様に、ここでもクライアント・プロキシを再生成する必要があります。前の項でおこなったように、ブラウザからWSDLファイルを取得して保存します。保存したファイルをエディタで開きます。新しい要素
wssp:Identityが表示されています。これは、クライアントに対し、サービス呼出しの際にユーザー名とパスワードを送信する必要があることを示すヒントとなります。また、以下のスクリプトからわかるように、新しい
Auth.xmlポリシーも含まれています。
<wsp:Policy s0:Id="Auth.xml">
...
</wsp:Policy>
...
<input>
<s2:body parts="parameters" use="literal"/>
<wsp:Policy>
<wsp:PolicyReference URI="#Auth.xml"/>
</wsp:Policy>
</input>
前述の手順と同様に、このWSDLファイルは、新しいデプロイメントによって生成されたものであるため、モニター用のポート番号を更新する必要があります。このWSDLファイルの最後に近い部分に、次のような行があります。
<s2:address location="http://localhost:7001/HelloWorldService/HelloWorldService"/>
以下のように、この行のポート番号を7002に変更します。
<s2:address location="http://localhost:
7002/HelloWorldService/HelloWorldService"/>
WSDLファイルを保存してから終了します。次に、コマンド・シェルで、コマンド
ant -buildfile gen-client.xmlを実行します。
BUILD SUCCESSFULメッセージが表示されます。これで、クライアントのプロキシが更新されました。
WTPに戻り、
WSTestプロジェクトをリフレッシュします。
HelloWorldClientクラスを実行します。何が起こるでしょうか。
javax.xml.rpc.soap.SOAPFaultException: Unable to add security token for identity
ここでは、クライアントはサービスの呼出しを試行していますが、認可用の
資格証明は一切提供していません。そのため、前述の手順で作成したユーザー名とパスワード、
suzie/munchkinを使用してサービスの呼出しがおこなわれるように、クライアントのコードを変更する必要があります。この処理をおこなうため、まず以下のスクリプトで
ハイライトされているコードを、
HelloWorldClient.javaの
mainメソッドに追加します。
stub._setProperty(
WSSecurityContext.CREDENTIAL_PROVIDER_LIST,
credProviders);
String username = "suzie";
String password = "munchkin";
cp = new ClientUNTCredentialProvider(username.getBytes(),
password.getBytes());
credProviders.add(cp);
stub._setProperty(
コードを実行します。前回と同じあいさつのメッセージが返されます。これで、クライアントではサービスを呼び出す前に資格証明書が強制的に追加されたこと がわかります。モニターをチェックして、リクエストを確認します。以下のスクリプトのように、新しいセクションが表示されます。
<wsse:UsernameToken>
<wsse:Username>suzie</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/
oasis-200401-wss-username-token-profile-1.0#PasswordText">munchkin</wsse:Password>
</wsse:UsernameToken>
この新しいセクションが、追加された資格証明書です。これらの資格証明書は、プレーン・テキストの形式で送信さ れています。WS-Securityの仕様ではユーザー資格証明の暗号化については規定されていませんが、ここでは、転送レイヤーのセキュリティを使用す る(すなわち、TCP/IPソケット全体を保護する)ことをお勧めします。
これで、Webサービスへの認証の追加に成功しました。
このほど、WebLogic Server 10がリリースされました。このリリースは、既存のバージョンで保護をおこなったWebサービスに、どのような影響を及ぼすことになるのでしょうか。幸い なことに、それほど大きな影響はありません。サービスのデプロイと実行については、バージョン10でもまったく変更はありません。ただし、クライアントの コードについては、バージョン10のクライアントAPIを使用して再生成する必要があります。また、WebLogic Server 10ではWS-SecurityPolicy 1.2へのサポートが追加され、現在はWS-Security 1.1に対応しています(WebLogic Server 9.2では、WS-Security 1.0をサポート)。
WS-SecurityPolicy 1.2の仕様がサポートされたことで大きく変わる点は、BEA専用のセキュリティ・ポリシー・ファイルと対比したうえで、"標準化"されたセキュリティ・ ポリシー・ファイルを作成できるようになったことです。WebLogic Server 9.2は、WS-SecurityPolicyの仕様が公開されるよりも前にリリースされたため、セキュリティ・ポリシーにはBEA専用のスキーマを使用 し、旧バージョンのWS-Policy仕様に基づいて記述されたセキュリティ・ポリシー・ファイルを使用しています。
では、どのタイプのポリシー・ファイルを使用すればよいでしょうか。BEAでは、BEA専用のポリシー・ファイ ルの代わりとして、WS-SecurityPolicyの標準ポリシー・ファイルを使用することを推奨しています。バージョン10では両方のポリシー・ ファイルがサポートされていますが、この2つのポリシー・ファイルには互換性がないため、特定のWebサービス内では1つのタイプしか使用できません。
ただし、WebLogic Server 9.2のポリシー・ファイルを新しい標準ポリシー・ファイルに性急に移行してしまう前に、WS-SecurityPolicyには、いくつかの制限がある ことに注意してください。これは、BEAが導入したときには、WS-SecurityPolicyはまだドラフト段階であったためです(現在もドラフト段 階にあります)。とくに、要素レベルでのデジタル署名と暗号化(またはそのいずれか)が必要な場合、すなわちメッセージの本文全体に対してデジタル署名や 暗号化をおこないたくない場合や、SAML 1.1が必要な場合については、BEA WebLogic 9.2専用スタイルのポリシーを使用する必要があります。
WS-Securityについては、WebLogic Server 10ではWS-Security 1.1に対応していますが、相互運用性を確保するため、BEAではWS-Security 1.0を使用することを推奨しています。WS-Security 1.1ポリシーについては、より強力なセキュリティ要件が求められている場合にだけ使用するようにすることをお勧めします。また、WS-Security 1.1は、新しいWS-SecurityPolicy 1.2ポリシー・ファイルを使用している場合以外はサポートされていません。
この記事では、Webサービスのセキュリティ関する3つの側面、すなわちメッセージの整合性、メッセージの機密 保護、および認証について説明しました。ここで見てきたとおり、これらの有用な側面によって"セキュア"なWebサービスをコーディングすることは、それ ほど難しい作業ではなく、Webサービスのコードに適切なアノテーションをつけるだけですべてが完了します。各側面を実現するためにどのようなアノテー ションを使用すればよいかについても、記事のなかで取り上げました。また、保護されたサービスを呼び出すためにクライアント・コードを変更する方法や、 SOAPメッセージ自体を変更して新しく追加したセキュリティが反映されるようにする方法についても学習しました。さらにチュートリアルでは、実際に3つ の側面を段階的に追加し、最終的にすべての側面が組み込まれたWebサービスを構築しました。
SOAPメッセージは元々"プレーン・テキスト"のメッセージであるため、企業の本番環境の一部としてWeb サービスをデプロイする場合には、強力なセキュリティ機能を整備することが重要となります。WS-SecurityとWebLogic Serverとを組み合わせれば、この問題に対する優れた解決策となり、開発者は企業における安全なサービスのデプロイと管理を簡単に実現できるようにな ります。
Gary Ng:WebAge Solutionsのシニア・コンサルタント、2001年以降は各種J2EE プロジェクトに携わっている
Matt Silver:技術コンサルタント兼トレーナー、現在はWeb Age Solutionsのシニア・コンサルタントを務める