スタックされた JAAS ログイン・モジュールを使用した SAML トークンの生成および消費

GenericSecurityTokenFactory API を使用して、作成した SAML トークンを SAMLGenerateLoginModule または GenericIssuedTokenGenerateLoginModule モジュールに渡すことができます。この API を使用して、SAMLConsumeLoginModule または GenericIssuedTokenConsumeLoginModule モジュールで消費された SAML トークンを取得することもできます。

始める前に

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

このタスクについて

このタスクでは、SAML 1.1 bearer トークンを生成しますが、sender-vouches およびランタイム環境でサポートされる任意の SAML バージョンを使用するように簡単に変更できます。

SAMLGenerateLoginModule の下にログイン・モジュールをスタックして、当該クラスで作成された SAML トークンを検査できますが、トークンにデジタル署名が含まれていない場合を除いて、このようにして取得した SAML トークンを変更することはできません。デジタル署名が含まれている SAML トークンを変更した場合、その更新に合わせて SAML トークンの XML が調整されます。ただし、トークンは更新前に署名されているため、受信側で署名の検証は失敗します。

このタスクでは、SAML 1.1 bearer トークンを生成しますが、ランタイム環境でサポートされる任意の SAML バージョンおよびタイプを使用できます。GenericSecurityTokenFactory API を使用した SAML トークンの作成および変更について詳しくは、『SAML アプリケーションの開発』を参照してください。JAAS ログイン・モジュールを使用してトークンを作成するのではなく、クライアントの要求コンテキストにトークンを配置する方法について詳しくは、com.ibm.wsspi.wssecurity.core.Constants の com.ibm.wsspi.wssecurity.token.tokenHolder および com.ibm.wsspi.wssecurity.token.enableCaptureTokenContext 定数を参照してください。

holder-of-key を使用するように生成プログラムの例を簡単に変更できないため、SAML holder-of-key に固有の createSamlToken() メソッドの例を、このタスクの末尾に示します。

手順

  1. 以下の生成プログラム JAAS ログイン・モジュールを作成し、 アプリケーション・コードで使用できるようにします。
    package test.tokens;
    
    import java.util.ArrayList;
    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 com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
    import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
    import com.ibm.websphere.wssecurity.wssapi.token.SAMLTokenFactory;
    import com.ibm.wsspi.wssecurity.saml.config.CredentialConfig;
    import com.ibm.wsspi.wssecurity.saml.config.ProviderConfig;
    import com.ibm.wsspi.wssecurity.saml.config.RequesterConfig;
    import com.ibm.wsspi.wssecurity.saml.data.SAMLAttribute;
    import com.ibm.wsspi.wssecurity.core.config.KeyInformationConfig;
    import com.ibm.wsspi.wssecurity.core.config.KeyStoreConfig;
    import com.ibm.websphere.wssecurity.wssapi.WSSUtilFactory;
    
    public class MySamlGenerator 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");
        }
        SAMLToken myToken = null;
        try {
          myToken = createSamlToken();
        } 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 SAMLToken createSamlToken() throws Exception {
        //SAML Bearer example 
        SAMLTokenFactory samlFactory = SAMLTokenFactory.getInstance(SAMLTokenFactory.WssSamlV11Token11);    RequesterConfig reqData = samlFactory.newBearerTokenGenerateConfig();    reqData.setAuthenticationMethod("Password"); //Authentication method for Assertion
    
        ProviderConfig samlIssuerCfg = samlFactory.newDefaultProviderConfig("self-issue");
    
        CredentialConfig cred = samlFactory.newCredentialConfig ();    cred.setRequesterNameID("Alice");   // SAML NameIdentifier
    	  
        //Add some SAML attributes:	
        SAMLAttribute attribute = new SAMLAttribute
          ("email", new String[] {"joe@websphere"},null, "WebSphere", "email", "joe");
        ArrayList<SAMLAttribute> al = new ArrayList<SAMLAttribute>();
        al.add(attribute);
        attribute = new SAMLAttribute("Membership", 
          new String[] {"Super users", "My team"}, null, null, null, null  );
        al.add(attribute);
        cred.setSAMLAttributes(al);
        SAMLToken samlToken = samlFactory.newSAMLToken(cred, reqData, samlIssuerCfg);
        return samlToken;
      }
    
      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.security.auth.Subject;
    import javax.security.auth.callback.CallbackHandler;
    import javax.security.auth.login.LoginException;
    import javax.security.auth.spi.LoginModule;
    import javax.xml.namespace.QName;
    import com.ibm.websphere.wssecurity.wssapi.token.GenericSecurityTokenFactory;
    import com.ibm.websphere.wssecurity.wssapi.token.SAMLToken;
    import com.ibm.websphere.wssecurity.wssapi.token.SAMLTokenFactory;
    import com.ibm.websphere.wssecurity.wssapi.token.SecurityToken;
    
    public class MySamlConsumer 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");
        }
        //Get the token that was consumed by the GenericIssuedConsumeLoginModule
        SecurityToken myToken = factory.getConsumerTokenFromSharedState(_sharedState, new QName(SAMLTokenFactory.WssSamlV11Token11));
        if (myToken == null) {
            throw new LoginException("myToken is null");
        }
        if (myToken instanceof SAMLToken) {
        		//Examine the SAML token with SAML APIs
        		SAMLToken samlToken = (SAMLToken)myToken;
        		String id = samlToken.getSamlID();
        		String subjectDns = samlToken.getSubjectDNS();
        	//...    	
        } else {
        		throw new LoginException("Did not receive a SAML token");
        }
        return true;
      }
      public boolean logout() throws LoginException {
        return false;
      } 
      public boolean abort() throws LoginException {
        return false;
      }
      public boolean commit() throws LoginException {
        return true;
      }
    }
  3. JAAS ログイン構成を作成します。
    1. 管理コンソールで、「セキュリティー」 > 「グローバル・セキュリティー」に移動します。
    2. 「認証」で、「Java 認証・承認サービス」 > 「システム・ログイン」に移動します。
    3. SAML トークン生成プログラムを作成します。
      1. 「新規」をクリックし、「別名」で test.generate.saml と入力します。
      2. 「JAAS ログイン・モジュール」で「新規」をクリックし、「モジュール・クラス名」で test.tokens.MySamlGenerator と入力します。 「ログイン・モジュール・プロキシーを使用」を選択し、「OK」をクリックします。
      3. 「新規」をクリックし、「モジュール・クラス名」で com.ibm.ws.wssecurity.wssapi.token.impl.SAMLGenerateLoginModule と入力します。 「OK」をクリックします。
    4. SAML トークン・コンシューマーを作成します。
      1. パンくずリストで「JAAS - システム・ログイン」をクリックして、JAAS システム・ログイン・ページに戻ります。
      2. 「新規」をクリックし、「別名」で test.consume.saml と入力します。
      3. 「JAAS ログイン・モジュール」で「新規」をクリックし、「モジュール・クラス名」で com.ibm.ws.wssecurity.wssapi.token.impl.SAMLConsumeLoginModule と入力します。 「ログイン・モジュール・プロキシーを使用」を選択し、「OK」をクリックします。
      4. 保存」をクリックします。
  4. 新しい JAAS ログイン構成を使用するように SAML トークン生成プログラムを構成します。
    1. 管理コンソールで、変更するバインディング構成を開きます。
    2. 「WS-Security」 > 「認証および保護」を選択します。
    3. 認証トークンの下で、変更する SAML アウトバウンド・トークンを選択します。
    4. 「JAAS ログイン」で test.generate.saml を選択します。
  5. 新しい JAAS 構成を使用するように SAML トークン・コンシューマーを構成します。
    1. 管理コンソールで、変更するバインディング構成を開きます。
    2. 「WS-Security」 > 「認証および保護」を選択します。
    3. 認証トークンの下で、変更する SAML インバウンド・トークンを選択します。
    4. 「JAAS ログイン」で test.consume.saml を選択します。
  6. 保存」をクリックします。
  7. アプリケーション・サーバーを再始動して JAAS 構成の変更を適用します。
  8. サービスをテストします。

以下の例では、非対称 SAML 2.0 holder-of-key トークンを作成するための createSamlToken() メソッドを示します。
private SAMLToken createSamlToken() throws Exception {
  SAMLTokenFactory samlFactory =  SAMLTokenFactory.getInstance (SAMLTokenFactory.WssSamlV20Token11);

  RequesterConfig reqData =  samlFactory.newAsymmetricHolderOfKeyTokenGenerateConfig();
  reqData.setAuthenticationMethod("Password"); //Authentication method for Assertion

  ProviderConfig samlIssuerCfg = samlFactory.newDefaultProviderConfig("self-issue");

  CredentialConfig cred = samlFactory.newCredentialConfig ();  cred.setRequesterNameID("Alice");   // SAML NameIdentifier

  // (Optional) If you want to use keystore and key properties other than what 
  // is set in the SAMLIssuerConfig.properties file, reset the keystore, 
  // trust store and alias information in the ProviderConfig object.
  KeyInformationConfig kic = samlFactory.newKeyInformationConfig("private_key","keypass","CN=Private");

  KeyStoreConfig ksc = samlFactory.newKeyStoreConfig("jks","/keystores/myKeystore.ks","storepass");

  samlIssuerCfg.setKeyStoreConfig(ksc);    //keystore that holds the private key    
  samlIssuerCfg.setTrustStoreConfig(ksc);  //keystore that holds the public key

  // Set the alias for the public certificate that must exist in the trust store.
  // This alias must not require a password.
  reqData.setKeyAliasForRequester("public_cert");  

  SecurityToken samlToken = samlFactory.newSAMLToken(cred, reqData, samlIssuerCfg);     

  // Get the private key from the key store
  WSSUtilFactory wssufactory = WSSUtilFactory.getInstance();
  java.security.KeyStore ks = wssufactory.getKeyStore("jks","/keystores/myKeystore.ks",
                                                      "storepass".toCharArray());
  java.security.Key privateKey = ks.getKey("private_key", "keypass".toCharArray());

  // Add the private key to the token so that the token can be used to sign 
  // elements in a SOAP message. ((com.ibm.ws.wssecurity.wssapi.token.impl.SecurityTokenImpl)samlToken).
  setKey(SecurityToken.SIGNING_KEY, privateKey);  ((com.ibm.ws.wssecurity.wssapi.token.impl.SecurityTokenImpl)samlToken).
  setKey(SecurityToken.DECRYPTING_KEY, privateKey);

  return samlToken;
}

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



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