With version 2.2, Jetspeed introduces a new security framework. The 2.2 security is based on an security association engine, enable you to introduce your own security components and build associations with other existing or new security components.
Jetspeed supports Subject-based security as defined by JAAS (Java Authentication and Authorization Services). A subject is an aggregation of security information for a security entity, like a person. A subject can have several identities, also called principals. For example, a user logging into a Jetspeed portal is associated with one Subject, which contains a user principal, zero or more role principals, zero or more group principals, etc. Each principal can be associated with a set of permissions that allow the user to perform certain actions, like accessing a page, updating secured objects, etc. Finally, user principals in Jetspeed can be associated with a credential. A credential is, simply put, a username / password combination.
All the security identity information above is managed by the Jetspeed Security Component. The Jetspeed Security Component provides a mechanism to access and update principal, credential and permission data. When a user is authenticated in Jetspeed, a user principal is resolved for that user, based on the credentials that the user provided on login. A user principal can then be associated with several other principals, which can be of the same (user principal) or different type (e.g. role, group, ..). Principals are resolved in a nested manner, which means that each principal that is associated with the user principal can also be associated with other principals, which can in turn be associated with other principals, etc. The final collection of principals found in this way is aggregated and attached to the Subject that is resolved for the authenticated user. The Subject is used throughout Jetspeed for security purposes and can also be used by portlet applications to secure custom objects using standard JAAS API.
Every project usually requires different security models, with meaningful relations between security principals that make sense for that project. Most projects can get away with using standard principal types like users, roles and groups, with regular associations between those principal types, like a user being a member of a role or group, a group being a member of a role, etc. There are also projects however, which go beyond that and require new principal types and custom associations between principal types. These projects create the need for a pluggable security architecture where new principal types and principal associations can be added easily. This is exactly what the Jetspeed Security Component provides. This is best explained by illustrating a custom security model, where a user is related to an organization. Jetspeed contains built-in support for users, groups and roles and associations between those, but not for organizations and associations between users and organizations. To achieve that though, the following changes can be made to plugin organizations:
The OrganizationManager is a strongly typed manager with methods for accessing and storing organizations. The BaseJetspeedPrincipalManager class however, is a weakly typed manager, which only operates on abstract principals. This means that for the most part, the OrganizationManager class can delegate back to the base class, except for some specific organization handling and typecasting abstract principals back to organization instances.
Configuring an association between users and organizations is in this case very simple, because an "isMemberOf" association handler is provided by default by Jetspeed. Configuring it is a matter of specifying a new instance of that handler and wiring it to both the UserManager and the OrganizationManager. The custom security model setup is depicted in Figure 1. Figure 1: Extending the security model with organizations
A Jetspeed principal is basically nothing more than a set of security attributes describing the principal. The attributes are custom and can differ per project. A user principal for example, can have contact information attributes. An organization principal (from the example above) can have geographical coordinates of the office as an attribute. The set of allowed attributes can be configured through Spring for each principal type. Besides the attributes, a principal also has several constraints in its usage and access that can be configured, such as whether the principal is read-only, can be removed, is enabled, etc.
A principal association is a relation between two principals, where the relation always has a direction: it goes from one principal to another. For example, in the relation "user is part of a group", the user is the starting point of the relation (the from principal) and the group is the ending point of the relation (the to principal). The naming convention using "to" and "from" is used in the Jetspeed Security API. An example is a method in the JetspeedPrincipalManager interface called getAssociatedTo(..), which fetches a list of associated principals given the name of a principal representing the "to" side of the association, and given the type of association. The list of principals returned represent the "from" principals in the association. Associations have several characteristics, that influence the creation and deletion of the principals in the association, or affect the way associations can be made between principals. The following list contains an overview of these characteristics:
|required||the "from" principal cannot be created without this association|
|dependent||the "from" principal will be deleted when the "to" principal is deleted|
|singular||the "from" principal can be associated from at most once|
|dominant||the "to" principal can be associated to at most once|
All these characteristics are configured for an association through Spring.
The built-in implementations of associations by Jetspeed are (and should be) independent of specific principal types. The advantage of that is that associations are pluggable and can be re-used between different pairs of principal types.
The storage engine of the Jetspeed Security Component uses a database to store and retrieve security data. By only allowing one type of data store, the storage and retrieval methods used internally by Jetspeed can be optimized and fine-tuned. An additional advantage is that more complex queries on security data are possible, which would be difficult to achieve if the storage engine was abstracted in such a way that any data store could be supported.
If the security model in Jetspeed is extended with new principals and/or associations, nothing has to be changed in database scripts or other code related to database. Jetspeed's generic storage engine will take care of storing and retrieving data. Although the storage engine works on top of a database internally, you have the possibility to synchronize data from another datastore. This will be discussed in the next section.
Security data can be synchronized from an external data store, and mapped to the database used internally by Jetspeed. Currently, LDAP is the only type of external data store supported by Jetspeed. LDAP data can be synchronized periodically, on startup or on authentication of a user. When synchronizing on authentication of a user, only the data related to that user is synchronized. Replication refers to writing back security data to the external store whenever security data in the database is updated. Synchronization is a mechanism which ensures that the contents of the external data store are the same as the internal database, where the external datastore has the highest priority. LDAP synchronization and replication is discussed in more detail in the LDAP Mapping guide.