We've done this. I think that the best way would be to implement the XWikiAuthService, XWikiRightService, and XWikiGroupService interfaces (in the com.xpn.xwiki.user.api package) using a JAAS structure. However, time constraints (plus the already robust XWiki.XWikiRights and XWiki.XWikiGroups objects built into the database) led me to provide a solution that subclassed com.xpn.xwiki.user.impl.XWikiAuthServiceImpl, overriding only the checkPassword method (and adding a default constructor that did some initialization of a client to the external password lookup service). Something like: package com.timcoop.xwiki.user.impl; import com.xpn.xwiki.user.impl.xwiki.XWikiAuthServiceImpl; public class TimsCustomDatabaseAuthServiceImpl extends XWikiAuthServiceImpl{ /* do be sure to throw in the Log initialization, ** which you can mimic from XWikiAuthServiceImpl */ public TimsCustomDatabaseAuthServiceImpl() throws XWikiException { super(); /* ** set up the database connection or whatever */ } protected boolean checkPassword(String username, String password, XWikiContext context) throws XWikiException { String uname = username.substring(username.lastIndexOf('.') + 1); XWikiRequest request = context.getRequest(); HttpSession session = request.getSession(false); Principal principal = (Principal) session.getAttribute("org.securityfilter.filter.SecurityRequestWrapper.P RINCIPAL"); String principalName = null; if(principal != null) principalName = principal.getName(); /* did all the above so I could do this; don't want to call the database unnecessarily */ if(principalName != null && principalName.equals(username)) return true; return password.equals(getUserPasswordFromTimsDatabase(uname)); } } With Eclipse, it's a snap, of course. Once you've done that, add a line to your xwiki.cfg file: xwiki.authentication.authclass=com.timcoop.xwiki.user.impl.TimsCustomDat abaseAuthServiceImpl and, of course, compile and put your code somewhere that the server can deploy it... If the database is not needed for anything more than verifying the user's password, this should work for you just fine. If various user attributes need to be gained from the database, you may need to do more, but unless they control or otherwise affect rights within the wiki, you will probably not have to implement the other two interfaces. Also, the code that I included in the checkPassword method is crucial, because the method is called every time any XWiki object or document checks access rights, which is just about every time it tries to do anything. This can amount to hundreds, or thousands(!) of times per HTTP request (for example, the Main.AllDocs and search pages check view access to every document that they may list, and many other operations called by render operations do this also). If your database retrieval happens to depend on some XWiki rights determination, of course, you're in infinite-recursion land, so as the doctor says: don't do that. One implication of this is that the password validation survives as long as the session does, so that if the user changes the password from another session, this one won't suddenly stop working. Since this is pretty much the way we expect sessions to work, that's probably not a problem. If you need it to behave differently, well, do that. A last thought is that you can probably dispense with the added default constructor, if you simply implement the user/password association in an object that you persist with Hibernate, and all that database initialization goes into the Hibernate configuration. I know very little (effectively nothing) about that, however; others will have to help you with that. Oh yes, there is also the fact that you may actually be able to forget everything else I've said above if it turns out that you can configure Hibernate's database mapping of the XWiki.XWikiUsers object in the user's profile page - or even just the password field - to point to your custom database... The user page will also need to be modified if you also want to handle all the identity lifecycle activities (creation, deletion, password changes) through the existing database's interfaces. In this case, the user registration page will have to be modified or disabled. Well, there's potentially a lot more to it, but I hope this is a useful start. brain[sic]
-----Original Message----- From: [email protected] [mailto:[email protected]] Sent: Thursday, November 02, 2006 11:45 AM To: [email protected] Subject: [xwiki-users] User authentication from an existing database
Hi everyone.
I'm looking to use XWiki for our corporate intranet. I would like to authenticate users from our existing database, like it says on this page: http://www.xwiki.org/xwiki/bin/view/AdminGuide/Pluggable+Authe ntication It says "Users can be authenticated against custom tables."
Can somebody tell me how to do this? Or do I need to write some custom code? Thanks. Sorry if the answer is documented somewhere; I haven't been able to find it. -- Tim K