uPortal Authorization System
2.0 Design
Proposal
Author: Bernie Durfee
Design: Alex Vigdor, Bernie Durfee, Dan Ellentuck, Don Fracapane
This document outlines the design of a new permission based authorization system. The goal is for this system to be combined with a group management system and to replace the existing uPortal authorization service. The initial version of uPortal authorization was based on the storage and manipulation of simple role information. Below is the original API:
public interface IAuthorization
{
public boolean isUserInRole(IPerson person, IRole role);
public Vector getAllRoles();
public int
setChannelRoles(int channelID, Vector roles);
public boolean canUserPublish(IPerson person);
public Vector
getAuthorizedChannels(IPerson person);
public boolean canUserSubscribe(IPerson person, int channelID);
public boolean canUserRender(IPerson person, int channelID);
public Vector
getUserRoles(IPerson person);
public void
addUserRoles(IPerson person, Vector roles);
public void
removeUserRoles(IPerson person, Vector roles);
}
The problem with this API is that it mixes role management
functionality with authorization functionality. “Can principal X perform activity Y on target Z” is
commonly used to define the authorization. In the old API, this question is only answered by the
following methods:
public boolean canUserPublish(IPerson
person);
public Vector getAuthorizedChannels(IPerson person);
public boolean canUserSubscribe(IPerson
person, int channelID);
public boolean canUserRender(IPerson
person, int channelID);
While the remaining methods deal with role management:
public boolean isUserInRole(IPerson
person, IRole role);
public Vector getAllRoles();
public int setChannelRoles(int channelID, Vector roles);
public Vector getUserRoles(IPerson person);
public void addUserRoles(IPerson person, Vector roles);
public void removeUserRoles(IPerson person, Vector roles);
After some discussions at Columbia University it has become evident that splitting up these two sets of methods would benefit the overall design of the authorization system. In doing so, a very simple and yet powerful system emerges. The former set of methods can be represented by a generic authorization system and the latter set of methods need to be incorporated into a group/role management system. This document proposes a solution for a generic authorization system.
The new authorization system would be based on an API that would be available and useful to both the framework and channels. Its API is based on answering the “Can principal X perform activity Y on target Z” question. The API for the new authorization system consists of the following methods:
public abstract class PermissionManager
{
// Store the name of the owner of this instance
protected String m_owner = null;
// Constructor that makes sure that an owner
// is bound to each instance of a PermissionManager
public PermissionManager(String owner)
{
m_owner = owner;
}
// This method adds a Permission object to the system
public void setPermission(Permission newPermission);
// This method adds a set of Permissions objects to the system
public void setPermissions(Permission [] new Permissions);
// This method retrieves a set of Permission objects based
// on the given parameters. Null parameters are ignored.
public Permission [] getPermissions( String
principal,
String activity,
String target )
}
This object represents a single permission in the system. This object contains the answer to a single “Can principal X perform activity Y on target Z” question. These permission objects can be bound to either the uPortal framework, a single channel or even shared among all uPortal entities.
public abstract class Permission
{
// Store the name of the owner of this instance
protected String m_owner = null;
// Constructor that makes sure each Permission has an owner
public Permission(String owner);
// Returns the owner of this Permission
public String getOwner();
// Getter and setter methods for Permission information
public String getPrincipal();
public void setPrincipal(String
principal);
public String getActivity();
public void setActivity(String
activity);
public String getTarget();
public void setTarget(String
target);
public String getType();
public void setType(String
type);
public Date getEffective();
public void setEffective(Date
effective);
public Date getExpires();
public void setExpires(Date
expires);
}
This is a token that describes who ‘owns’ the Permission. This token generally denotes the entity that created and uses the Permission. As a result this is most likely the only entity to which the Permission will have meaning.
An example of an owner would be a channel ID. The framework will create a PermissionManager object for each channel published in the system. This channel specific PermissionManager would only allow channels to create/read/modify Permission objects that they own. This will prevent channels from manipulating Permission objects that don’t belong to them.
These are tokens that make up the X, Y and Z in “Can principal X perform activity Y on target Z”. These tokens will most likely only have meaning in the context of the object that uses them.
These dates represent suggested effective and expires dates relate to the Permission. These tokens will most likely only have meaning in the context of the object that uses them.
This field is intended to specify the Permission type, such as GRANT or DENY.
.
As with most parts or uPortal the authorization system is based on the Factory design pattern. There will be an interface that can be implemented by any uPortal site to meet any specific needs. However, a solid reference implementation of this system is needed because this design is meant to meet the needs of most uPortal implementers. The reference implementation being proposed consists of the following parts:
The Permission objects will be stored persistently in a relational database. The schema for the database simply reflects the structure of the Permission objects themselves:
OWNER VARCHAR(255)
PRINCIPAL VARCHAR(255)
ACTIVITY VARCHAR(255)
TARGET VARCHAR(255)
EFFECTIVE TIMESTAMP
EXPIRES TIMESTAMP
A well performing authorization system is crucial due to the fact that it will be queried very often by many pieces of uPortal during use. An efficient and robust caching mechanism must be in place in order for any implementation to be viable. This caching can be done through the use of entity beans inside of an EJB server, but for the uPortal’s needs a custom solution is required.
This solution would most likely cache the Permission object as they are retrieved from the database. This cache would keep the objects alive for a specified period of time. After this time the cache would expunge the Permission so that it is retrieved from the database again. This would compensate for the fact that Permissions may change in the database, but should not change often enough to forgo the use of a cache.
From inside the CHeader channel you would…
// Get the IPerson object for the current user
String personID = staticData.getPerson().getID() + “”;
// Get the Permission manager object that has been
// created for the CHeader channel and stored in the
// StaticData object by the framework.
PermissionManager pm = staticData.getPermissionManager();
// Check to see if the current user has the Permission to publish.
// Ask the question, “Can principal (personID) publish?”
Permission [] permissions =
pm.getPermissions(personID,
“publish”, null);
…at this point the reference implementation would check for a row that
contained the person’s ID in the PRINCIPAL column and the string ‘Publish’ in
the ACTIVITY column. Permission objects would be built based on the results.
// Check to see if anything was returned
if(permissions != null && permissions.length > 0)
{
// Allow the user to publish
}
This is a very simple example. To make
better use of the system the framework could check the effective and expires
dates. Another option would be for the framework to render a publish link based
on who the current user can publish too. Each returned Permission object could
be checked for a target, these rows could exist…
OWNER PRINCIPAL ACTIVITY TARGET
chan01 english_prof Publish english_student
chan01 physics_prof Publish physics_student
chan01 administrator Publish NULL
…this would say that…
User’s in the english_prof group can publish to user’s in the
english_student group.
User’s in the physics_prof group can publish to the user’s in the
physics_student group.
User’s in the administration group can publish to anyone.
…each of the above
statements would be up to the interpretation of the CHeader channel. Group
information could be retrieve from a group management system. All rows in the
UP_PERMISSIONS table would be created by an administration tool, XML descriptor
file, etc.
As addressed above, creation of Permission objects needs to be carefully controlled. With the proliferation of channels written by third parties, uPortal implementers should be wary of inter-portal security. For instance, it’s possible that third part can write a channel that acts maliciously inside of the uPortal server. Allowing channels to create Permission objects with any owner field would allow for channels to add or modify the Permission objects owned by other channels.
The owner field of a Permission object should be used to effectively prevent channels from manipulating each others Permission objects. So a PermissionManager should be carefully implemented to only dole out Permission objects that belong to the requestor. Permission objects themselves should have an immutable owner field to make sure that they are stored properly.
It is the goal of uPortal to utilize as many standard Sun Java packages as possible. There will be debate as to why the standard Java security package is not utilized for Authorization. After much review it is the author’s opinion that this package was designed and written for code level authorization.
The components of uPortal are concerned with authorization on a higher level. Channels will use the authorization system to determine how to render their content. Try to fit code-level authorizations into this task does not seem reasonable.
The system described in this document is sufficiently simple and abstract as to provide high usefulness with little effort. It is also modeled after the standard Java packages to make migration to a future Java standard that fits the uPortal model better.