Generating a pluggable token

The Web services security run time uses the JAAS CallbackHandler interface as a plugin to generate security tokens on the client side or when a Web service is acting as client. This topic describes how to write a Java Authentication and Authorization Server (JAAS) javax.security.auth.callback.CallbackHandler to generate a binary security token (<wsse:BinarySecurityToken>) and an XML-based token.

See Configure a pluggable token for information about configuring the pluggable token authentication for a request receiver.

Standard Java Authentication and Authorization Service CallbackHandler

WebSphere Application Server - Express provides a default implementation of the following JAAS callback handlers that you can use:

Developing a Java Authentication and Authorization Service callback handler

Because tokens are pluggable, you can also provide your own callback handler implementation.

Perform the following steps to develop your own JAAS callback handler:

  1. Implement the javax.security.auth.callback.CallbackHandler interface. The implementation must provide a default constructor with the following method signature:

    MyCallbackHandler(String userid, char[] password, java.util.Map properties)

    where userid and password is the basic authentication data, and properties are the authentication properties that are defined in the login binding.

  2. For the BasicAuth authentication method, the handler() method must handle the following javax.security.auth.callback.Callback implementation classes:

  3. For pluggable security token (other authentication methods), the handler() method must handle the following javax.security.auth.callback.Callback implementation classes:

    Note: If both the binary security token and XML-based token callback handlers are set, the binary security token takes precedence over the XML-based token. A binary security token is generated.

Sample implementation for BasicAuth authentication method

The following code is a sample callback handler implementation for generating the <wsse:UsernameToken> element. The error handling has been removed for clarity.

public class MyBACallbackHandler implements CallbackHandler {
  public MyBACallbackHandler() {
    super();
  }

  public MyBACallbackHandler(String userid, char[] password, Map properties) { 
    super();
    tmpusername = userid;
    tmppassword = password;
    tmpMap = properties;
  }


  /**
   * This implementation of MyBACallbackHandler map the username and
   * password data defined in the Login binding to another user.
   */
  public void handle(Callback[] callbacks)
    throws IOException, UnsupportedCallbackException {
      
    if ((callbacks == null) || (callbacks.length == 0)) {
      return;
    }
      
    // call out to some server to perform mapping of
    // tmpusername and tmppassword to a mappeduser
    // and mappedpassword
    Result result = mapUser(tmpusername, tmppassword, tmpMap); 
    String mappeduser = result.getMappedUser();
    char[] mappedpassword = result.getMappedPassword();

    for (int i = 0; i < callbacks.length; i++) {
      callback c = callbacks[i];
        
      if (c instanceof javax.security.auth.callback.namecallback) {
        ((javax.security.auth.callback.namecallback) c).setname(mappeduser);
      } else if (c instanceof javax.security.auth.callback.passwordcallback) {
        ((javax.security.auth.callback.passwordcallback) c).setpassword(
          (mappedpassword == null) ? new char[0] : mappedpassword);
      } else {
        throw new unsupportedcallbackexception(c, "Unsupported callback");
      }
    }
  }
    
  private string tmpusername = "";
  private char[] tmppassword = null;
  private map tmpmap = null;
}

The following sample code is a sample callback handler implementation for generating <wsse:BinarySecurityToken> element.

public class MyBSTCallbackHandler implements CallbackHandler {
  public MyBSTCallbackHandler() {
    super();
  }

  public MyBSTCallbackHandler(String userid, char[] password, Map properties) { 
    super();
    tmpusername = userid;
    tmppassword = password;
    tmpMap = properties;
  }


  /**
   * This implementation of MyBSTCallbackHandler generates binary
   * security token based on the username and password data defined in the
   * Login binding to another user.
   */
  public void handle(Callback[] callbacks)
    throws IOException, UnsupportedCallbackException {
      
    if ((callbacks == null) || (callbacks.length == 0)) {
      return;
    }
      
    // call out to create binary security token
    // based on tmpusername and tmppassword
    byte[] token = login(tmpusername, tmppassword);

    for (int i = 0; i < callbacks.length; i++) {
      callback c = callbacks[i];
        
      if (c instanceof com.ibm.wsspi.wssecurity.auth.callback.binarytokencallback) {
        ((com.ibm.wsspi.wssecurity.auth.callback.binarytokencallback) c).setcredtoken(token);
      } else if (c instanceof com.ibm.wsspi.wssecurity.auth.callback.xmltokensendercallback) {
        continue;
      } else {
        throw new unsupportedcallbackexception(c, "Unsupported callback");
      }
    }
  }
    
  private string tmpusername = "";
  private char[] tmppassword = null;
  private map tmpmap = null;
}