Thursday 6 March 2008

Log In into Domino using AJAX

The other gurus have probably covered this already, but I only worked this out today and if you haven't this is really a rather cool trick.

Domino allows you to login to the server using the following URL structure if you have session authentication turned on.

http://[server]/names.nsf?login&username=[username]&password=[password]&redirectto=[url]

and similarly logout using

http://[server]/names.nsf?logout

So it occured to me that if the browser allowed a session cookie to be set by and AJAX call to these URLs then it would be possible to override the default notes logon and have an application specific login or out functions on any page or form.

So basically what you do is use this to your advantage by constructing a AJAX connection using whatever framework you want using either GET or POST that calls the LOGIN or LOGOUT parameter and populate the &username= and &password= from values in your form. Now comes the cheeky part, instead of a page have an agent in the &redirectto= parameter. This agent is a very simple beast like this

Sub Initialize
Print |Content-Type:text/plain|
Print |***Logged IN***|
End Sub


This will be returned to the browser as plain text .. do a simple test for ***Logged IN*** being present and act accordingly by redirecting to another page or doing something on the page your are on This text will ONLY be present if you logged on successfully.. if your sign-on fails the text is not there so you can act accordingly for a log-in failure.

You do have to remember to make your login page or form available to Public Users and ensure
that all other pages and views are not available to Public users. Also setting the ACL of your application so that DEFAULT has no access but IS allowed to READ PUBLIC DOCS.

I have used this technique in an application and it works, sadly I cannot share the application it being company property and all that. But if anyone is interested I could throw together a sample file and post it in the code bin on OpenNTF .. let me know if you want it.


** UPDATE **
As has been pointed out in the comments by both Radu Cadiru and Jake Howlett. There are BIG security issues with using the GET option in that this will expose your USERNAME and PASSWORDS both on the network and in the various web logs on the server and in browser caches.

I would strongly recommend you use the POST method to pass the data and to do so over your SSL port. *** Especially if this in on the INTERNET *** This will make it difficult for your user's username&password data to be "snooped".




Slaun
Steve

5 comments:

Radu Cadariu said...

from the security point of view this is hell, since all your usernames AND passwords will appear in the logs of the Domino server in clear text. I would advise against it, hope your app is not on public site :)

Jake said...

This is a topic I've been meaning to tackle for a while and probably will do soon.

I don't see it as a security issue, as long as you user POST rather than GET. In that way you're just doing exactly what a normal Domino login form does.

Why not have it return json? All the agent/page/whatever needs to do is return "@UserName" and see if it's "anonymous" or not.

Jake

Steve McDonagh said...

@radu

You are corrent and i
In the application I uses a POST rather than a GET for this very reason while not perfect it is as Jake says doing exactly the same (with a POST) as the server does The Application is not on a public facing port it is an intranet only app and yes it I direct the logon to an SSL port. I was going to cover these points if anyone was interested ... LOL ... perhaps I should have straight away .. I have added an update to the orginal post.

@Jake

Acutally I am looking at the JSON return today. I was going to load up PAB info about the signed on user.. DEPT, MANAGER, FULLNAME etc into a JSON User object rather than have to bounce back and forth to the server everytime we need that info.

Steve

Jake said...

Alternatively you could test the cookies of the returned page for DomAuthSessId
I've been thinking about it and wondering it it's worth logging in with Ajax? Surely upon a successful login you'd want to refresh the whole page anyway as so much of what makes up most webpages is user dependent. No?
Jake

Steve McDonagh said...

@Jake

Thats something we are doing at the minute ... I have a function that is called as part of the post connection event that tests for the continued existence and contents of the DomAuthSessId cookie, which if your session expires on the server will disappear, if this happens the user is pushed back to the logon screen.

In my app the login is a [div] near the top of the page, like the blogger log in. Once logged in the [div] is set to display:none; and a logout option appears as does the "logged in" all without the page having to be re-composited by the server.

This was more a "look and feel" tip
i really am not keen on the amount of fiddling you have to do to get a nice consistent signon display for an app.

1. The look of the login page is application dependent and not server dependent.

2. When the page expires and the user is forced to re-logon you can do that without moving from their current position in the app. Simply hide the current data panels and display the logon, and when the user logs back in redisplay them as they were. I know the server does this too.. but it looks so.. OLD :)

3. When you send a notification mail say of a review pending and the link points at a specfic document you can code your page to do the logon (dependant on the existence of DomAuthSessId) and then display the document. I know the server does this anyway but you get again a consistent UI feel to the application.

4. I have the JSON I mentioned earlier returning a Logged On User Object. Which gives me the bits of the PAB for that user that I might need, which the server doesn't do on logon.

None of these are show-stoppers and the server does most of the things for you anyway.

My app follows this scheme on logon

01. Nicely formated home page, admin contact details etc and a logon option

02. User logs on (sucessfully)

03. Page polls the server and gets back the users available menu options based on user name

04. Menu system enabled and displayed

05. User free to do whatever they need to.

I did some benchmarks to see if this was was any more efficient at compositing the page than the tradition method.. and is was about the same the AJAX method was slightly faster bit only marginally so on a normal menu tree.

Steve

Disqus for Domi-No-Yes-Maybe