Hiding Domino HTTP authentication in Vaadin applications

All web based applications that I’m building nowadays are based on Vaadin. If you haven’t heard of this framework I highly recommend to check it out.

One of the benefits of Vaadin is that you can run the same application on multiple server platforms. Those platforms are in our case IBM Domino and IBM WebSphere Liberty. Serving different platforms also means to work with different authentication mechanisms. You can use either the “application authentication” or the “platform authentication” approach. I prefer the latter as you can rely on rock-solid authentication mechanisms of the application server instead of creating your own stuff.

This decision also makes it “interesting” in terms of: how can I accomplish the same user experience for an application login while leveraging different systems? So here’s how I do it on Domino.

 

To give you some background: a Vaadin application is a servlet application that runs in the context of a Java EE web container, which is on Domino the Lotus Expeditor web container. As Java EE roles aren’t supported/working on Domino you’ve to forward the security stuff to the server (which is IMHO the better way).

IBM Domino has, like other HTTP servers, basically three manual authentication methods for its HTTP stack:

  • None (Anonymous)
  • Password
  • Certificate based

Why “manual”? Well, you may also go with SPNEGO or SAML. But that’s a different story. You’ll find mostly password based authentication for the manual login.

 

Depending of the server configuration an administrator may completely lockdown the HTTP access to the server with a server-based login – or an anonymous access may be allowed, too. In the first case it’s easy – the user get’s authenticated and then reaches the application as an authenticated user. In the latter case the application (in our case the Vaadin) has to take care of authenticating the user.

 

docstore_login

 

This login form (to be specific: the underlying code package) is the same on all platforms. From there we’re authenticating, if not already done, against the application server.

You can reach the form with an anonymous request and login from there in two ways. The first way has been described by Sven Hasselbach some time ago here (search for the word “anonymous” on the site to find the code/example). This is an easy solution as you’re directly forwarded to the server login and  you’ll come back – if successfully authenticated – with an authenticated HTTP session (cookie based). That’s great. But – it breaks the user interface experience in some way as the application login and the server login don’t match.

That’s where way  no. 2 enters the game. As Vaadin is a Java based, stateful web application you’ve all the power of Java at your fingertips. And as the guys at Vaadin do a great job you’ve also great client-side capabilities.

 

So lets dig into some code. The following snippet shows an extract of the custom “WebAuthenticationDomino” class which handles some Domino related stuff (server login, server access checking, roles etc.). To be specific the code example shows the method that is used to authenticate and initiate the session based authentication.

 

public class WebAuthenticationDomino implements WebAuthentication {

	private Logger	 logger = MPLog.getInstance();
	private Session	 session;

	/**
	 * @param username
	 *      The user name, must fit the allowed authentication name variations in the server document.
	 * @param password
	 *      The users password.
	 * @return
	 *      True is the user has been successfully authenticated, otherwise false.
	 */
	@Override
	public boolean isValidUser(String username, String password) {
		boolean isValid = false;
		try {
			session = NotesFactory.createSession((String) null, username, password);
			if (session != null) {
				String token = this.requestToken(username, password);
				if (!token.equals("")) {
					JavaScript.getCurrent().execute(String.format("document.cookie = "%s";", token));
					isValid = true;
				}
			}
		} catch (Exception e) {
			logger.error(e);
		}
		return isValid;
	}
}

 

The authentication happens in three steps.

 

Native authentication
The given username and password is natively authenticated against Domino. That may seem as an extra, not needed step but it’s the easiest (== fastest) way to authenticate the user.

session = NotesFactory.createSession((String) null, username, password);

You’ll get back a valid native session (may/will be leveraged in other, non shown methods) in the case of a successful authentication.

 

Getting a session token
The next step is to get a session token for the user.

String token = this.requestToken(username, password);

I cannot expose the full code here (sorry), but ‘requestToken(username,password)’ basically creates a HTTP/S connection to the current server and and initiates from the backend a form based authentication. That will return the session cookie for the authenticated user (HTTP header “Set-Cookie: DomAuthSessId”).

See here for some sample code.

 

Returning the cookie to the browser
Imagine: You’ve authenticated the user in the backend natively. You’ve used a backend HTTP/S request to get a session cookie for this user. And now you’ll use a “backend method” to return that cookie to the browser.

JavaScript.getCurrent().execute(String.format("document.cookie = "%s";", token));

The JavaScript class is a convenience class within Vaadin to interface with JavaScript code – without writing the client-side (hello, Marky ;-)). In this case we’re writing the gathered token right into the document.cookie property of the browser. The user/browser tab is now fully authenticated with a Domino HTTP session without leaving the Vaadin UI. Mission accomplished.

 

Happy coding!