Menu Close

7.3. クライアントクレデンシャルの提供

概要

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

クライアントクレデンシャルのプロパティー

表7.1「クライアントクレデンシャルのプロパティー」 は、Blueprint XML でクライアントの要求コンテキストに 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 パスワードを設定する目的で CallbackHandler が Apache CXF クライアントで呼び出されると、対応する WSPasswordCallback オブジェクトには USERNAME_TOKEN 使用コードがあります。

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

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

USERNAME_TOKEN

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

サーバー側で、このコードは以下のケースで設定されます。

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

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

DECRYPT
Java キーストアから秘密鍵を取得するためにパスワードが必要です。WSPasswordCallback.getIdentifier() は、キーストアエントリーのエイリアスを提供します。WSS4J はこの秘密鍵を使用して、セッション (対称) キーを復号化します。
SIGNATURE
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 では使用されません。