wamblee.org

Introduction

User management provides the interfaces to manage users and groups.

The current functionality is limited to administering users and groups. Self-registration of users is not (yet) implemented.

Requirements

  1. It shall be possible to add, remove, and modify users
  2. It shall be possible to add, remove, and modify groups.
  3. The design shall guarantee that a users is always part of at least one group.

Non-functional requirements

  1. The design shall scale to thousands of users and groups.
  2. User management shall provide one service interface through which all changes are finally made. It shall be impossible to bypass this interface and make changes to the user administration in any other way.
  3. The design shall be extendible to an implementation of user management as a remote service.
  4. It must be possible to integrate user management with that of an application server (at least JBoss)

Design

The design is centered around a simple domain model with users and groups and relations between them. In addition, there is one interface (facade) through which all changes to users and groups must be made. If a change is made to a user or group object, the change will only become visible after notifying user administration of the change through the interface. This approach also lends itself to an implementation where user administration is a remote service.

To avoid the creation of separate Data Transfer Objects for users and groups and to guarantee consistency through the user administration interface, the following approach is taken:

  • User and group objects have a package-scope constructor and must be created through the user administration interface
  • Relations between users and groups can only be changed through the user administration interface.
  • Users and groups may only be renamed through the user administration interface since a rename could violate constraints.
  • User administration always returns copies of users and groups and does not allow direct manipulation of users and groups through their interface. Instead, user and group objects obtained through the user administration interface may be modified but after that user administration must be notified of the change.

Integration with application server authentication is provided through persistent storage of the users and groups and their relations in a database. Based on this the integration in an application server can be configured.

Structure

Package Overview

The design consists of two packages, a usermgt package with standard interfaces and implementations that are usable in any environment and a usermgt.hibernate package that provides specific implementations for persistence with hibernate.

Package overview.

Model

The basic model is straightforward: a User can have relations with one or more Groups. Both objects implement AbstractPersistent to provide functionality for persistence. The User class guarantees that a user will always be part of at least one group. Both User and Group have package scope constructors and must be obtained through the user administration interface.

Basic model for users and groups.

Interface

The interface of user administration is defined by (surprisingly) UserAdministration. The interface provides methods for creating, removing, renaming, and looking up users and groups. It also provides operations for managing the relations between users and groups and for notifying user administration of changes to a user or group. This is required since user administration returns copies of users and groups.

User administration interface.

A straightforward implementation of user administration is to create an implementation of the user administration and map this to a database using Hibernate. Nevertheless, this design would depend heavily on the behavior of Hibernate for lazy loading in combination with, possibly large, numbers of objects. Therefore, we provide a lower level implementation whereby the implementation of user administration delegates to a UserSet and GroupSet respectively.

It is then the responsibility of UserAdministrationImpl to manage the rules governing consistency of the user administration and the UserSet and GroupSet simply manage storage of the users and groups.

Persistence

The UserSet and GroupSet interface both have an in-memory implementation and a Hibernate implementation. The Hibernate implementation is the one which will be used for actual deployments. The Hibernate implementation also uses caching at application level of users. This is done because user information is accessed frequently. Caching in Hibernate had a much lower performance (in tests it was 100 time slower) so that caching at application level is done instead.

Persistence of users and groups.

Accessing the currently logged in user

It is required to link together the security mechanism and user management to obtain a user object based on the currently logged in user. This functionality is defined by the UserAccessor. One implementation of this is the JaasUserAccessor which retrieves the user principal from JAAS (using the configured class of the user principal) and uses user administration to lookup the correct User object representing the user.

The user accessor.

Dynamics

A small number of sequence diagrams is used to illustrate how user management should be used and to describe the responsibilities of the involved objects. The sequence diagrams do not cover the full functionality of user management.

Adding a user

To add a new user, first a group must be obtained from the user administration. This is because a user must always be part of at least one group. After that, the user can be created with the basic properties of the user and with a reference to the group. The user administration then checks whether the user does not already exist and if so through a UsermgtException. Otherwise, the new user is created.

Adding a user.

Adding a user to a group

To add a user to a group, the user and group must first be obtained from the user administration interface. After that, addUserToGroup is used to add the user to a group. Again, user administration checks that the user and group are valid before actually adding the user to the group. Since adding a user to a group modifies the user, the UserSet must be notified of this change by calling userModified() with the modified user.

Adding a user to a group.

Changing the password of a user

To change the password of the user, the user must first be obtained from the user administration (not shown). Then, changePassword() must be called with both the old and new password as arguments. The password is then checked and if it is ok, the password is changed. Note that, for security reasons the interface of the user does not allow retrieval of the password.

Changing the password of a user.

Design Rules

To use user management effectively, the following rules should be followed:

  • After modifying a user or group, userModified() and groupModified() must be called on the user administration interface respectively.