Hi everyone,

I'd like to post a few quick thoughts about authentication strategies for JSPWiki 3.0. When I say "authentication," I mean the process by which a user logs into JSPWiki. I don't mean "authorization" -- what a user can do once they log in.

Since 2.4, we've used a captive JAAS (the Java Authentication and Authorization Service) to log in users. That means we tell the JVM where to find our login configuration, and then we execute the "login stack" as its configured. "Authentication" via JAAS happens twice: once when the user's HTTP request is received (so that we can grab any container-managed credentials) and (optionally) a second time if we authenticate against JSPWiki's user database, using Login.jsp. It's a "captive" JAAS system in the sense that we wire it up and execute it independently from the container.

I suppose the details of exactly what we do don't matter nearly as much as the technologies. In both cases, we're relying on JAAS to look up a LoginConfiguration and execute it.

Of course, the current strategy causes problems because it means sometimes we need to wire up certain containers in special ways (e.g., JBoss). And it's sometimes a deployment hassle. From the deployer standpoint, it's probably not very obvious what the jspwiki.jaas config file we use does.

On the plus side, using standard JAAS LoginModules for authentication is a good thing because it's a fairly well-defined interface, and if developers want to plug in their own LoginModules, it's just a matter of configuring the JAAS login config file and putting the custom module on the classpath. So that's good. Also, we get to say that we're doing things in a "Java standard" way.

But I confess I've been re-thinking the authentication strategy lately, largely because of some of the deployment hassles people have experienced. To solve them properly, there's really only two ways to go:

1) Build a "clean-room" implementation of LoginContext that would re- implement the JAAS login stack, but do it in a way that could be instantiated per-webapp, rather than JVM-wide. That would allow us to re-use all of our LoginModules and the JAAS config file, and is the least invasive alternative. Precedent for this approach exists. This is totally analogous to how we've handled the security policy configuration issues with jspwiki.policy: the "local security policy" scheme is, in essence, a clean-room (and portable) re-write of the Java security Policy class. It doesn't require any special JVM config to work, and it's the policy files it reads are line-for-line compatible with the standard J2SE policy files.

It's a neat approach, but not the only one. Which brings me to the second approach:

2) Get rid of significant chunks of the JAAS login scheme we use, and do something a little simpler. I'm thinking, in particular, of putting in a very lightweight servlet filter that wraps the incoming HttpServletRequest. It would delegate to WikiSession for getUserPrincipal() and getRemoteUser(), and delegate to WikiSession and AuthorizationManager for isUserInRole(). This is similar to how, for example, ACEGI does things. For configuring custom authentication, we'd simply put in a single line that points to ONE LoginModule to execute. As it happens, that's what we do today in the "jswiki-custom" configuration -- the config says, "execute [just] the UserDatabaseLoginModule." Today, we specify the UserDatabaseLoginModule class name in jspwiki.jaas -- all we'd be doing is moving it to jspwiki.properties.

I'm strongly leaning towards number 2. Benefits would include:

- No more fooling around with the java.security.auth.login.config system property (meaning: no more container dependencies)
- We'd throw away jspwiki.jaas
- isUserInRole() would become a lot more useful to JSPs because callers could inquire about JSPWiki roles, and even about wiki group membership
- "Probably" better compatibility with schemes like ACEGI
- We could slightly reduce the security privileges JSPWiki requires to run under a security manager (hypothetically)

Here's what wouldn't change:

- We'd keep the JAAS UserDatabaseLoginModule class for custom authentication (and allow it to be swapped out in favor of any LoginModule, by changing a line in jspwiki.properties) - We'd keep the cookie authentication technique (as much as it pains me to do so) and the cookie-sniffing technique for "asserted" names - WikiSession, with its embedded Subject and Principals, would still exist and be associated with the HttpSession
- Public API for WikiSession, SessionMonitor, etc. wouldn't change
- Java security policies (and the related APIs in AuthorizationManager) would stay exactly the same

I don't see too many downsides to this, frankly. Really, this is more about the "plumbing" than stuff that would be visible to users, deployers or developers not named Andrew.

Thoughts? There's nothing that says we need to wait until 3.0. If everyone likes this idea, we could do it in 2.8.

Andrew

Reply via email to