About the single sign-on framework

The Build Forge® SSO framework provides the capability to integrate with many SSO solutions on the market. The SSO framework is interceptor-based, meaning that it intercepts an HTTP request and provides methods for handling it. You can write custom interceptors to receive and validate security artifacts in the HTTP request. In particular, the interceptor can set tokens in the HTTP response and then look for those tokens in a successive request.

Two SSO solutions are provided with Build Forge®:

SSO framework methods

An SSO interceptor is a Java class that implements an interface used by the Build Forge® SSO framework:
com.buildforge.services.server.sso.ISSOInterceptor
It is located in the services layer component:
<bfinstall>/Apache/tomcat/webapps/jas/WEB-INF/eclipse/plugins/com.ibm.jas-1.0.jar

The interface provides the following methods.

initInterceptor
Called when the interceptor is loaded. A map of configuration properties is passed to the initInterceptor() method. Configuration properties are created in the Build Forge console at Administration > Security > SSO.
isTargetInterceptor
Reviews attributes in the inbound request to determine if this interceptor needs to act on them. If so, the interceptor is responsible for authenticating the request with the authenticateRequest() method. Otherwise this interceptor is skipped. Interceptor selection assumes that multiple interceptors are configured and running. They are addressed in order.
authenticateRequest
Authenticates the request using data in the request. It uses a response attribute to send data back to the client.
logoutRequest
Cleans up any user-related security information after the request is handled.

Interceptor configurations and ordering

Interceptor configurations are defined in Administration > Security > SSO. The following configurations are shipped with Build Forge®:

After you implement an interceptor class and place it in the Build Forge® Apache Tomcat application server, you configure a new SSO configuration here. The class is one property of the SSO configuration.

The order of this list determines the order in which interceptors are consulted to handle requests. You can configure multiple interceptors to handle requests. During a login, each interceptor is consulted in order. The interceptor that handles the request is the first active interceptor whose attributes are appropriate for the attributes in the request. Only one interceptor handles the request. It is always the first one that responds true for isTargetInterceptor.

Note: To provide a fallback in the case of error, leave the Form SSO interceptor active. Place custom interceptors in the list before it.

Adding a custom SSO interceptor

To create a custom interceptor in Build Forge®, complete the following steps:

  1. Create a custom Java class.

    The class must implement the ISSOInterceptor interface.

  2. Deploy the custom class to the services layer component WAR file.
    1. Create a JAR file containing the compiled custom SSO interceptor class.
    2. Merge the JAR file into the Build Forge® services layer JAR file in the following location: <bfinstall>/server/tomcat/work/Catalina/localhost/jas/eclipse/plugins/com.ibm.jas-xxx.jar.
    3. Restart Build Forge®.
  3. Optional: Define an environment. This environment can be passed to the initInterceptor() method as a properties object.
    1. In the Management Console, go to Environments.
    2. Click Add Environment.
    3. Define all of the properties needed by the SSO interceptor to initialize.
  4. Add the SSO interceptor to Build Forge®:
    1. In the Management Console, go to Administration > Security > SSO.
    2. Click Add SSO Configuration, and enter the properties:
      • Name - enter a name for the SSO configuration.
      • Active - set to Yes. Active configurations are all accessed during an authentication request. They are accessed in the order in which they appear on this panel.
      • Java Class - enter the full package name of the class. A given class can be assigned to only one SSO interceptor.
      • Environment - if you defined an environment to use with this SSO interceptor, select it.
    3. Click Save.
    Your SSO interceptor now appears in the list.
  5. Order the SSO configurations by clicking the icon to the left of your SSO Interceptor, and then select Move to Top.

    During a request, active SSO configurations are accessed in the order in which they appear on this panel. Because it is active by default and always returns true when accessed, your configuration must be placed before the Form SSO configuration. The SPNEGO SSO configuration is inactive by default.

Example authenticateRequest implementation

The following example is taken from the WebSphere SSO interceptor, which is used to integrate WebSphere Application Server security with Build Forge®.

The interceptor uses reflection to find the WebSphere class WSSubject. The class has a getCallerPrincipal method to return the principal used to log in to the AuthServlet. The AuthServlet needs to be protected before WebSphere Application Server can authenticate with it.

Other methods are available that can return even more information. Similar methods are available to work with any application server.

public Result authenticateRequest 
      (Request requestAttributes, Response responseAttributes) 
       throws SSOException {

  Result result = null;

try {
  Class<?> cl = 
    Class.forName(“com.ibm.websphere.security.auth.WSSubject”);
      Method theMethod = cl.getMethod("getCallerPrincipal", 
        (Class[])null);
    String principal = (String)theMethod.invoke((Object[])null, 
          (Object[])null);

if (principal != null 
      && principal.length() > 0 
      && !principal.equals("UNAUTHENTICATED")) {
  result = new Result(Result.UseridOnlyOID, domain, principal);
	responseAttributes.setStatus(HttpServletResponse.SC_OK);	
} catch (Exception e) {
		throw new SSOException(e);
}

return result;
}

During the implementation of authenticateRequest, you must set a response status before returning:

There are additional status values that can be used. See the JavaDoc for HttpServletResponse.

Recovering from a login error

If your custom interceptor does not work correctly when tested, the most likely issue is authentication. An error page is displayed with the following information:

Build Forge Error

     Access is denied to the Build Forge console

     "Error authenticating:
     com.buildforge.services.common.api.APIException - API:
     Authentication Error."

     Please click here to try the same type of login again
     or click here to force a form login (user ID/password).

You have two options for recovery:

Method source listing

The following comments and source listings provide more information about the methods in the ISSOInterceptor interface.

initInterceptor
	/**
	 * This method is called when the interceptor is loaded.  A map of the 
     configuration properties is passed into the init method.  You can create 
     the configuration properties from a BuildForge Environment and associate 
     it with the SSO configuration.
	 *
	 * @param initializationProps used to configure the implementation
	 * @return true if successful, false if an error should be reported.
	 * @throws SSOException if the initialization fails
	 **/
	public boolean initInterceptor (Properties initializationProps) throws SSOException; 
isTargetInterceptor

	/**
	 * This methods will review the attributes in the requestAttributes Map 
     to determine if there is something that this interceptor should 
     act on.  If the interceptor return is "true", then the interceptor will 
     be responsible for authenticating the request and the authenticateRequest 
     method is invoked. If the interceptor return is "false", then this 
     interceptor is skipped and the next isTargetInterceptor in the list will 
     be called. Ordering of the interceptors during the configuration will 
     return which interceptor has the first shot at authenticating a request.
	 *
	 * @param requestAttributes attributes found in the inbound request	 
   * @return true if this interceptor will authenticate the request, 
             false if it will not.
	 * @throws SSOException
	 *
	 **/
	public boolean isTargetInterceptor(Request requestAttributes) throws SSOException;
	authenticateRequest

  /**
	 * This method is called on an interceptor that returns true for the 
     isTargetInterceptor method. The Request will contain data used 
     to perform the authentication.  The Response is for the interceptor 
     to send information back to the client.  The Result returned will contain 
     the following information if the status code is 200:
	 * 
	 * OID: an object identifier of the SecurityContext that can process token 
     information stored in this map when going to an Agent.
	 * Domain: a valid BF domain name or <default> if not known 
     (the username must be valid in the configured realm).
	 * Username:  a valid BF username.   This will be used to lookup BFUser attributes 
     that are used in checking authorization policy.
	 * @see com.buildforge.services.common.security.context.Result
	 * 
	 * @param requestAttributes attributes found in the inbound request
	 * @param responseAttributes sent back in the outbound response
	 * @return com.buildforge.services.common.security.context.Result - result 
          information that tells BF how to handle the authentication request.
	 * @throws com.buildforge.services.server.sso.SSOException
	 **/
	public Result authenticateRequest(
			Request requestAttributes, 
			Response responseAttributes)
		throws SSOException;
	logoutRequest

  /**
	 * This method is called to logout a request. The first interceptor that 
     returns true for the isTargetInterceptor method will perform the logout.   
     The main point is to clean up any user-related security information that 
     should not be kept.  The interceptor can inspect the request and response 
     objects to determine what needs to be removed.
	 * 
	 * @param requestAttributes attributes found in the inbound request
	 * @param responseAttributes sent back in the outbound response
	 * @return boolean - true if request redirect to exit page, 
                       false if redirect to login page.
	 * @throws com.buildforge.services.server.sso.SSOException
	 **/
	public boolean logoutRequest(
			Request requestAttributes, 
			Response responseAttributes)
		throws SSOException;

Feedback