Add new attachment

Only authorized users are allowed to upload new attachments.

This page (revision-111) was last changed on 23-Jul-2009 09:30 by StefanBohn  

This page was created on 19-Jul-2005 01:39 by

Only authorized users are allowed to rename pages.

Only authorized users are allowed to delete pages.

Difference between version and

At line 1 changed 199 lines
This page contains a quick overview of the AAA development for JSPWiki 2.3. There has been quite a bit of development done on it since January to merge the classic custom JSPWiki authorization scheme with web container authorization and standard Java 2 security. Here are the highlights.
''--Andrew Jaquith''
The core concept is the WikiSession, an object that is stored in the user's HTTPSession.
It contains a standard J2SE Subject with a collection of Principals. The Principals
can be one of two types (more on how they get there in a minute).
1. User Principals -- one or more, as supplied by the JAAS LoginModules
2. Built-in Role Principals - represents the logical roles "admin", "authenticated",
"anonymous", "asserted" (user supplies a cookie saying who they
are, but doesn't authenticate), and "all" (any of the preceding four)
So, how do the Principals get there? Easy---JAAS. Recall that JSPWiki can use either
container-managed auth, or its own custom authentication scheme. Let's handle the
container case first.
For container-managed auth, the WebContainerLoginModule tries to "sniff"
the Principal from the HTTP request. If it's there, we use it and add that Principal
and two Role Principals: ALL and AUTHENTICATED. If not, we try the RemoteUser property
and manufacture a synthetic user Principal and the ALL and AUTHENTICATED Roles.
If neither of these methods succeed, we manufacture a generic user Principal represeting
an asserted user (if we can find a cookie using CookieAssertionLoginModule) or an
anonymous user (if we cannot). The role principals in this case would be ALL (of
course) and either ASSERTED or ANONYMOUS. The AnonymousLoginModule that runs last
*always* succeeds.
The process I've just described happens automatically without user intervention.
What's point to remember is that we will always have a populated WikiSession with
a Subject containing some built-in roles that we can use for authorization purposes.
Let's go to the custom-auth scenario---we're not using container authentication,
but JSPWiki's own authentication. In this case the UserDatabaseLoginModule takes
data submitted on the login form (Login.jsp) and authenticates against the UserDatabase
we've configured to use with JSPWiki. The default database persists to an XML file,
but the interface is documented so you could use it with an RDBMS or LDAP if you
wish. If the login suceeds, it replaces the Subject's Principal set with three user
principals representing the user's login name, full name, and wiki name (for flexibility,
so we don't need to be super-precise in ACLs). It also adds the built-in roles ALL
The net result of the whole process is that we have at least one user Principal
representing the user's identity, and at least two built-in role principals: ALL
plus either ANONYMOUS, ASSERTED or AUTHENTICATED. (I'm glossing over some important
stuff about how the ADMIN role gets populated, and about the anti-spoofing checks
we need to do, but we can have that discussion later.) Because we're using JAAS
for login, too, we can configure the login process however we like---although I
think the defaults are pretty decent.
Authorization grants access based on 1) examination of the Principals the user possesses
and 2) whether the user belongs to an external role or Wiki group. Recall that even
"anonymous" users will still have the ANONYMOUS Role, so we can make decisions
based on that.
What constitutes a request for access? A read, write, rename or delete operation
on a page; attempt to self-register; create, save or delete a wiki group; create
a page, etc. The calling JSP or Java code asks JSPWiki to authorize the action by
calling AuthorizationManager.checkPermission(WikiContext, Permission). The Permission
will either be a PagePermission (if it involves page-level operations) or a WikiPermission
(for Wiki-level operations like registering a user, or creating a group, or page).
The authorization process works as follows:
- If the Subject's principal set includes the Role principal that is the administrator
group, always allow the permission.
- If there is no ACL at all, check to see if the Permission is allowed according
to the "static" security policy. The security policy (jspwiki.policy,
see below) specifies what permissions are available by default
- If there is an ACL, get the list of Principals assigned this permission in the
ACL: these will be Principals representing a role, arbitrary wiki group or user.
Then determine whether the user (Subject) is considered to have any of these roles
or principals. THAT process is as follows:
- If the desired Principal is a built-in Role, the algorithm simply checks
to see if the Subject possesses it in its Principal set
- If the desired Principal is a Role but not built-in, the external Authorizer's
isInRole method is called
- If the desired principal is a wiki Group, the GroupManager's group authorizer
isInRole method is called
- If the desired Principal is a user, check whether the Subject possesses it
in its Principal set
- Otherwise, deny the permission
What this algorithm gives us is a way to use built-in roles (AUTHENTICATED, ALL
etc) in our access checks, but also external groups (such as those provided by the
web container) and ad-hoc, arbitary wiki groups. So, if you've got an external LDAP
server wired up to your web container for authentication and authorization, you
can use it! And if your users want to create their own wiki groups by creating a
special Group* page, we can use that too.
Again, I'm glossing over some important details about name resolution, anti-spoofing
and the like, but I think you can see how the overall authorization process works.
!Security Policy
Underpinning the authorization process is a standard Java 2 security policy (jspwiki.policy).
The policy file gives us a way to express what the static page permissions of the
wiki should be in the absence of page ACLs---these are the PagePermission grant
statements. It also controls certain aspects of what a user can do for non-page
operations---these are the WikiPermission grants. It's a standard Java policy file,
so if you are familiar with the syntax it should be easy to understand. The PagePermission
grant statements, in particular, support wildcards. I think the default policy is
pretty decent---the defaults are aimed at a standard "internal wiki" use
One might think that an administrator could limit anonymous access by removing
the "AnonymousLoginModule SUFFICIENT" line from jspwiki.jaas. That's a
very good guess, but not quite correct. The right way to do it would be to edit
jspwiki.policy and look for this grant entry:
grant signedBy "jspwiki" principal com.ecyrd.jspwiki.auth.authorize.Role
"Anonymous" {
You'd edit this line:
permission com.ecyrd.jspwiki.auth.permissions.PagePermission "*",
"view,comment"; reflect that users should be able to see the "Oops! You need to register!"
wiki page, and probably a few others, but nothing else. That's something we will
tweak as development on JSPWiki continues... feedback would be much appreciated.
Likewise, if you wanted to limit the capabilities of "asserted" users
(as I would in a production environment), you could simply remove the block for
asserted users, e.g.,:
grant signedBy "jspwiki" principal com.ecyrd.jspwiki.auth.authorize.Role
"Asserted" {...};
An important limitation (for the moment) in the security policy implementation is
that the policy grammar (PagePermission/WikiPermission) doesn't yet support multiple
wikis---you could get around this by having separate policy files per wiki if you
wanted. This isn't as big of a limitation as you might think---the default policies
for all wikis on a server are likely to be the same: i.e., anonymous users either
can/cannot self-register, create new pages or groups, etc. So you will probably
just need one policy file.
!Groups and Authorizers
Recall that the authorization algorithm checks for the presence of built-in role
Principals or user Principals when making decisions. It also can make decisions
based on wiki group membership or membership in a role as determined by an external
Authorizer. The external authorizer has priority. The default Authorizer (WebContainerAuthorizer)
delegates to the web container via the HttpRequest's isUserInRole(String) method.
There's a documented interface, so you could easily add your own implementation
such as an RDBMS authorizer. If you use your own Authorizer, you'd need to specify
the implementation class in
Group membership is much more ad hoc---these are groups that JSPWiki users create
themselves. The default implementation reads membership lists from WikiPages with
the prefix "Group." Janne and I have discussed doing this using other
methods such as sub-pages, but for now they're just plain wiki pages. The wiki markup
"[{SET members='Foo, Bar'}]" enumerates the members. Again,
you are free to use your own GroupManager implementation.
!Access Control Lists
The Java security policy for JSPWiki applies to all pages that don't have an ACL.
But ACLs are often required to refine (usually, reduce) the privileges for particular
pages. Here's the wiki markup syntax---it's just like earlier versions of JSPWiki:
[{ALLOW view Janne,Mike Morris}]
This allows Janne and Mike to view the page, but nobody else can view it. Note that
if this was the *only* ACL entry for the page, only ADMIN would be able to edit
it! Thus, I've implemented JSP logic so when pages are created, the ACL is "pre-populated"
with the current user's name.
Note: there is no support for "deny" access control entries. That's a
deliberate, philosophical choice---it's far easier to deny by default than to worry
about whether the grants or denies take precedence. The code's much cleaner too.
That said, there's nothing in the design that precludes "deny" ACL entries.
The consensus we got during the requirements phase was that this was a wish-list
item, but not critical for the next release.
At present, to use the new AAA scheme you need to specify the location of the JSPWiki
security policy (jspwiki.policy) and JAAS login configuration file (jspwiki.jaas).
Janne's recent e-mails were on this subject.
To make the security policy active, you will need to specify its location by setting
the JVM system property '' in the command line script you use
to start your web container. The file location should be the absolute path to the
jspwiki.policy file. For example:
java -jar myservletcontainer.jar
Some servlet containers make this very easy by looking for an environment variable
and automatically appending the contents to the 'java' command. For example, Tomcat
users just need to set the CATALINA_OPTS variable:
The system property for the JAAS login configuration works the same way, except
the property is called "". In security-conscious
environments you will probably want to store jspwiki.policy and jspwiki.jaas in
the Tomcat config directory (CATALINA_HOME/conf).
Short-term development will likely focus on making the AAA configuration easier,
so that a decent default policy & login configuration are loaded "by default"
from WEB-INF... thus preserving the "it just works" quality of JSPWiki.
This page has been [moved to the official documentation wiki |].
Version Date Modified Size Author Changes ... Change note
111 23-Jul-2009 09:30 0.118 kB StefanBohn to previous
110 10-Nov-2007 02:33 0.107 kB to previous | to last
109 10-Nov-2007 02:31 0.122 kB to previous | to last
108 06-Nov-2007 21:16 0.107 kB JanneJalkanen to previous | to last
107 06-Nov-2007 21:12 0.121 kB to previous | to last
106 26-Sep-2007 23:28 0.107 kB JanneJalkanen to previous | to last
105 26-Sep-2007 02:32 0.145 kB to previous | to last
104 26-Sep-2007 02:30 0.132 kB to previous | to last
103 25-Sep-2007 19:36 0.12 kB to previous | to last
102 22-Aug-2007 14:59 0.107 kB JanneJalkanen to previous | to last
101 22-Aug-2007 11:56 0.104 kB to previous | to last
« This page (revision-111) was last changed on 23-Jul-2009 09:30 by StefanBohn