Previous Topic: Implement the Java XML Agent Content Helper APINext Topic: Scenarios


Java XML-Enabled Agent Functional Flow

This section describes the flow of calls required for an effective XML-enabled custom agent implemented using the Java CA SiteMinder Agent API for Java and the XML Agent Content Helper API for Java.

Force the JVM to use Xerces Parser

Include the following line at the beginning of your custom XML agent code to force the JVM to use the Xerces parser included in the CA SiteMinder WSS SDK:

System.setProperty("javax.xml.parsers.DocumentBuilderFactory","org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
Initialize the CA SiteMinder Agent API

You initialize the CA SiteMinder Agent API by creating an AgentAPI() object and initializing connections to one or more Policy Servers by issuing the init() method. For example:

AgentAPI aa = new AgentAPI();
int result = aa.init (...);
...

Through the InitDef parameter, you can specify connection parameters such as failover mode and connection pool size. This step creates TCP connections and typically does not need to be done more than once per agent instance.

Once the Agent API is initialized and its connection to the Policy Server established, all API calls are fully thread-safe with respect to the initialized API instance.

It is possible to initialize more than one API instance (for example, when working with Policy Servers that use separate policy stores).

Immediately after initializing the Policy Server connection, the agent should communicate its version information to the Policy Server by calling doManagement() with the constant MANAGEMENT_SET_AGENT_INFO set in the ManagementContextDef object. The actual information can be any string containing enough information about the agent, such as the build number, version number, and so on. The string is recorded in the Policy Server logs.

CA SiteMinder Agent API Required Code Block

The following static block of code must be included in any implementation of the CA SiteMinder Agent API class. This code should not be placed within a method:

static{
		InetAddress clientAddress;
		String clientAddressString;
		try {
			clientAddress = InetAddress.getLocalHost();
			clientAddressString = clientAddress.getHostAddress();
		}
		catch (Exception e) {
			clientAddressString = "123.123.123.123";
		}
}
Initialize the XML Agent Content Helper API

You must also initialize the XML Agent Content Helper API and initialize its connection to one or more Policy Servers. To do this you must first create an instance of ContentHelperService, initialize it, and then call createAgentApiService() to establish the XML Agent Content Helper API’s connection to the Policy Server. For example:

chs = new ContentHelperService ();
String hostConfFilePath = new String ("C:/Program Files \
	/CA/SOA Security Manager/webagent/config/SmHost.conf");
chs.initialize(hostConfFilePath);
if (chs.CreateAgentApiService() != IContentHelperReturnCodes. \
	SUCCESS) {}

To handle policy expressions that use XML Agent variables, you should create an instance of ServerVariablesResolver and then initialize it by setting values for those keys by calling its setVariables() method. For example:

// create a new Server Variables Resolver object    
svr = new ServerVariablesResolver ();   

// initialize XMLAgent variables and Server Variables Resolver
// object
HashMap serverVarsMap = new HashMap ();

String serverVendorKey = new String ("Microsoft");
String serverVendorValue = new String ("IIS");
serverVarsMap.put (serverVendorKey , serverVendorValue );
...

svr.setVariables (serverVarsMap );
Steps Required for Resource Access

Once the CA SiteMinder Agent API and XML Agent Content Helper API have been initialized, the XML-enabled agent can perform useful work. At this point it can start accepting XML documents from clients.

The agent must perform the following steps before granting a user access to a requested resource. The outcome of most steps can be cached to improve agent performance. The agent can choose to cache as little or as much as possible.

  1. Accept a POSTed XML message

    Accept a client request to access a resource. This is the application-specific request. For example, the XML Agent would accept a Web service consumer’s POST request to a URL-bound Web service.

  2. Call helperFactory() to obtain an interface to a content helper class that implements the IContentHelper interface to handle XML content.

    Note: In the CA SiteMinder WSS r6.0 SDK, the only implemented content helper is " XMLContentHelper", which handles SOAP-wrapped and raw XML.

    For example:

    	IContentHelper ich
    	ich = chs.helperFactory("XMLContentHelper");
    
  3. Initialize the XML message buffer

    Write Web server-specific functions to obtain the XML message header and body and then pass these to setMessageBuffers(). This buffers the XML message for use by the XML Agent Content Helper API.

  4. Identify the resource being requested

    Call identifyResource() to identify the URL of the requested resource and the rule action of the requesting client.

    Note: If the XMLResourceIdentification agent configuration parameter is set for your custom agent, the Policy Server will return an action of ProcessSOAP or ProcessXML; otherwise it will simply return POST.

  5. Check if the resource is protected

    Call isProtected() to determine if the requested resource is protected.

    If the resource is protected, the policy server returns the required credentials that must be obtained from the user in order to validate the user’s identity. If the resource is not protected, access to the requested resource should be allowed.

    The outcome of this step can be cached.

  6. Obtain the user credentials from the posted XML message

    Call gatherCredentials() to obtained the required user credentials from the posted XML message.

    Note: If your custom agent code does not call gatherCredentials(), instead manually populating the structures that gatherCredentials() typically populates, you must ensure that you set the value of the password field of the CA SiteMinder Agent API userCredentials.userCreds data structure appropriately: For XML Document Credential Collector (DCC) authentication, the value of the password field must be set to "N:" if no password is required or to "Y:password" if a password is required. The prepended "N:" or "Y:" informs CA SiteMinder WSS whether or not to expect a password for authentication. The appropriate value is automatically supplied by gatherCredentials().

  7. Authenticate the user

    Call login() to collect the required credentials from the user and to authenticate the user.

    Upon successful authentication, the Policy Server creates a session and returns response attributes, including the unique session id and session specification. These response attributes are policy-driven and may include user profile data, static or dynamic privileges, a number of predefined authentication state attributes, or any other data that was designated by a policy administrator.

    The agent can now perform session management by caching user session information and keeping track of session expiration.

  8. Check whether the XML message creator is authorized

    Call the CA SiteMinder Agent API authorizeEx() method to validate that the user is authorized to access the requested resource and determine whether there are unresolved variables associated with that resource.

    If authorizeEx() returns UNRESOLVED, there are XML content-based and/or XML Agent variables that must be resolved to complete authorization. Call IContentHelper.resolveVariables() to resolve XML content-based variables. If unresolved variables still remain, call ServerVariablesResolver.resolveVariables()to resolve XML Agent instance variables. Finally call authorizeEx() again to check if the message can now be authorized. (Keep repeating until all variables are resolved and authorization is successful or fails).

    Note: The CA SiteMinder Agent API authorizeEx() method is generally intended for CA internal use only, and is therefore not fully documented in the CA SiteMinder Agent API Javadoc. You should not attempt to use it any manner other than to authorize XML messages in XML-enabled custom agents using code similar to that shown in the following example.

    For example:

    ResourceContextDef rcd;
    RealmDef rd;
    UserCredentials uc;
    SessionDef ssd;
    AttributeList al;
    // set the transaction id
    String transactionID = clientAddress +
      System.currentTimeMillis();
    
    // create the unresolved and resolved variable buffers
    StringBuffer ul = new StringBuffer ();
    StringBuffer rl = new StringBuffer ();
    
    Boolean simple = new Boolean(false);
    
    // check to see if the user is authorized to use the resource
    
    int azResult = AgentAPI.UNRESOLVED;
    
    while (azResult == AgentAPI.UNRESOLVED)
    {
    	azResult = aa.authorizeEx (clientAddress, transactionID,
    	  rcd, rd, ssd, al, ul, rl, simple);
    
    	if (azResult == AgentAPI.UNRESOLVED)
    	// agent is asked to resolve variables
    	{
    		int xmlSdkReturn = IContentHelperReturnCodes.FAILURE;
    
    		// try to resolve variables other than 'XML Agent'
    		// variables
    		xmlSdkReturn = ich.resolveVariables(ul, rl);
    
    		if (	xmlSdkReturn == IContentHelperReturnCodes.FAILURE
    			||
    			ul.length () > 0
    		)
    		// there are still variables to be resolved
    		{
    			xmlSdkReturn = svr = resolveVariables(ul, rl);
    		}
    	}
    }
    // end of while (azResult == AgentAPI.UNRESOLVED)
    

    Upon successful authorization, the policy server returns response attributes including resource-specific privileges. These response attributes are policy driven and may include user profile data, static or dynamic privileges, or any other data that was designated by a policy administrator.

    At this point the user’s authorization information with respect to the requested resource is known and can be cached to speed up future requests.

  9. Apply any responses that modify the content of the buffered XML message

    Call applyResponses() to apply any XML message content-based responses (for example, SAML assertions) to the XML message before passing that message on to the Web service.

  10. Check to see whether the buffered XML message content has changed

    Call isMessageHeaderListModified() and isMessageBodyModified() to check whether the buffered XML message has been modified as a result of applyResponses().

  11. If the buffered XML message content has been changed, obtain that content from the buffer and return it to the Web server.

    Call getMessageHeaderList() and/or getMessageBody(), as applicable, to retrieve the XML message content from the agent buffers and then write Web server-specific functions to pass these back to the Web server.

  12. Audit cached authorization information

    Both the authentication and authorization steps log the relevant information about the user, the protected resource, and the agent. However, if the agent performs authorizations out of its cache, the transaction can still be logged through the audit() method.

  13. Allow access to resource.

    Now that the XML message originator’s identity is known, authorization has been verified, and the required entitlements obtained, give the authorized user access to the resource.

  14. Issue a management request to update encryption keys and/or flush caches.

    (Optional) Poll the Policy Server for update commands by calling the CA SiteMinder Agent API doManagement() method. In response, encryption keys are updated for the AgentAPI() instance and/or the caches are flushed .

    If doManagement() returns an indication that encryption keys have changed, call agentKeysChanged() to force the ContentHelperService() instance to poll the Policy Server for the updated encryption keys.

    If doManagement() returns an indication of a cache update event (FLUSH_ALL or FLUSH_ALL_REALMS), call IContentHelper.flushcache() to flush the agent caches and obtain updated metadata (for example, user attributes) from the Policy Server.

Uninitialize the APIs

Once the agent is no longer needed, uninitialize all API instances by issuing the ContentHelperService.shutdown() method for each XML Agent Content Helper API instance and the unInit() method for each CA SiteMinder Agent API instance. This closes TCP connections to all policy servers.

Note: The CA SiteMinder Agent API does not provide a facility for caching in a manner that enforces session validity. By choosing to cache user sessions and/or resource-specific privileges, the agent becomes obligated to perform its own session management during each user request. This session management is required, since caching on the agent removes the need to contact the CA CA SiteMinder WSS Policy Server to perform session validation and/or resource authorizations.