Developing a custom trust association interceptor

You can develop a class that facilitates the integration of WebSphere® Application Server security and third-party security servers by using the com.ibm.wsspi.security.tai.TrustAssociationInterceptor interface.

Before you begin

You can find the com.ibm.wsspi.security.tai.TrustAssociationInterceptor interface in the (wasHome)/dev/was_public.jar file and the javax.* interfaces in the (wasHome)/dev/javax.j2ee.servlet.jar file. Make sure that these JAR files are available when you compile your custom interceptor.

Procedure

  1. Define the interceptor class methods.
    WebSphere Application Server provides the com.ibm.wsspi.security.tai.TrustAssociationInterceptor interceptor Java™ interface, which defines the following methods:
    • public boolean isTargetInterceptor(HttpServletRequest req) creates WebTrustAssociationException;.

      The isTargetInterceptor method of the trust association interceptor is called with HttpServletRequest as a parameter. The trust association interceptor inspects to see whether it can process the request, based on information in the HttpServletRequest parameter and other custom configuration information that the TAI might have. Return true from this method if the interceptor can process the request, otherwise, return false.

    • public void negotiateValidateandEstablishedTrust (HttpServletRequest req) creates WebTrustAssociationException;.

      This method is used to determine whether trust association can be established between WebSphere Application Server and the third-party security service. In most situations, trust association depends on authenticating the server. All the information to authenticate the server must be available in the HTTP request or the trust association interceptor (TAI) configuration.

    • public String initialize(Properties props) creates WebTrustAssociationException;.
      The initialize method is called to initialize the trust association interceptor. This method must be implemented by all the trust association interceptor implementations when properties are defined in the TAI configuration.
      Avoid Trouble: When a TAI is configured on an application server or cell that has multiple security domains, the TAI initialize(Properties props) method is invoked more than once: one time for the global domain and once for each of the additional security domains. Keep this detail in mind when you implement your TAI.
    • getVersion()

      This method returns the version of the trust association implementation.

    • getType()

      This method returns the trust association interceptor type.

    • cleanup()

      This method is called during stopping the WebSphere Application Server process and provides an opportunity for trust association interceptor to do any necessary cleanup. If no cleanup is needed, this method can be no operation (NOP).

    For more information, see the Javadoc information for com.ibm.wsspi.security.tai.TrustAssociationInterceptor.

    The following example shows a custom interceptor implementation.
    import java.util.Collections;
    import java.util.Enumeration;
    import java.util.Properties;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.ibm.websphere.security.WebTrustAssociationException;
    import com.ibm.websphere.security.WebTrustAssociationFailedException;
    import com.ibm.wsspi.security.tai.TAIResult;
    import com.ibm.wsspi.security.tai.TrustAssociationInterceptor;
    
    // This custom TAI intercepts any inbound HTTP request that
    // includes a custom header.  The default for the custom header name is 
    // CUSTOM_HEADER.  The user name is the value for the custom header.
    // The custom header name can be customized with a TAI property 
    // called headerName.
    // 
    public class myTAIImpl implements TrustAssociationInterceptor {
    
        private static String _headerName = "CUSTOM_HEADER";
    
        public myTAIImpl () {}
    
        public int initialize(Properties props) throws WebTrustAssociationFailedException {
            //initialize the implementation. If successful return 0, else return 1.
            if (props!=null) {
                String value = props.getProperty("headerName");
                if (value!=null && value.length()!=0) {
                    _headerName = value;
                }
            }
            return 0;
        }
        public boolean isTargetInterceptor(HttpServletRequest req) throws WebTrustAssociationException {
            // use attributes of the HTTP request to determine if you want your interceptor 
            // to handle the request
            // return true if this is the target interceptor, else return false.
            // 
            if (req!=null && req.getHeader(_headerName) != null) {
                return true;
            }
            return false;
        }
        public TAIResult negotiateValidateandEstablishTrust(HttpServletRequest req, HttpServletResponse resp)
        throws WebTrustAssociationFailedException {
            //validate the request and establish trust.
            //create and return a TAIResult object
    
            Enumeration<String> headers = req.getHeaders(_headerName);      
            if (Collections.list(headers).size() > 1) {
                throw new WebTrustAssociationFailedException("Too many "+_headerName+" headers");
            }
            String username = req.getHeader(_headerName);
            // now you can either do extra processing to validate the user or transform the value
            // to something that is more friendly to the current registry
    
            TAIResult taiResult = TAIResult.create(HttpServletResponse.SC_OK, username);
            return taiResult;
        }
        public String getVersion() {
            //Return a version specific to your implementation
            return "1.0";
        }
        public String getType() {
            //Return a type specific to your implementation
            return "my custom TAI";
        }
        public void cleanup() {
            //Cleanup code specific to your implementation
        }
    }
  2. Compile the implementation after you implement it.
    For example, app_server_root/java/bin/javac -classpath install_root/dev/was_public.jar;install_root/dev/javax.j2ee.servlet.jar
    1. [z/OS][AIX Solaris HP-UX Linux Windows]Identify the trust association interceptor class file for use when the server is restarted. Place the file either at the app_server_root/classes directory OR use the Java virtual machine (JVM) system property, -Dws.ext.dirs to specify where the file is located.
    2. [IBM i]Copy the custom trust association interceptor class files to a location in your product class path.
      Copy these class files into the profile_root/classes directory.

      You must copy this class file to the profile_root/classes directory of each node and cell.

    3. Restart all the servers.
  3. Enable trust association.
    1. In the administrative console, click Security > Global security.
    2. Under Authentication, click Web and SIP security > Trust association.
    3. Make sure that the Enable trust association box is checked.
    4. Click Apply.
  4. Optional: Delete the deprecated interceptor.
    1. Under Additional properties, click Interceptors.
    2. If the com.ibm.ws.security.web.TAMTrustAssociationInterceptorPlus interceptor is listed, select it by checking the box.
    3. Click Delete.
  5. Add your custom interceptor.
    1. Click New.
    2. Enter your interceptor class name.
      Verify that the class name is dot-separated and appears in the class path.
  6. Optional: Add properties that are needed to initialize the custom interceptor.
    These properties are passed to the initialize(Properties) method of your interceptor.
  7. Save the configuration and synchronize it, if applicable.
  8. Restart the servers for the custom interceptor to take effect.