[Fix Pack 27 or later]


Generating and consuming SAML tokens using stacked JAAS login modules

You can use the GenericSecurityTokenFactory APIs to pass a SAML token that you have created to the SAMLGenerateLoginModule or GenericIssuedTokenGenerateLoginModule modules. You can also use these APIs to obtain SAML tokens that are consumed by SAMLConsumeLoginModule or GenericIssuedTokenConsumeLoginModule modules.

Before you begin

You must have a functioning set of JAX-WS service client and provider applications to which you can add new JAAS login module classes.

About this task

This task generates a SAML 1.1 bearer token, but you can use any SAML version and type that is supported by the runtime environment. For more information about creating and modifying SAML tokens with the GenericSecurityTokenFactory APIs, see Developing SAML applications. For more information about how to place the token on the client's request context instead of using a JAAS login module, see the com.ibm.wsspi.wssecurity.token.tokenHolder and com.ibm.wsspi.wssecurity.token.enableCaptureTokenContext constants in com.ibm.wsspi.wssecurity.core.Constants.

Procedure

  1. Create the following generator JAAS login module and make it available to your application code.
    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;
    
    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. Create the following consumer JAAS login module and make it available to your application code.
    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. Create a JAAS login configuration.
    1. In the administrative console, go to Security > Global security .
    2. Under Authentication, go to Java Authentication and Authorization Service > System logins.
    3. Create the SAML token generator.
      1. Click New, and under Alias, enter test.generate.saml.
      2. Under JAAS login modules, click New, and under Module class name, enter test.tokens.MySamlGenerator. Select Use login module proxy, and click OK.
      3. Click New, and under Module class name, enter com.ibm.ws.wssecurity.wssapi.token.impl.SAMLGenerateLoginModule. Click OK.
    4. Create the SAML token consumer.
      1. Click JAAS - System logins in the breadcrumbs at the top of the page to return to the JAAS system logins page.
      2. Click New, and under Alias, enter test.consume.saml.
      3. Under JAAS login modules, click New, and under Module class name, enter com.ibm.ws.wssecurity.wssapi.token.impl.SAMLConsumeLoginModule. Select Use login module proxy, and click OK.
      4. Click Save.
  4. Configure the SAML token generator to use the new JAAS login configuration.
    1. In the administrative console, open the bindings configuration that you want to change.
    2. Select WS-Security > Authentication and protection.
    3. Under Authentication tokens, select the SAML outbound token that you want to change.
    4. Under JAAS login, select test.generate.saml.
  5. Configure the SAML token consumer to use the new JAAS configuration.
    1. In the administrative console, open the bindings configuration that you want to change.
    2. Select WS-Security > Authentication and protection.
    3. Under Authentication tokens, select the SAML inbound token that you want to change.
    4. Under JAAS login, select test.consume.saml.
  6. Click Save.
  7. Restart the application server to apply the JAAS configuration changes.
  8. Test the service.



In this information ...


IBM Redbooks, demos, education, and more

(Index)

Use IBM Suggests to retrieve related content from ibm.com and beyond, identified for your convenience.

This feature requires Internet access.

Task topic Task topic    

Terms and conditions for information centers | Feedback

Last updatedLast updated: Jun 11, 2013 8:40:09 AM CDT
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=v701sca&product=was-nd-mp&topic=twbs_gen_con_token_JAAS_mod
File name: twbs_gen_con_token_JAAS_mod.html