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)
- Certificate based
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.
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.
The authentication happens in three steps.
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.