This is version . It is not the current version, and thus it cannot be edited.
[Back to current version]   [Restore this version]

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

And if this isn't enough, lets maintain a Authorization And Authentication 2.3 FAQ as well.


JSPWiki supports multiple levels of authentication and trust. Users can be anonymous, have "asserted" identities using cookies, be authenticated, or be administrators:
Status Description Left Menu Shows..
Anonymous User not logged in, and has not supplied a cookie "You are anonymous"
Asserted User's browser contains a cookie called JSPWikiAssertedName "G'Day, username (not logged in)"
Authenticated User logged in with a login id and password "G'Day, username (authenticated)"
Admin User logged in with a login id and password, and this id has been pre-designated as the Admin user "G'Day, username (authenticated)

Depending on the default security policy and page access controls in place, users may (or may not) be required to authenticate.

When a user decides to log in--or is challenged to do so by a page access control or security policy--he or she sees a standard web form with a username field and a masked password field. After receiving the submitted web form, JSPWiki attempts to log the user in via either of these methods:

  • Custom authentication, which looks up and validates the user's id and password against those stored in JSPWiki's UserDatabase
  • Container authentication, which relies on the servlet container to perform the authentication and supply credentials

JSPWiki is smart enough to detect which authentication method is in force. If certain <security-contraint> elements in web.xml are uncommented, container authentication is used. If not, JSPWiki uses custom authentication. In both cases, the user experience is identical.

User Registration and Preferences#


Although some wikis are anonymous, many are not. Often, wikis give users the ability to create an identity for the website. JSPWiki includes a basic self-registration page that allows users to set up and manage their own wiki profiles.

To set up a wiki profile, users click on a link on the front page that opens the Register.jsp page. By default, the form asks for:

  • A user ID
  • The user's desired "wiki name" (e.g., JanneJalkanen)
  • The user's full name (first and last name)
  • A password
  • E-mail address
If container-managed authentication is in force, the user ID will not be editable; the container will supply this value.

When the user saves the profile, JSPWiki checks to make sure that the new user id, wiki name and full name aren't already used by someone else. If so, the user is given the opportunity to choose different values.

User Profiles#

After a user is registered, he or she may edit the wiki profile at a later date via the Edit your profile link on the front page. By default, users must be authenticated to edit their own profiles.

User Database#

When users save their profiles, they are persisted to a permanent storage area called a UserDatabase. By default, profiles are saved to an XML file called userdatabase.xml in the WEB-INF directory. Each user profile is a separate <user> entry. Passwords are hashed using SHA-1.

Access Control#

JSPWiki is a wiki. Wikis foster openness and collaboration. By default, JSPWiki allows all users to view, create and edit all wiki pages. However, in many cases users will want to restrict access to particular pages. Access control lists, or ACLs, allow users to refine (usually, restrict) the privileges for particular pages. ACLs specify which users, Roles and wiki groups are allowed to perform particular actions.


JSPWiki implements role-based security through the use of a class called a Role. Out of the box, JSPWiki defines five roles, which correspond to the user authentication status:
  • Anonymous
  • Asserted
  • Authenticated
  • Admin
  • All
The "All" role is special; it means "anybody, regardless of authentication status."

In addition to these built-in Roles, JSPWiki also recognizes Roles that are supplied by external authorizers such as the servlet container.

Wiki Groups#

Role-based security sounds terrific, but in practice it can be problematic for wikis. That's because traditional role-based access controls often assume that everything is configured by an administrator. This creates a support bottleneck, and a barrier to adoption.

To make role-based access controls more flexible, JSPWiki allows users to create wiki groups. These are a special roles that users create themselves. Users create wiki groups by clicking on the front page link Create a new group. The JSP NewGroup.jsp opens. The user gives the group a name and enumerates its members. The "save" button creates a new wiki page with the prefix "Group" that contains the membership list. By defaut, any member listed in the group member list can edit the group.

Roles and wiki groups (in conjunction with page access controls) are used to lock down a wiki. We discuss access controls next.

Access Control Lists#

Access control lists, or ACLs, allow users to refine (usually, reduce) the privileges for particular pages. An ACL is simply special wiki markup that defines who should be able to perform what actions on a particular page.
  • Who: User WikiNames or full names can be used; either will work just fine. Built-in Roles and wiki groups work, too.
  • What: Valid permissions include "view", "edit", "comment", "rename" and "delete".
The syntax is ALLOW permission userOrRole1, userOrRole2, userOrRole3, enclosed in [{ }] brackets.

For example, suppose you've just created a confidential page that only users Janne and Mike Morris should be able to view. Just add this to the top of the wiki page markup:

[{ALLOW view Janne,Mike Morris}]

This allows Janne and Mike to view the page, but nobody else can view it. Note that this particular ACL does not contain any "edit" privileges. If you wanted Janne to be able to edit the page as well, you would add this line:

[{ALLOW edit Janne}]

Access control lists can contain entries for roles and wiki groups. Suppose we wanted to broaden access to the wiki page so that all authenticated users could view the page, and all members of the wiki group "Managers" could edit it:

[{ALLOW view Janne,Mike Morris,Authenticated}]
[{ALLOW edit Janne,Managers}]

Roles, wiki groups and user/wiki names can sometimes have the same names. For security reasons, built-in Roles and container-defined Roles always take priority over wiki groups with the same name. Likewise, wiki groups override user names or wiki names. Thus, although it's technically possible to register a new user with the name "Authenticated", they won't magically receive access to everything that the role Authenticated is entitled to.

Note: there is no support for "deny" access control entries. That is a deliberate, philosophical design choice---it is far easier to deny by default than to worry about whether grants or denies take precedence.

By default, wiki pages do not have access control lists. When a page doesn't have an ACL, the default security policy for the page applies. We discuss security policy next.

Security Policies#

JSPWiki decides whether to allow an action by consulting two sources of information:
  • Page access control lists - per-page markup defining access restrictions (discussed in the previous section)
  • Security policy - a pre-defined set of privileges for each type of user
To make it easy for users to quickly get productive, JSPWiki ships with a fairly loose default policy out of the box:

Permission Anonymous users Asserted users (with cookie) Authenticated users Administrator
View all pages* x x x x
Edit all pages* x x x x
Upload attachments to all pages* x x x x
Comment on all existing pages* x x x x
Create new pages* x x x x
View all groups x x x
Create new groups x x
Rename all pages* x x
Delete all pages* x
Register as new user x x x x
Edit user preferences x x
(*)except group pages or pages with existing ACLs

JSPWiki uses the standard Java 2 security policy APIs under the covers. Default permissions are granted using standard security policy file syntax. When JSPWiki starts up, it loads the default policy file (stored in WEB-INF/jspwiki.policy).

JSPWiki's default policy is suitable for a small team. It is probably too loose for a corporate intranet or public wiki. See the next section, Modifying the Default Security Policy for details on how to tighten the policy, or for information on running JSPWiki with an existing security policy.

Customizing JSPWiki Security#

Modifying the Default Security Policy#

How the Security Policy Works#

JSPWiki's security policy system is based on Java 2 policy APIs. The default policy file, stored in WEB-INF/jspwiki.policy, expresses what the page permissions of the wiki should be when the user hasn't supplied a page ACL. The policy also governs what other non-page-related actions users are allowed to take, such as registering user profiles and creating groups.

The jspwiki.policy file is a standard Java policy file, so if you are familiar with the syntax it should be easy to understand. The default policy is aimed at a standard "workgroup wiki" use case. Policy blocks typically grant two types of permissions, PagePermission and WikiPermission to users having a particular Role:

  • PagePermission is an action on a particular page or set of pages: view, edit, comment, rename, upload, delete. PagePermission supports wildcards.
  • WikiPermission is an action that is wiki-wide: createPages, createGroups, registerUser, editPreferences

Here's an example "grant" block from the default policy file.

grant signedBy "jspwiki" 
  principal com.ecyrd.jspwiki.auth.authorize.Role "Anonymous" {
    permission com.ecyrd.jspwiki.auth.permissions.PagePermission "*", "view";
    permission com.ecyrd.jspwiki.auth.permissions.PagePermission "*", "edit";
    permission com.ecyrd.jspwiki.auth.permissions.WikiPermission "createPages";
    permission com.ecyrd.jspwiki.auth.permissions.WikiPermission "registerUser";

This policy block grants a fairly wide set of privileges to anonymous users. Users can view and edit any page that doesn't have an ACL, and can create new pages and self-register. But this policy can be customized as needed. For example, let's cut this down a bit so that anonymous users can't edit existing pages or create new ones---we'd like them to register first (and authenticate) before allowing them to do these things. Here's what the revised policy block would look like:

grant signedBy "jspwiki" 
  principal com.ecyrd.jspwiki.auth.authorize.Role "Anonymous" {
    permission com.ecyrd.jspwiki.auth.permissions.PagePermission "*", "view";
    permission com.ecyrd.jspwiki.auth.permissions.WikiPermission "registerUser";

But suppose even this isn't strict enough; perhaps users should only be able to read the front page, and nothing else. Here's a policy block that would accomplish that goal:

grant signedBy "jspwiki" 
  principal com.ecyrd.jspwiki.auth.authorize.Role "Anonymous" {
    permission com.ecyrd.jspwiki.auth.permissions.PagePermission "Main", "view";
    permission com.ecyrd.jspwiki.auth.permissions.WikiPermission "registerUser";

Note: the signedBy "jspwiki" section of the "grant" block ensures that calling code is signed and trusted. If you customize the default policy, we highly recommend that you include this statement in all "grant" blocks.


The policy syntax for PagePermission accepts wildcards as a prefix or suffix to a page target. This keeps policy blocks nice and concise. For example, a page target of "Main*" applies to pages "MainPage", "MainStreet" and "MainWelcome". The wildcard "*" means all pages in the wiki other than group pages. Group pages have a page prefix of "Group" and are used to define wiki groups. You must explicitly grant permissions for a Group page or collection of Group pages, e.g.:
permission com.ecyrd.jspwiki.auth.permissions.PagePermission "GroupManagers", "edit";
permission com.ecyrd.jspwiki.auth.permissions.PagePermission "Group*", "edit";

Implied Permissions#

Certain permissions imply others:

Specifying Principals in Policy Blocks#

As noted previously, each "grant" block in the policy file grants privileges to a particular role. The role is specified with the principal type "principalName" portion of the grant statement. The type can be any class that implements the interface; for standard JSPWiki roles this Principal type is com.ecyrd.jspwiki.auth.authorize.Role. The principal name can be any value that is returned by the Principal type's getName() method. In the case of Role, JSPWiki contains these standard names:
  • "Anonymous"
  • "Asserted"
  • "Authenticated"
  • "Admin"
  • "All"
You can also use user-specfied Role names with certain external Authorizer implenentations, such as WebContainerAuthorizer. You can grant privileges to container-managed roles by specifying a Principal type of Role, with the name of the role as the target. For example: suppose JSPWiki is configured to use container-managed authentication, and that the container knows about an externally-defined role called "SystemAdministrator". You would grant privileges using this principal:
principal com.ecyrd.jspwiki.auth.authorize.Role "SystemAdministrator"

You are not restricted to using Principals of type Role, however. You can also specify wiki Groups or any other type of Principal. For example, suppose one of your wiki pages defines an arbitrary wiki group called "Managers". You'd like this group to be able to manage all group membership lists and to delete or rename pages, just like an administrator could. Here's a policy block that accomplishes that goal:

grant signedBy "jspwiki" 
  principal com.ecyrd.jspwiki.auth.authorize.Group "Managers" {
    permission com.ecyrd.jspwiki.auth.permissions.PagePermission "*", "edit,rename,delete";
    permission com.ecyrd.jspwiki.auth.permissions.PagePermission "Group*", "edit";

The possibilities are endless. That said, it's wise not to go too crazy with the policy file---they should be as simple as possible, but no simpler.

Implementing Custom Policies#

At startup time, JSPWiki looks to see if the user has previously specified a JVM-wide security policy by checking to see if the system property was set. In most cases, a custom security policy has not been loaded, so JSPWiki will load the default policy from WEB-INF/jspwiki.policy.

However, in some cases adminstrators would like to use their own Java security policies, or would like to customize the JSPWiiki default policy. In these cases, you should set 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, or whatever you've decided to call it. 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:

In security-conscious environments you should store jspwiki.policy in a directory far away from JSPWiki, for example in $CATALINA_HOME/conf.

Note: JSPWiki defines custom security Permission classes. In order for the JVM to use these classes to make security policy decisions, the jspwiki.jar file is signed with a self-issued digital certificate with the alias jspwiki. The keystore jspwiki.jks that contains this certificate should be present in the same directory as the policy file, which by default is /WEB-INF. If you build JSPWiki from source, the Ant build script will offer to generate a certificate and keystore for you. If the JSPWiki security policy file cannot figure out how to find its associated keystore, JSPWiki will absolutely, positively stop working. Therefore, it is critical that the jspwiki.jks keystore be present in the same directory as your security policy file._

Customizing the Authentication Process#

How Authentication Works#

JSPWiki uses the Java Authentication and Authorization Service (JAAS) to log users in and out of the wiki. JAAS is conceptually very similar to PAM, which is a "stackable" authentication framework for Linux, Solaris and other operating systems.

Under the covers, JSPWiki tracks each user throughout its lifecycle using an object called a WikiSession. The WikiSession is analogous to (and associated with) the HttpSession. As the user progresses from anonymity to asserted status, then to authenticated status, the WikiSession object stays constant, but the series of credentials associated with his or her login status changes.

In particular, each user's WikiSession contains a standard J2SE Subject with a collection of Principals. The Principals can be one of two types:

  1. User Principals, which represent one or more user credentials, as supplied by the custom or container JAAS LoginModules
  2. Built-in Role Principals, which represents the logical Role objects "admin", "authenticated","anonymous", "asserted" and "all"

So, how do the Principals get there? Easy--JAAS. Recall that JSPWiki can use either container-managed auth, or its own custom authentication scheme. The default authentication "stack" works slightly differently in each case:

  1. Container-managed authentication. The WebContainerLoginModule first tries to "log in" by sniffing 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 (perhaps because the user hasn't had to log in yet), 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". If the other modules fail, the AnonymousLoginModule that runs last always succeeds.
  2. Custom Authentication. In this case, the UserDatabaseLoginModule takes data submitted on the login form (Login.jsp) and authenticates against the configured UserDatabase. The default database persists to an XML file. 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" and "authenticated".

This process described is invisible to the user, and happens behind the scenes. What's important to remember is that WikiSession will always have a Subject containing some built-in roles that we can use for authorization purposes. Specifically, WikiSession's Subject will always possess at least one user Principal that represents the user's identity, plus at least two built-in Role Principals: "all" plus either "anonymous", "asserted" or "authenticated".

Customizing JSPWiki's JAAS Configuration#

These default login process should be quite sufficient. However, because JSPWiki uses JAAS, you can configure the login process however you like. Here's the default jspwiki.jaas file, loaded by default from the WEB-INF directory:
JSPWiki-container {
  com.ecyrd.jspwiki.auth.login.WebContainerLoginModule    SUFFICIENT;
  com.ecyrd.jspwiki.auth.login.CookieAssertionLoginModule SUFFICIENT;
  com.ecyrd.jspwiki.auth.login.AnonymousLoginModule       SUFFICIENT;

JSPWiki-custom {
  com.ecyrd.jspwiki.auth.login.UserDatabaseLoginModule    REQUIRED;

The first block (JSPWiki-Container) shows how the authentication process is invoked during WikiContext creation. If the user isn't authenticated already, the configuration tells JSPWiki to try the logging the user in using WebContainerLoginModule, CookieAssertionLoginModule, and AnonymousLoginModule, in order. The first module to succeed will be the one that populates the WikiSession's Subject with Principal credentials. Changing this block modifies the default behavior. For example, removing the CookieAssertionLoginModule prevents users from asserting their identities with browser cookies. You should not remove the AnonymousLoginModule line; this guarantees that unauthenticated sessions will posesss (at least) the "anonymous" credential. Also, if you are using container-managed authentication, you should keep the WebContainerLoginModule line. (And even if you aren't, there's no harm in keeping it there because it will just no-op.)

The second block (JSP-custom) specifies that JSPWiki should use the UserDatabase for custom authentication. You can easily replace this with any JAAS LoginModule implementation, if you wish. For example, the Sun JDK ships with a Kerberos LoginModule and a native OS LoginModule (Unix JDK distributions use PAM; the Windows version uses the local SAM).

If you customize the JAAS configuration, you should save the new configuration in a separate file. You can (and should!) tell JSPWiki where this file is by setting the JVM system property to the absolute path of the file:

java -jar myservletcontainer.jar

Similar to configuration of custom security policies, your web container may have a recommended way of setting the JAAS property at startup. Tomcat makes it very easy; just append the system property to CATALINA_OPTS:


In security-conscious environments you should store jspwiki.jaas in a directory far away from JSPWiki, for example $CATALINA_HOME/conf.

Note: if your web container is running additional applications that use JAAS, you should append the contents of your revised jspwiki.jaas configuration into your existing JAAS configuration file.

Integrating JSPWiki with Container-Managed Authentication#

By default, JSPWiki logs in users via custom authentication. That is, it validates the username and password against those stored in the configured UserDatabase. However, many corporations prefer to use container-managed authentication. This allows JSPWiki to use credentials obtained from the web container realm. Depending on the container's realm configuration, this sharply expands the range of authentication mechanisms available to JSPWiki. Many containers support LDAP, database, Kerberos, SecurID, Shibboleth, SAML and NT domain controller authentication among others.

Configuring JSPWiki to rely on container-managed authentication is simple. First, configure your web container to use a security realm for the JSPWiki webapp. For example, in Tomcat, the <realm> element configures container-managed authentication for particular webapps (or for the container as a whole). Here's a sample MySQL realm configuration:

      <Realm  className="org.apache.catalina.realm.JDBCRealm"
         connectionName="test" connectionPassword="test"
              userTable="users" userNameCol="user_name" userCredCol="user_pass"
          userRoleTable="user_roles" roleNameCol="role_name" />

Other containers (WebSphere, WebLogic, JBoss, et al) configure realms differently, but the principles are the same.

After configuring the security realm for the JSPWiki webapp, enable container authentication by uncommenting these <security-constraint> elements in WEB-INF/web.xml:

           <web-resource-name>Protected Area</web-resource-name>


       This logical role includes all authenticated users

       This logical role includes all administrative users
When JSPWiki starts up, it parses the JSPWiki's web application descriptor (WEB-INF/web.xml) and identifies whether certain constraints exist. Specifically, it checks to see if the logical role "Authenticated" is required to access /Delete.jsp, /UserPreferences.jsp and LoginRedirect.jsp. If you have uncommented the <security-constraint> block, this will be true, and JSPWiki will conclude that is should use container authentication instead of custom.

By the way, the default container-managed security constraints in web.xml will force users to log in when they try to edit a page, upload a file, comment on a page, create a new group, or edit their user profiles. This supplements, and is slightly stricter than, the default security policy. It should be sufficient for most corporate intranets and public wikis. You can tweak the constraints if you wish, although you must retain the constraint for LoginRedirect.jsp for the "Log in" link on the menu bar to work correctly.

Customizing the User Database#

Out of the box, JSPWiki uses a standard UserDatabase implementation com.ecyrd.jspwiki.auth.user.XMLUserDatabase for loading and persisting user profiles. This implementation is good enough for workgroups and small-scale public wikis. By default, JSPWiki looks for a file called userdatabase.xml in WEB-INF/web.xml. You can (and should) specify a permanent location for this file by editing the jspwiki.xmlUserDatabaseFile property in The location should be outside of the JSPWiki webapp directory, ideally in a place like /etc.

In addition to the default XML implementation, you can write your own alternative implementation that relies on, for example, LDAP or a relational database for persistent storage. The interface com.ecyrd.jspwiki.user.UserDatabase defines standard methods for finding, loading and saving user profiles. If you use your own UserDatabase, you need to specify the implementation class in

jspwiki.userdatabase =

Customizing the Authorization Process#

How Authorization Works#

Internally, the JSP authorization algorithm 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 possess Role "anonymous", thus even these users can be subjected to authorization checks.

What constitutes a request for access? Any action requiring a Permission, such as 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. Before executing the action, the calling JSP or Java code asks JSPWiki for authorization by calling AuthorizationManager's checkPermission method. As a parameter to this method, the calling code passes a Permission object that 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 checks whether the Permission was granted to the Subject associated with the WikiSession. The Permission-checking algorithm works as follows:

  • If the Subject's Principal set includes the Role Principal that represents the administrator group ("administrator"), the Permission is always allowed. By definition, administrators can do anything.
  • If the Permission is not a PagePermission, or if it is but its associated page has no ACL, we check to see if the Permission is allowed according to the default security policy
  • For pages with ACLs, we retrieve the list of Principals assigned this permission in the ACL: these will be Principals representing a Role, wiki group or user. Then, we determine whether the Subject is considered to have any of these Roles or Principals. That process is as follows:
    • If the Principal in the ACL is a built-in Role, the algorithm simply checks to see if the Subject possesses it in its Principal set
    • If the Principal in the ACL is a Role but not built-in, the external Authorizer's isInRole method is called
    • If the Principal in the ACLl is a wiki Group, the GroupManager's group authorizer isInRole method is called
    • If the Principal in the ACL is a user, check whether the Subject possesses it in its Principal set
  • Otherwise, deny the permission

In short, this algorithm provides a way to use built-in roles ("authenticated", "all" etc) in 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 those too.

Consulting External 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 Authorizer interface (com.ecyrd.jspwiki.auth.Authorizer) provides a standard set of methods for querying an external authorizer. You can easily create your own implementation class that consults an RDBMS authorizer or LDAP. If you use your own Authorizer, you need to specify the implementation class in

jspwiki.authorizer =

JSPWiki's default Authorizer is com.ecyrd.jspwiki.auth.authorize.WebContainerAuthorizer, which delegates to the web container via the HttpRequest's isUserInRole(String) method.

The GroupManager interface (com.ecyrd.jspwiki.auth.authorize.GroupManager) extents Authorizer, and defines additional methods for loading, saving and querying group member lists.The default implementation (com.ecyrd.jspwiki.auth.authorize.DefaultGroupManager) reads membership lists from WikiPages that have the prefix "Group". You are free to create your own GroupManager implementation. If you do, you need to specify the implementation class in

jspwiki.groupManager =

What's the difference between and Authorizer and a GroupManager? They perform similar functions, in the sense that they both authorize actions based on whether or not users possesses a particular roles. The difference is that GroupManager is explicitly designed for wiki group storage: it loads, saves and manages discretionary roles that users create themselves. An Authorizer, on the other hand, is generally a back-end service provided by infrastructure under control of IT administrators. The external Authorizer does not provide the ability to create new roles; only the ability to determine whether users are members of the ones that have already been defined. We wanted to keep the boundaries between these two authorization methods clear.

The benefit of this approach is that it provides a lot of flexibilty. For the default, out-of-the box configuration, it means we can use a GroupManager plus an external Authorizer that takes advantage of the web container's authorization APIs.

Add new attachment

Only authorized users are allowed to upload new attachments.
« This particular version was published on 06-Sep-2005 16:48 by AndrewJaquith.