I apologize for the length of this message, but it's a topic that I
believe to be of pretty wide interest and takes some explaining.
I've built a servlet filter to intercept requests and demand cookies,
redirecting to an enterprise SSO server if they're missing or invalid.
Intended to provide the benefits of the SSO server to any J2EE-compliant
servlet, it implements the servlet API methods
HttpServletRequest.getUserPrincipal() and
HttpServletRequest.isUserInRole() in a custom HttpServletRequestWrapper,
which it initializes with the cookie-supplied information and then
passes down the filter chain. An interface for writing custom adaptor
classes is provided, and for XWiki I use it to customize the Principal
to prepend "XWiki." to the value to be returned from
Principal.getName(). All this is working splendidly for XWiki without
the need for any custom versions of the authentication, rights, or group
services, which was a design goal.
Another design goal was to eliminate the need for manual registration of
new users, either by themselves or administrators, by automatically
registering any user not already registered before passing the request
on. My filter provides two possible avenues for this: first, a second
filter, which can be placed after the first, sends a generic POST
request with all the cookie data to a custom-crafted URL, which is easy
enough for an application such as XWiki to provide - or so it seems;
second, adding code (in the application-specific adaptor interface
mentioned above) to accomplish the task directly using the XWiki APIs.
The first approach would have required a custom form, and it looked hard
enough that I didn't try it, but most of all I couldn't work out how to
get the correct permissions. Between that and the second, I created a
URL object with which I formatted a GET request to the
XWiki.RegisterNewUser page. That had significant problems, chief of
which was determining whether the registration had actually worked - the
HTTP status doesn't tell you, and I'd have to parse the response to
guess the answer. Changing the form (which I had to do anyway) would
make that easier, but I didn't like that answer either.
So now I come to the second approach, which has so far been the most
straightforward and appears, sometimes, to work, sort of. There is an
XWiki.createUser() method that takes only the user name, a Map of object
properties, the parent document name, the user profile document content,
the user's privileges and the XWikiContext. All of those except the
XWikiContext can be determined easily, but what goes into the context,
and how it gets there, is another question, not to mention how I get my
hands on the XWiki object running in the servlet to exercise that
method.
The second problem was attacked first. I found that after the servlet
had handled its first request after starting, there was a property in
the servlet context called "xwiki", and the currently running instance
was its value. Bingo. As long as I could be sure I wasn't the first
customer of the day, everything was great. And that would still work if
it had to, but I still didn't like it. Putting a breakpoint in
XWiki.init_xwiki(), which looked to be where the show began, showed me
that it was called by a chain of (deprecated) constructors called,
ultimately, by static method getXwiki. Now we're getting somewhere.
But still I had to get some information into the XWikiContext which I
had to pass to that method.
I've had a bit of trouble getting to the method in the Struts packages
that is called to initialize the context, and I'll probably find it
eventually, but it's taking a long time and I'm hoping that someone has
better understanding of Struts and J2EE and other such stuff and could
shortcut my current route to understanding all of this, and/or to
suggest a better approach.
So, in short:
1) Where, if anywhere, can I jump into the XWiki APIs to initialize
the context properly? and/or
2) If this is a stupid way to approach the problem, what would be a
wiser one?
Thanks in advance, as always,
brain[sic]