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:
The UserAdmin Bundle JAR file is useradm.jar, and is found in the bundles folder.
All packages imported by the UserAdmin Bundle are exported by bundles from the Framework Professional Edition Package :
|
The UserAdmin Bundle does not export any packages.
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.
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);
. . .
}
}
|
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);
}
}
}
|
UserListener userListener = new UserListener();
bc.registerService(UserAdminListener.class.getName(), userListener, null);
|
The UserAdmin Bundle conforms with following system properties:
|
To apply the above properties, you should specify them:
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.
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.