7.3. クライアント認証情報の指定

概要

UsernameToken クライアントクレデンシャルを提供する方法は、基本的に 2 つあります。クライアントの Blueprint XML 設定でユーザー名とパスワードの両方を直接設定する方法と、クライアントの設定でユーザー名を設定し、コールバックハンドラーを実装してプログラムでパスワードを提供する方法の 2 つです。後者のアプローチ (プログラミングによる) には、パスワードが見えないようにするのが簡単であるという利点があります。

クライアント資格情報のプロパティー

表7.1「クライアント資格情報のプロパティー」 は、BlueprintXML でクライアントの要求コンテキストに WS-Security ユーザー名/パスワード資格情報を指定するために使用できるプロパティーを示しています。

表7.1 クライアント資格情報のプロパティー

プロパティー説明

security.username

UsernameToken ポリシーアサーションのユーザー名を指定します。

security.password

UsernameToken ポリシーアサーションのパスワードを指定します。指定しない場合、パスワードはコールバックハンドラーを呼び出すことによって取得されます。

security.callback-handler

UsernameToken ポリシーアサーションのパスワードを取得する WSS4J コールバックハンドラーのクラス名を指定します。コールバックハンドラーは他の種類のセキュリティーイベントも処理できることに注意してください。

Blueprint XML でのクライアント資格情報の設定

Blueprint XML でクライアントの要求コンテキストでユーザー名/パスワードクレデンシャルを設定するには、以下のように security.username および security.password プロパティーを設定します。

<beans ... >
    <jaxws:client name="{NamespaceName}LocalPortName"
                  createdFromAPI="true">
        <jaxws:properties>
            <entry key="security.username" value="Alice"/>
            <entry key="security.password" value="abcd!1234"/>
        </jaxws:properties>
    </jaxws:client>
    ...
</beans>

パスワードを Blueprint XML に直接保存したくない場合 (セキュリティー上の問題が発生する可能性があります)、代わりにコールバックハンドラーを使用してパスワードを提供できます。

パスワードのコールバックハンドラーのプログラミング

コールバックハンドラーを使用して UsernameToken ヘッダーのパスワードを提供する場合は、最初に Blueprint XML でクライアント設定を変更し、以下のように security.password 設定を security.callback-handler 設定に置き換える必要があります。

<beans ... >
    <jaxws:client name="{NamespaceName}LocalPortName"
                  createdFromAPI="true">
        <jaxws:properties>
            <entry key="security.username" value="Alice"/>
            <entry key="security.callback-handler" value="interop.client.UTPasswordCallback"/>
        </jaxws:properties>
    </jaxws:client>
    ...
</beans>

上記の例では、コールバックハンドラーは UTPasswordCallback クラスによって実装されます。例7.2「UsernameToken パスワードのコールバックハンドラー」 に示されるように、javax.security.auth.callback.CallbackHandler インターフェイスを実装してコールバックハンドラーを作成できます。

例7.2 UsernameToken パスワードのコールバックハンドラー

package interop.client;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.ws.security.WSPasswordCallback;

public class UTPasswordCallback implements CallbackHandler {

    private Map<String, String> passwords =
        new HashMap<String, String>();

    public UTPasswordCallback() {
        passwords.put("Alice", "ecilA");
        passwords.put("Frank", "invalid-password");
        //for MS clients
        passwords.put("abcd", "dcba");
    }

    public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
        for (int i = 0; i < callbacks.length; i++) {
            WSPasswordCallback pc = (WSPasswordCallback)callbacks[i];

            String pass = passwords.get(pc.getIdentifier());
            if (pass != null) {
                pc.setPassword(pass);
                return;
            }
        }

        throw new IOException();
    }

    // Add an alias/password pair to the callback mechanism.
    public void setAliasPassword(String alias, String password) {
        passwords.put(alias, password);
    }
}

コールバック機能は CallbackHandler.handle() メソッドによって実装されます。この例では、handle() メソッドに渡されるコールバックオブジェクトはすべて、org.apache.ws.security.WSPasswordCallback タイプであることが想定されます (より現実的な例では、コールバックオブジェクトのタイプを確認してください)。

クライアントコールバックハンドラーのより現実的な実装は、おそらくユーザーにパスワードの入力を求めることで設定されます。

WSPasswordCallback クラス

UsernameToken パスワードを設定する目的で Apache CXF クライアントで CallbackHandler が呼び出されると、対応する WSPasswordCallback オブジェクトに USERNAME_TOKEN 使用コードが含まれます。

WSPasswordCallback クラスの詳細は org.apache.ws.security.WSPasswordCallback を参照してください。

WSPasswordCallback クラスは以下のように、異なる使用コードを複数定義します。

USERNAME_TOKEN

UsernameToken 資格情報のパスワードを取得します。この使用法コードは、クライアント側 (サーバーに送信するパスワードを取得するため) とサーバー側 (クライアントから受信したパスワードと比較するためにパスワードを取得するため) の両方で使用されます。

サーバー側では、このコードは次の場合に設定されます。

  • ダイジェストパスワード: UsernameToken にダイジェストパスワードが含まれる場合、コールバックは (WSPasswordCallback.getIdentifier() が提供する) 指定されたユーザー名に対応するパスワードを返す必要があります。パスワードの検証 (ダイジェストパスワードとの比較による) は、WSS4J ランタイムによって行われます。
  • プレーンテキストパスワード ダイジェストパスワードの場合と同じ方法で実装されます (Apache CXF 2.4.0 以降)。
  • Custom password typeorg.apache.ws.security.WSSConfiggetHandleCustomPasswordTypes()true に設定されている場合は、(Apache CXF 2.4.0 以降) ダイジェストパスワードの場合と同じように実装されています。そうでない場合は、例外が発生します。

    サーバー側で受信した UsernameToken に Password 要素が含まれていない場合、コールバックハンドラーは呼び出されませ (Apache CXF 2.4.0 以降)。

DECRYPT
Java キーストアから秘密鍵を取得するためにパスワードが必要です。WSPasswordCallback.getIdentifier() は、キーストアエントリーのエイリアスを提供します。WSS4J は、この秘密鍵を使用して、セッション (対称) 鍵を復号化します。
署名
Java キーストアから秘密鍵を取得するためにパスワードが必要です。WSPasswordCallback.getIdentifier() は、キーストアエントリーのエイリアスを提供します。WSS4J はこの秘密鍵を使用して署名を生成します。
SECRET_KEY
アウトバウンド側での暗号化または署名、またはインバウンド側での復号化または検証のための秘密鍵が必要です。コールバックハンドラーは、setKey(byte[]) メソッドを使用してキーを設定する必要があります。
SECURITY_CONTEXT_TOKEN
setKey(byte[]) メソッドを呼び出して指定する wsc:SecurityContextToken のキーが必要です。
CUSTOM_TOKEN
トークンを DOM 要素として必要とします。たとえば、これは、メッセージに含まれていない SAML アサーションまたは SecurityContextToken への参照の場合に使用されます。コールバックハンドラーは、setCustomToken(Element) メソッドを使用してトークンを設定する必要があります。
KEY_NAME
(廃止) Apache CXF 2.4.0 以降、この使用法コードは廃止されました。
USERNAME_TOKEN_UNKNOWN
(廃止) Apache CXF 2.4.0 以降、この使用法コードは廃止されました。
UNKNOWN
WSS4J が使用していない。