汎用発行ログイン・モジュールでのカスタム・トークンの生成および使用

汎用発行トークンのジェネレーターとコンシューマーである GenericIssuedTokenGenerateLoginModule と GenericIssuedTokenConsumeLoginModule は、 GenericSecurityTokenFactory SPI および GenericSecurityToken SPI とともに使用して、 カスタム・トークンのエンドツーエンド・ソリューションを実装できます。汎用発行ログイン・モジュールでの カスタム・トークンの生成および使用は、ポリシーとバインディング、または WSSAPI によって 実行できます。

始める前に

新規 JAAS ログイン・モジュール・クラスを追加できる JAX-WS サービス・クライアントとプロバイダー・アプリケーションの機能セットが必要です。

このタスクについて

JAX-WS サービス・クライアントとプロバイダー・アプリケーションのセットがカスタム・トークンを使用できるようにするには、以下のステップを実行します。 手順中の MyToken は、作成されるトークンの名前です。

このタスクを完了すると、以下のようになります。
  1. 2 つの JAAS ログイン・モジュールが作成されます。1 つはトークンの生成用、もう 1 つは トークンの消費用です。
  2. トークンは、汎用発行トークン生成プログラムおよびコンシューマーを使用して生成および使用されます。
  3. 次に、ポリシー・セットとバインディングによってセキュリティー制約がアプリケーションに適用されます。

手順

  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;
      }
    }
  2. 以下のコンシューマー 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;
      }
    
    }
  3. 新しい JAAS ログイン構成を作成します。
    1. 管理コンソールで、「セキュリティー」->「グローバル・セキュリティー」を選択します。
    2. 「認証」の下で、「Java 認証・承認サービス」を選択します。
    3. 「システム・ログイン」を選択します。
    4. 最初に、カスタム・モジュールを使用してジェネレーターを作成します。
      1. 「新規」をクリックし、Alias = test.generate.customと指定します。
      2. 「新規」をクリックし、Module class name = test.tokens.MyCustomGeneratorと指定します。
      3. 「ログイン・モジュール・プロキシーを使用」を選択します。
      4. 「OK」をクリックします。
      5. 「新規」をクリックし、 Module class name = com.ibm.ws.wssecurity.wssapi.token.impl.GenericIssuedTokenGenerateLoginModuleと選択します。
      6. 「OK」をクリックします。
      7. JAAS - システム・ログイン」をクリックします。
    5. 最後に、カスタム・モジュールを使用してコンシューマーを作成します。
      1. 「新規」をクリックし、Alias = test.consume.customを指定します。
      2. 「新規」をクリックし、 Module class name = com.ibm.ws.wssecurity.wssapi.token.impl.GenericIssuedTokenConsumeLoginModuleを選択します。
      3. 「新規」をクリックし、 Module class name = test.tokens.MyCustomConsumerと指定します。
      4. 「ログイン・モジュール・プロキシーを設定」を選択します。
      5. OK」をクリックします。
    6. 保存」をクリックします。
  4. カスタム・ポリシー・セットを作成します。
    1. 管理コンソールで、「サービス」>「ポリシー・セット」>「アプリケーション・ポリシー・セット」とクリックします。
    2. 「新規」をクリックし、ACustomTokenPolicyと指定します。
    3. 適用」をクリックします。
    4. 「ポリシー」の下で、「追加」>「WS-Security」とクリックします。
  5. カスタム・ポリシー・セットを編集します。
    1. 管理コンソールで、「WS-Security」>「メイン・ポリシー」とクリックします。
    2. 以下のようにして、不要なエレメントを除去します。
      1. 「セキュリティー・ヘッダー内にタイム・スタンプを組み込みます」を選択解除します。
      2. 「メッセージ・レベル保護」を選択解除します。
    3. カスタム・トークンを追加します。
      1. 要求トークン・ポリシー」をクリック します。
      2. 「トークン・タイプの追加」>「カスタム」とクリックし、以下を指定します。
        • Custom token name = myToken
        • Local part = MyToken
        • Namespace URI = http://www.acme.com
      3. 「OK」をクリックします。
    4. 保存」をクリックします。
  6. ACustomTokenPolicy ポリシー・セットを使用するようにクライアントを構成します。
    1. 管理コンソールで、「サービス」 >「サービス・クライアント」とクリックします。
    2. 目的のサービス・クライアントをクリックします。
    3. トップレベルのリソースを選択します。
    4. 「ポリシー・セットの関連付け」をクリックします。
    5. 「ACustomTokenPolicy」を選択します。
  7. クライアントのカスタム・バインディングを作成します。
    1. 再び、トップレベルのリソースを選択します。
    2. 「バインディングの割り当て」を選択します。
    3. 新規のアプリケーション固有バインディング (New Application Specific Binding)」 をクリックして、アプリケーション固有のバインディングを作成します。
    4. バインディング構成の名前を指定します。

      name: customTokenClientBinding

    5. 「追加」>「WS-Security」をクリックします。

      「メイン・メッセージ・セキュリティー・ポリシーのバインディング」パネルが表示されない場合は、「WS-Security」を選択します。

  8. クライアントのカスタム・バインディングを構成します。
    1. 「認証と保護」>「request:myToken」とクリックします。
    2. 「JAAS login = test.generate.custom」を選択します。
    3. 適用」をクリックします。
    4. コールバック・ハンドラー」をクリックします。
    5. passThroughToken=true カスタム・プロパティーを 追加します。
  9. ACustomTokenPolicy ポリシー・セットを使用するようにプロバイダーを構成します。
    1. 管理コンソールで、「サービス」 >「サービス・プロバイダー」とクリックします。
    2. 目的のサービス・プロバイダーをクリックします。
    3. トップレベルのリソースを選択します。
    4. 「ポリシー・セットの関連付け」をクリックします。
    5. 「ACustomTok enPolicy」を選択します。
  10. プロバイダーのカスタム・バインディングを作成します。
    1. 再び、トップレベルのリソースを選択します。
    2. 「バインディングの割り当て」を選択します。
    3. 新規のアプリケーション固有バインディング (New Application Specific Binding)」 をクリックして、アプリケーション固有のバインディングを作成します。
    4. バインディング構成の名前を指定します。

      customTokenProviderBinding

    5. 「追加」>「WS-Security」をクリックします。

      「メイン・メッセージ・セキュリティー・ポリシーのバインディング」パネルが表示されない場合は、「WS-Security」を選択します。

  11. プロバイダーのカスタム・バインディングを構成します。
    1. 「認証と保護」>「request:myToken」とクリックします。
    2. 「JAAS login = test.consume.custom」を選択します。
    3. 適用」をクリックします。
    4. コールバック・ハンドラー」をクリックします。
    5. カスタム・プロパティーのpassThroughToken=truealwaysGeneric=true を追加します。
  12. 保存」をクリックして、構成変更を保存します。
  13. アプリケーション・サーバーを再始動して JAAS 構成の変更を適用します。
  14. サービスをテストします。

上記の手順に従うことで作成される 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>

トピックのタイプを示すアイコン タスク・トピック



タイム・スタンプ・アイコン 最終更新: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_gen_consum_custtokens
ファイル名:twbs_gen_consum_custtokens.html