I am also looking to integrate OpenFire with CAS. I have some ideas on how this can be done, but I am only beginning the process. I would also be interested if anyone else has had experience with this, but judging from the lack of response so far to this thread, I am guessing we are pioneers in this area.
Just to be clear for those OpenFire gurus who may not be familiar with CAS, it is a single sign-on solution. Its advantage over pure LDAP authentication is that it allows a user to authenticate a single time and get access to multiple applications using the same credentials. It is primarily designed to be used with web applications, but integration with a not-purely-web-based application like a Java or Flex chat client should be possible provided the client is launched from the browser, giving it access to browser resources, in particular cookies.
Basically, each application is CAS-ified (to use the CAS terminology) so that when a user accesses the application as a not yet authenticated user, they are redirected to the CAS portal. CAS collects the username and password and authenticates the user. It returns a cookie with a CAS ticket in it to the browser and then redirects the browser back to the original application. When the CAS-ified application sees the cookie, it contacts the CAS server to validate the ticket and retrieves the username associated with the ticket. Therefore, the user is logged in without seeing any application-specific login page. When a user visits subsequent apps that are also CAS-ified, they are automatically logged in similarly, again without seeing yet another login page.
LDAP can still be used as the back-end authentication source. CAS uses ACEGI Security for Spring under the covers and ACEGI provides adapters out-of-the-box for doing the authentication against an LDAP server.
Since all one needs to log into a CAS-ified application is a way to indicate to the application that it is a CAS login (e.g. a special username) and the CAS ticket (which can be obtained from the cookie and can be used in lieu of the password), it should be possible to CAS-ify both the OpenFire server and any OpenFire client that is launched from the browser (though access to the client source code is likely required).
Here are my initial thoughts to get the ball rolling.
I would be happy to hear any opinions or just discuss this further with others who are interested. If several people need this, why not make it a collective effort and share the fruits of our labors.
CAS-ifying the client should be a matter of retrieving the CAS ticket from the cookie stored in the browser. The name of the cookie and the form of the ticket are well documented so this should be fairly easy, I think. When connecting to the OpenFire server, a special username (not valid as an OpenFire user) could be used to show that this is a CAS login. The ticket would be passed in place of the password. The only prerequisite is that you must have logged into CAS prior to connecting or there will be no cookie to retrieve. The client should probably be written to return an authentication error in the event the cookie is not found … or possibly to do a client-side redirect to the CAS portal to let the user log in. There isn’'t any clean way I can come up with of to do a server-side redirect to the CAS Portal login page since the server in this case is not a web server.
My plan is to provide a minimal, custom Flex client using the XIFF API. Since I will be writing the client, it should be relatively straightforward to do the above. CAS-ifying the Spark client would require making changes to the Spark source as nearly as I can tell. I don’'t see any non-intrusive way to CAS-fiy it.
On the server side, OpenFire kindly provides an interface that can be implemented to provide a custom module for authentication. This seems the best place to start. Essentially, the custom module could either check for a special username to determine whether to authenticate against CAS or assume all logins are via CAS. Either way, the next step is to take the ticket (from the password field) and call CAS (a simple https service) to validate the ticket. So far I have run into one problem that I am still trying to find a solution to …
The current interface for authentication assumes, as nearly as I can tell, that the username field passed in is in fact the actual username … which is I suppose reasonable. However, in this case, the username is not known until after CAS validates the ticket … the initial username passed by the client is only a placeholder. It looks like by the time this happens, it may be too late to inform OpenFire of what the real username is. I suppose one possibility would be to modify the OpenFire source rather than just creating a custom authentication adapter, but this is more intrusive than I would like. I am still looking for a way around this issue. But it is possible I have just missed something … as I said, I am only just beginning this process.
If the server authentication mechanism assumes all logins are via CAS, then I could pass the actual username instead of a placeholder indicating a CAS login. But this requires me to remember the username on the client. And since the user only types in the username on the CAS portal, I think this would require me to modify CAS to return a cookie with the username as well as the CAS ticket. So I would be trading work on the OpenFire side for more work on the CAS side. Also, I’‘m not convinced yet that there isn’'t some security disadvantage to saving the username in a cookie on the browser.
I hope this has given some food for thought. I would be very interested in hearing others view or thoughts.
Senior Developer / DBA
Northland, A Church Distributed