Using Kerberos authentication to call remote EJB’s on Weblogic 10.3, or not…

For a client I have been trying to get kerberos authentication to work for the following setup:

A Swing client application running on the user’s machine.

An enterprise application consisting of several EJB’s running on Weblogic 10.3.0.

The client application connects to the EJB’s remotely. Currently there is no security at all between the client and server applications.

The client application uses an initial context as such to create the connection to the server application:

private static Context getContext() throws Exception {
 Hashtable ht = new Hashtable();
 ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
 ht.put(Context.PROVIDER_URL, "t3://localhost:8001");
 // Get a context for the JNDI lookup
 return new InitialContext(ht);
}

The desire of the client are as followed:

  1. Secure the EJB’s to prevent unauthorized access.
  2. Provide single sign-on to allow users to log on to windows, and then start the application directly without logging in again.
  3. Also provide a measure to implement a password schema (size, no repetition of the same password, change the password every so often etc.)

The first point can easily be solved by using the @RolesAllowed annotation. This annotation requires the user to have a proper authorization for the EJB (method) to be present in order to call the EJB method.

For the third point we decided to use the existing Active Directory (which is present anyway as we need it for point 2). All the password strength requirements can be solved in Active Directory itself. This has the added advantage that there is only one location to administer users.

The second point is where we stranded. Authenticating using a username/password is relatively easy. Just extend the method above like this:

private static Context getContext(String username, String password) throws Exception {
 Hashtable ht = new Hashtable();
 ht.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
 ht.put(Context.PROVIDER_URL, "t3://localhost:8001");

 ht.put(Context.SECURITY_PRINCIPAL, username);
 ht.put(Context.SECURITY_CREDENTIALS, password);

 // Get a context for the JNDI lookup
 return new InitialContext(ht);
 }

However I could not find a way to use Kerberos tokens instead of using a username and password. After much looking around and some help from myfear I found some lines on the Security Fundamentals page for Weblogic 10.3. This page states (for the EJB communication protocol):

Supports Generic Security Services Application Programming Interface (GSSAPI) initial context tokens. For this release, only usernames and passwords and GSSUP (Generic Security Services Username Password) tokens are supported.

This seems to indicate that kerberos tickets, and other token based authentication methods are not possible.

Currently I have only one option which is open. This would be to write a username/password authenticator which parses the password as if it would be a Kerberos service ticket. However the time needed to provide such an authenticator is not available for the project. Maybe something to research in the future.

Asynchronous Ajax with Apex

While doing a short project with Oracle Apex we needed an asynchronous ajax call where we changed the page based on the result. Almost all the examples we could find did nothing with the response of the asynchronous call which made it take some time to figure out how to make it work.

The first stage of the asynchrounous call is exactly the same as synchronous calls in Apex:

function searchAsynchronous() {
	var get = new htmldb_Get(null,html_GetElement('pFlowId').value,
		'APPLICATION_PROCESS=AP_SEARCH',0);
	get.add('AI_SEARCH', html_GetElement("AI_SEARCH").value);
	get.GetAsync(asyncReturn);
	get = null;
}

Whenever the state of the asynchronous call changes the f_AsyncReturn function gets called. When the response is available the state will be 4.

function asyncReturn(){
	if(p.readyState == 1){
	}else if(p.readyState == 2){
	}else if(p.readyState == 3){
	}else if(p.readyState == 4){
		handleResult(p.responseXML);
	}else{return false;}
}

In our case we needed the XML DOM model of the response so we used the responseXML attribute as an argument to the function that handles the response of the search.

function handleResult(responseXML) {
	if(responseXML) {
		var count = responseXML.getElementsByTagName("row").length;
		if (count > 0) {
			for(var i=0; i &lt ; count;i++) {
				var item = responseXML.getElementsByTagName("row")[i];
				var content = item.firstChild.nodeValue;
				alert(content);
			}
		} else if (count == 0) {
			alert("no result");
		}
	}
}

The responseXML is comparable with the object that is returned when get.get('XML') is used instead of get.GetAsync(asyncReturn). If the ajax request returns plain text, or should be parsed otherwise p.responseText can be used to give a similar result to get.get()

Managing expectations

Recently i was doing a project which had the incredibly short duration of eight days. This amongst other things meant there is no time for re-writes, big changes in the interface etc. So one major issue is to keep the client satisfied with the result without allowing big changes to be introduced in the requirements.

The way we approached this was to give the client a demonstration at the development station every few days. This worked like a charm, not only did we prevent having to change things during the project, but also the client was immensly happy with seeing the progress and was suddenly very motivated to sell it to the users.

Its always nice to see people being enthousiastic about a project.