汎用発行ログイン・モジュールでのカスタム・トークンの生成および使用
汎用発行トークンのジェネレーターとコンシューマーである GenericIssuedTokenGenerateLoginModule と GenericIssuedTokenConsumeLoginModule は、 GenericSecurityTokenFactory SPI および GenericSecurityToken SPI とともに使用して、 カスタム・トークンのエンドツーエンド・ソリューションを実装できます。汎用発行ログイン・モジュールでの カスタム・トークンの生成および使用は、ポリシーとバインディング、または WSSAPI によって 実行できます。
始める前に
新規 JAAS ログイン・モジュール・クラスを追加できる JAX-WS サービス・クライアントとプロバイダー・アプリケーションの機能セットが必要です。
このタスクについて
JAX-WS サービス・クライアントとプロバイダー・アプリケーションのセットがカスタム・トークンを使用できるようにするには、以下のステップを実行します。 手順中の MyToken は、作成されるトークンの名前です。
このタスクを完了すると、以下のようになります。
- 2 つの JAAS ログイン・モジュールが作成されます。1 つはトークンの生成用、もう 1 つは トークンの消費用です。
- トークンは、汎用発行トークン生成プログラムおよびコンシューマーを使用して生成および使用されます。
- 次に、ポリシー・セットとバインディングによってセキュリティー制約がアプリケーションに適用されます。
手順
- 以下の生成プログラム JAAS ログイン・モジュールを作成し、
アプリケーション・コードで使用できるようにします。
package test.tokens; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; import javax.xml.soap.SOAPFactory; import javax.xml.soap.SOAPElement; import javax.xml.namespace.QName; import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory; import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken; public class MyCustomGenerator implements LoginModule { private Map _sharedState; private Map _options; private CallbackHandler _handler; public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { this._handler = callbackHandler; this._sharedState = sharedState; this._options = options; } public boolean login() throws LoginException { GenericSecurityTokenFactory factory = null; try { factory = GenericSecurityTokenFactory.getInstance(); } catch (Exception e) { throw new LoginException(e.toString()); } if (factory == null) { throw new LoginException("GenericSecurityTokenFactory.getInstance() returned null"); } SecurityToken myToken = null; try { SOAPElement tokenElement = createCustomElement(factory); myToken = factory.getToken(tokenElement, new QName("http://www.acme.com","MyToken")); } catch (Exception e) { throw new LoginException(e.toString()); } if (myToken == null) { throw new LoginException("myToken is null"); } //Put the token in a list on the shared state where it will be available to be used by //stacked login modules factory.putGeneratorTokenToSharedState(_sharedState, myToken); return true; } private SOAPElement createCustomElement(GenericSecurityTokenFactory gstFactory) throws Exception { /* <acme:MyToken xmlns:acme="http://www.acme.com" xmlns:utl="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" utl:Id="cust_3"> <acme:EMail>joe.smith@acme.com</acme:EMail> </acme:MyToken> */ SOAPFactory factory = SOAPFactory.newInstance(); //Create the MyToken element SOAPElement tokElement = factory.createElement("MyToken", "acme", "http://www.acme.com"); //Add the Id attribute tokElement.addAttribute(new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "Id", "utl"), gstFactory.createUniqueId()); //Create the Email element SOAPElement emailElement = factory.createElement("Email", "acme", "http://www.acme.com"); emailElement.addTextNode("joe.smith@acme.com"); //Add the EMail element to the MyToken tokElement.addChildElement(emailElement); return tokElement; } public boolean logout() throws LoginException { return false; } public boolean abort() throws LoginException { return false; } public boolean commit() throws LoginException { return true; } }
- 以下のコンシューマー JAAS ログイン・モジュールを作成し、
アプリケーション・コードで使用できるようにします。
package test.tokens; import java.util.Map; import javax.xml.namespace.QName; import org.apache.axiom.om.OMElement; import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; import com.ibm.websphere.wssecurity.callbackhandler.PropertyCallback; import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory; import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken; import com.ibm.wsspi.wssecurity.wssapi.OMStructure; public class MyCustomConsumer implements LoginModule { private CallbackHandler _handler; private Map _sharedState; public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) { this._handler = callbackHandler; this._sharedState = sharedState; } public boolean login() throws LoginException { PropertyCallback propertyCallback = new PropertyCallback(null); Callback[] callbacks = new Callback[] { propertyCallback}; try { this._handler.handle(callbacks); } catch (Exception e) { throw new LoginException(e.toString()); } //Get the GenericSecurityTokenFactory GenericSecurityTokenFactory factory = null; try { factory = GenericSecurityTokenFactory.getInstance(); } catch (Exception e) { throw new LoginException(e.toString()); } if (factory == null) { throw new LoginException("GenericSecurityTokenFactory.getInstance() returned null"); } //Get the token that was consumed by the GenericIssuedConsumeLoginModule SecurityToken myToken = factory.getConsumerTokenFromSharedState(_sharedState, new QName("http://www.acme.com","MyToken")); if (myToken == null) { throw new LoginException("no token"); } //Get the token's element Object obj = myToken.getXML(); if (obj == null) { throw new LoginException("token is empty"); } if (!(obj instanceof OMStructure)) { throw new LoginException("XML is not OMStructure"); } OMElement tokenElement = ((OMStructure)obj).getNode(); //you can use the org.apache.axis2.util.XMLUtils.toDOM method //if you want to work with the a w3c.dom element instead of an //Axiom element //Do some processing on the contents of the token element OMElement el = tokenElement.getFirstChildWithName(new QName("http://www.acme.com","Email")); if (el == null) { throw new LoginException("no email element"); } String value = el.getText(); if (value != null && value.equals("joe.smith@acme.com")) { return true; } else { throw new LoginException("email value is bad"); } } public boolean commit() throws LoginException { return true; } public boolean logout() throws LoginException { return false; } public boolean abort() throws LoginException { return false; } }
- 新しい JAAS ログイン構成を作成します。
- 管理コンソールで、「セキュリティー」->「グローバル・セキュリティー」を選択します。
- 「認証」の下で、「Java 認証・承認サービス」を選択します。
- 「システム・ログイン」を選択します。
- 最初に、カスタム・モジュールを使用してジェネレーターを作成します。
- 「新規」をクリックし、Alias = test.generate.customと指定します。
- 「新規」をクリックし、Module class name = test.tokens.MyCustomGeneratorと指定します。
- 「ログイン・モジュール・プロキシーを使用」を選択します。
- 「OK」をクリックします。
- 「新規」をクリックし、 Module class name = com.ibm.ws.wssecurity.wssapi.token.impl.GenericIssuedTokenGenerateLoginModuleと選択します。
- 「OK」をクリックします。
- 「JAAS - システム・ログイン」をクリックします。
- 最後に、カスタム・モジュールを使用してコンシューマーを作成します。
- 「新規」をクリックし、Alias = test.consume.customを指定します。
- 「新規」をクリックし、 Module class name = com.ibm.ws.wssecurity.wssapi.token.impl.GenericIssuedTokenConsumeLoginModuleを選択します。
- 「新規」をクリックし、 Module class name = test.tokens.MyCustomConsumerと指定します。
- 「ログイン・モジュール・プロキシーを設定」を選択します。
- 「OK」をクリックします。
- 「保存」をクリックします。
- カスタム・ポリシー・セットを作成します。
- 管理コンソールで、「サービス」>「ポリシー・セット」>「アプリケーション・ポリシー・セット」とクリックします。
- 「新規」をクリックし、ACustomTokenPolicyと指定します。
- 「適用」をクリックします。
- 「ポリシー」の下で、「追加」>「WS-Security」とクリックします。
- カスタム・ポリシー・セットを編集します。
- 管理コンソールで、「WS-Security」>「メイン・ポリシー」とクリックします。
- 以下のようにして、不要なエレメントを除去します。
- 「セキュリティー・ヘッダー内にタイム・スタンプを組み込みます」を選択解除します。
- 「メッセージ・レベル保護」を選択解除します。
- カスタム・トークンを追加します。
- 「要求トークン・ポリシー」をクリック します。
- 「トークン・タイプの追加」>「カスタム」とクリックし、以下を指定します。
- Custom token name = myToken
- Local part = MyToken
- Namespace URI = http://www.acme.com
- 「OK」をクリックします。
- 「保存」をクリックします。
- ACustomTokenPolicy ポリシー・セットを使用するようにクライアントを構成します。
- 管理コンソールで、「サービス」 >「サービス・クライアント」とクリックします。
- 目的のサービス・クライアントをクリックします。
- トップレベルのリソースを選択します。
- 「ポリシー・セットの関連付け」をクリックします。
- 「ACustomTokenPolicy」を選択します。
- クライアントのカスタム・バインディングを作成します。
- 再び、トップレベルのリソースを選択します。
- 「バインディングの割り当て」を選択します。
- 「新規のアプリケーション固有バインディング (New Application Specific Binding)」 をクリックして、アプリケーション固有のバインディングを作成します。
- バインディング構成の名前を指定します。
name: customTokenClientBinding
- 「追加」>「WS-Security」をクリックします。
「メイン・メッセージ・セキュリティー・ポリシーのバインディング」パネルが表示されない場合は、「WS-Security」を選択します。
- クライアントのカスタム・バインディングを構成します。
- 「認証と保護」>「request:myToken」とクリックします。
- 「JAAS login = test.generate.custom」を選択します。
- 「適用」をクリックします。
- 「コールバック・ハンドラー」をクリックします。
- passThroughToken=true カスタム・プロパティーを 追加します。
- ACustomTokenPolicy ポリシー・セットを使用するようにプロバイダーを構成します。
- 管理コンソールで、「サービス」 >「サービス・プロバイダー」とクリックします。
- 目的のサービス・プロバイダーをクリックします。
- トップレベルのリソースを選択します。
- 「ポリシー・セットの関連付け」をクリックします。
- 「ACustomTok enPolicy」を選択します。
- プロバイダーのカスタム・バインディングを作成します。
- 再び、トップレベルのリソースを選択します。
- 「バインディングの割り当て」を選択します。
- 「新規のアプリケーション固有バインディング (New Application Specific Binding)」 をクリックして、アプリケーション固有のバインディングを作成します。
- バインディング構成の名前を指定します。
customTokenProviderBinding
- 「追加」>「WS-Security」をクリックします。
「メイン・メッセージ・セキュリティー・ポリシーのバインディング」パネルが表示されない場合は、「WS-Security」を選択します。
- プロバイダーのカスタム・バインディングを構成します。
- 「認証と保護」>「request:myToken」とクリックします。
- 「JAAS login = test.consume.custom」を選択します。
- 「適用」をクリックします。
- 「コールバック・ハンドラー」をクリックします。
- カスタム・プロパティーのpassThroughToken=true と alwaysGeneric=true を追加します。
- 「保存」をクリックして、構成変更を保存します。
- アプリケーション・サーバーを再始動して JAAS 構成の変更を適用します。
- サービスをテストします。
例
上記の手順に従うことで作成される SOAP セキュリティー・ヘッダーを以下の例に示します。
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" soapenv:mustUnderstand="1">
<acme:MyToken xmlns:acme="http://www.acme.com" xmlns:utl="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" utl:Id="cust_3">
<acme:Email>joe.smith@acme.com</acme:Email>
</acme:MyToken>
</wsse:Security>


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_gen_consum_custtokens
ファイル名:twbs_gen_consum_custtokens.html