UserAdmin Bundle

The UserAdmin Bundle of ProSyst mBS maintains a user database with specific user attributes. It supports authentication and authorization mechanisms so that bundles can filter the access to their confidential resources. The bundle implements the OSGi User Admin Service Specification.

Contents:


Bundle Information

Bundle JAR

The UserAdmin Bundle JAR file is useradm.jar, and is found in the bundles folder.

Import

All packages imported by the UserAdmin Bundle are exported by bundles from the Framework Professional Edition Package :

Package Exporter Description
com.prosyst.mbs.services.db DB Bundle Provides a persistent database for storing user account information. All users and their properties are stored in a database, called "useradmin", provided by this bundle.
com.prosyst.mbs.framework.event OSGi Library Bundle Provides a utility for using pooled events.
com.prosyst.util.hash System Bundle/
ProSyst Util Full Bundle
Contains the hashtable utility for associating numbers and objects.
com.prosyst.util.io Contains the I/O utilities of the ProSyst Util Bundle. The User Manager Bundle uses them for object serialization.
com.prosyst.util.ref ProSyst Util Bundle/
ProSyst Util Full Bundle
Contains the log utility in the ProSyst Util Bundle . The User Manager Bundle uses it to write log messages about its runtime status.
com.prosyst.util.security Holds the Access Controller that examines permissions and found in the ProSyst Util Bundle.
com.prosyst.util.timer Contains the Timer services for receiving time-based events.
org.osgi.service.event OSGi Library Bundle Contains the Event Admin service API whose management part is implemented by the Event Admin Bundle.
org.osgi.service.useradmin Contains the OSGi User Admin Service API components and is exported by the OSGi Library Bundle.
com.prosyst.util.tracker Contains the OSGi Service Tracker utility for enhanced tracking of services.

Export

The UserAdmin Bundle does not export any packages.


Overview

Conventionally, user administration encloses two mechanisms - authentication and authorization.

After successful authentication, the user is authorized to play certain roles within the system of the Service Gateway. Roles are two types - user and group.

The members of a group own a common role usually associated by the name of the group. Groups facilitate the authorization process. To provide access to its resources, a bundle can check if a user participates in a group that represents a certain role instead in a long list of authorized users. A user being a kind of role always implies itself.

For example: A bundle manages a specific database. It permits only administrators to the database components. The database administrative role is provided to a group called "dbAdmins" (the group name is user-defined). When a user requests to read a record in the database, the bundle checks if this user is member of "dbAdmins". If the user participates in this group, he could read the requested record. Otherwise, the bundle rejects access.

Every user that is registered in the UserAdmin Bundle owns a collection of properties and credentials. Public information about a user like a service preference is stored as a property. Private user information, such as a password, is treated as a credential.

The UserAdmin Bundle supports two types of members: basic and required. The initiator of the resource request should imply one or more basic members and all required members of a group. A group may contain zero or more basic and/or required members. Usually, the required term is applied for groups. If there are no basic members, a user.anyone member should be added to it, and then all initiators that fulfill the requirement to imply all required members, will get access.

For example: A user requests access to a resource and this access is granted only to the members of a particular group. If the group to examine contains only basic members, the user is authorized if at least one member implies it. Another case is if the group contains only required members, then the requester must participate in all of them. If both basic and required members present, the user must be registered in all required member groups and in at least one basic group.

User Admin Service

The User Admin service provides specific authentication and management of users. It is realized according to the OSGi User Admin Service API.

The User Admin service arranges users in groups and stores user attributes, such as name, properties and credentials in a database, called "useradmin". The service does not allow a user and a group to have one and the same name.

The User Admin service publishes the org.osgi.service.useradmin.UserAdmin interface. From this interface developers can retrieve the current user hierarchy and obtain access to the specific attributes of a user.

The main unit in the User Admin service is the org.osgi.service.useradmin.Role object. Generally, such an object represents a role that can be a user or a group. An org.osgi.service.useradmin.User object represents a user, and an org.osgi.service.useradmin.Group instance stands for a group.

The User Admin service restricts the access to user attributes, such as properties and credentials, by detecting the existence of an org.osgi.service.useradmin.UserAdminPermission with action that specifies the modification rights (in case framework security is on).

Credentials and properties of every user are stored in java.util.Dictionary objects. The keys in these objects are strings, and the values - strings or byte arrays. When assigning a new credential or property, a developer should comply with this format.

The example that follows creates a group called "mBServer" with two basic groups - "programmers" and "documentators". "programmers" contains the basic members "pascal_programmers" and "c_programmers" and the required member "java_programmers". "documentators" include the "designers" required member and "programmers" as a basic member. The following users are specified:

Next, the checkUsers method checks whether Peter owns the "documentators" and "programmers" roles.

           . . .
public class UserAdminTest implements BundleActivator {
  private ServiceReference userAdmRef;
  private UserAdmin userAdm;

  public void start(BundleContext bc) throws BundleException {
    userAdmRef = bc.getServiceReference(UserAdmin.class.getName());
    userAdm = (UserAdmin) bc.getService(userAdmRef);

    Group server = (Group)userAdm.createRole("mBServer", Role.GROUP);

    // Forming "programmers"
    Group programmers = (Group)userAdm.createRole("programmers", Role.GROUP);
    Group jProgr = (Group)userAdm.createRole("java_programmers", Role.GROUP);
    Group cProgr = (Group)userAdm.createRole("c_programmers", Role.GROUP);
    programmers.addRequiredMember(jProgr);
    programmers.addMember(cProgr);
           . . .

    // Adding a programmer
    User peter = (User)userAdm.createRole("Peter", Role.USER);
    jProgr.addMember(peter);
    cProgr.addMember(peter);
           . . .
 
    // Forming "documentators"
    Group documentators = (Group)userAdm.createRole("documentators", Role.GROUP);
    documentators.addMember(jProgr);
 
    // Specifying user properties
    Dictionary props = peter.getProperties();
    props.put("Position", "Department Manager".getBytes());
    Dictionary creds = peter.getCredentials();
    creds.put("password", peter.getName().getBytes());
           . . .

    // Adding all users to "mBServer"
    server.addMember(documentators);
    server.addMember(programmers);

    // Authorizing created members
    checkUsers(documentators, peter);
    checkUsers(programmers, peter);
  }
           . . .
  public void checkUsers(Role role, User user) {
           . . .
    Authorization autho = userAdm.getAuthorization(user);
    boolean ok = autho.hasRole(role.getName());
    System.out.println("In group " + role.getName() + " ? " + ok);
           . . .
  }
}
Listing 1: Using the User Admin Service

Interfaces

Developers that are interested in receiving notification when a role is created/removed or changed, should implement the org.osgi.service.useradmin.UserAdminListener interface and register it as a service in the framework. The User Admin service listens for such services and notifies all registered listeners for user admin events.

           . . .       
public class UserListener implements UserAdminListener {

  public void roleChanged(UserAdminEvent ue) {
    if (ue.getType() == UserAdminEvent.ROLE_CREATED) {
      String name = ue.getRole().getName(); 
      System.out.println("Created " + name); 
    } 
  }
}
Listing 2: Implementing UserAdminListener

    UserListener userListener = new UserListener();
    bc.registerService(UserAdminListener.class.getName(), userListener, null);
Listing 3: Registering an UserAdminListener

System Properties

The UserAdmin Bundle conforms with following system properties:

System Property Default Value Description
mbs.useradmin.administrator.delete true Allows deletion of the administration group and the last administrator user when this property is true or is not set.
mbs.measurements.full false

Enable generation of debug information about the startup time of UserAdmin Bundle's functional parts.

These properties become useful only if the mbs.util.ref.log.debug system property is true. To view generated logs in the system output, make sure that the mbs.util.ref.log.printOnConsole system property is also true.

mbs.measurements.bundles

To apply the above properties, you should specify them:

Troubleshooting

UserAdmin Bundle uses DB Bundle for storing the database containing users and their properties. After DB Bundle has been stopped, modifications to user database are not stored. They will be stored and synchronized with the content of the user database, when DB Bundle is activated. Though, if UserAdmin Bundle is stopped before the activation of DB Bundle, the modifications will be lost.

Turning Debug Logs On

The UserAdmin Bundle produces Tracer-enabled log information with the help of the ProSyst log reference utility. To enable the generation of debug information, you should activate the utility's debug mode by setting mbs.util.ref.log.debug system property to true prior to starting the framework. To be able to view created logs in the framework console, make sure that the mbs.util.ref.log.printOnConsole system property is also true.

For more details on the Tracer support of the log reference utility, refer to the description of the ProSyst Util Bundle.

References


OSGi Bundles