Web Service interfaces to the Roles Database

Last modified 8/1/2007

Table of Contents

Roles Database basics

The Roles Database is MIT's central system for storing and disseminating authorization information. It currently stores authorizations for hundreds of business functions within dozens of applications, and new functions are being added each year. Maintenance of authorizations is distributed to departmental administrators (who control access to their department's resources) and to central offices responsible for HR, financial, student records, and other resources.

ISDA has developed a Web Service providing real-time access for looking up authorizations in the Roles Database. The Web Service is described in detail later in this document, but first, let's cover some of the basics of the Roles Database.

Authorizations in the Roles Database have the form:

Authorization = Person + Function + Qualifier
The Person is the person who has the Authorization to do some sort of business transaction. The Function represents the business transaction. The Qualifier is the organizational, financial, or other unit within which the Person is is Authorized to perform the Function. When an Authorization is created (by a person with appropriate authority), the authorization-creator picks a Person, a Function, and a Qualifier from pre-existing lists.

Consider, for example, the following hypothetical authorization:

PersonFunction Qualifier
CategoryFunction Name
JOEUSERHRView Employee Records 10000429 (Biology)
In this example, the person JOEUSER (identified by his username) has an authorization to perform the function "View Employee Records" within the category HR, but only applying to records related to organizational unit 10000429 (Biology). In this particular hypothetical case, the particular Function requires that the Qualifier Type must be an 8-digit org unit; other Functions would require different types of Qualifiers such as financial units, academic course numbers, etc..

There are several hierarchies of Qualifiers within the Roles Database, one for each Qualifier Type. Most of the Qualifier heirarchies are updated automatically each night in the Roles Database from sources of financial, HR, EHS, or other data at MIT. Other Qualifier hierarchies can be maintained manually via a web-based UI.

When an Authorization is created, the Qualifier may be a "leaf" level, or a "node" in a hierarchy, in which case the Authorization applies to all Qualifiers that are a child, grandchild, etc. of the specified node. In the above example, the Qualifier could have been specified as "10000030 Science Area", and the Authorization would have applied not only to Biology, but also to Mathematics, Physics, and all other units under the School of Science. An Authorization can be "direct" (i.e., it was explicitly created in the Roles Database), or "implied" (i.e., it is implied by an Authorization created for an object at a higher level in the hierarchy).

Qualifiers can be identified by a Qualifier Code (usually the common code used throughout MIT) or the Qualifier ID (a unique number within the Roles Database that has no meaning in other systems at MIT).

There is a special Qualifier "NULL". Some business Functions do not need a Qualifier. This would be the case where the business transaction to be performed is all-or-nothing and is not limited to an organizational or financial area. In these cases, Authorizations would have a Qualifier identified by the Qualifier Code "NULL".

Within the Roles Database, a Person is identified by his/her Kerberos principal at MIT. In the future, the "Person" field may be broadened to represent a broader set of Agents, including people in the broader MIT community who do not have an MIT Kerberos principal, servers, groups, etc.. There are some limited definitions of "pseudo-usernames" within the Roles Database representing servers, but this is an ad-hoc mechanism that needs to be replaced with a more generic way of representing diverse people, servers, and other agents. For now, authorizations can only be created for people at MIT who have an MIT Kerberos principal, and a few "pseudo-users" representing servers.

A Function is an object that represents a role or authority to perform some sort of business transaction, such as viewing data, spending money, accepting a student's application, etc.. Functions are grouped into Function Categories, or application areas, such as HR (Human Resources), PAYR (Payroll), EHS (Environment, Health and Safety), UADM (Undergraduate Admissions), etc.. A Function Category is identified by a 2-4 character code. A Function can be identified by either (1) its Function Category and Function Name or (2) its unique Function ID number.

Within an Authorization, in addition to the main fields of Person, Function, and Qualifier, there are also some minor fields that optionally specify a date range for the Authorization, and flags indicating whether the person can "do" the function specified in the Authorization, grant the Authorization to others or both.

Introduction to the Roles Web Service

This document describes the Java APIs wrapped around the Roles Web Service. It would be possible for a non-Java developer to use the Web Service directly, though this is not described in this document.

There are currently 2 exposed APIs for the ROLES web service. These APIs are

In the future, there will be more APIs, allowing for more versatile ways of listing authorizations, as well as interfaces for creating authorizations, viewing and maintaining qualifiers, and other features.

Controlling access to the web service

The Roles Web Service deals with look-ups or other actions related to people's authorizations, but access to features of the Web Service itself are also controlled by Authorizations within the Roles Database.

There is an authentication step and up to two levels of authorization checking when the Web Service is used.

  1. The application server must authenticate with the WS server.
    Setting up authentication is done via agreement with ISDA. This is done at the WS Server layer, and the Roles Database is not involved in this authentication.

  2. The service name associated with the application server is checked to make sure it has the authority to look up or do other operations related to objects in the Roles Database. A server in general will be limited to working with Authorizations within one or more specified Categories (or application areas).

  3. In some cases, the application server allows an end user to perform authorization look-ups or other transactions. In these cases, there will be two levels of authorization checking: (a) the application server needs to be authorized for one or more Function Categories and (b) the end user connected to the application server will need his/her own authorizations to perform lookups or other transactions.

Examples will illustrate a simple and more complex case of authorization checking for the Roles Web Server.

  1. Simple case
    A good example of the simple case is provided by the Undergraduate Admissions server.
    This server looks up authorizations for its end users, and based on this, allows or denies its end users access to Undergraduate Admissions functionality. However, the end users do not use the UA server to create or look-up authorizations of others, so the UA server does not act as a proxy for end users to allow them to pass through to the Roles DB and do authorizations lookups or other authorizations operations.

    Thus, there is only one level of authorization checking -- the application server looks up the authority of its end users. The Undergraduate Admissions server, once it has connected and has been authenticated with the WS Server, is identified with the pseudo-username 'UA$SERV'. It is allowed to run Roles Web Services to look up authorizations only within the Function Category 'UADM'. This is controlled via an Authorization in the Roles Database for pseudo-user UA$SERV, function 'RUN ROLES SERVICE PROCEDURES' and qualifier "CATUADM (Category UADM)". Thus, the Undergraduate Admissions server is allowed to look up authorizations in the UADM category but not in other categories such as HR, PAYR, EHS, etc..

  2. More complex case
    Let's imagine a hypothetical server to control people's access to locked rooms at MIT. In our example, imagine that the Roles Database has authorizations that allow specific individuals to enter specific rooms (based on their MIT ID cards). The hypothetical server will have two functions (a) to open doors for authorized individuals, and (b) to allow building administrators to maintain authorizations for people to get into various rooms within their building. Let's further suppose that room-access authorizations are controlled by functions in the function category MKEY, and the server is known by the pseudo-username MKEY$SRV.

    In this case, the Room Access application server would need to authenticate with the Web Service. Once authenticated, one of its features will be to decide whether to let an individual into a given room. When it does this, it will call the Web Service to look up the individual's authorization to enter the room. The pseudo-username MKEY$SRV will need an authorization to 'RUN ROLES SERVICE PROCEDURES' for qualifier "CATMKEY (Category MKEY)", allowing the application server to look up authorizations within the category MKEY.

    The Room Access application server will also allow administrators to look up people's authorizations within the Roles Database for entering rooms. In this case the application server will serve as a proxy for an end user, passing the end user's lookup request about authorizations to the Roles Database, which will return information about who is authorized to enter a given room. The application server will fill in a parameter in its Web Service call to tell the WS server the username of the end user. Thus, there will be two levels of authorization checking: (a) the application server (identified by MKEY$SRV) will need "RUN ROLES SERVICE PROCEDURES" authorization for the appropriate category of authorizations (MKEY), and (b) the end user, identified by his/her Kerberos username, will need "VIEW AUTH BY CATEGORY" authorization for the appropriate category of authorizations (again, MKEY).

isUserAuthorized

The isUserAuthoried API returns a Boolean true if the user is authorized for the category, function and qualifier parameters or a Boolean false if the user is not authorized.

syntax:

 public boolean isUserAuthorized(	
   String kerberos_principal, 
   String category,
   String function, 
   String qualifier, 
   String proxy_user)
 throws rolesException

Parameters:

kerberos_principal:
  [in]	string which contains the kerberos principal name for the user whose
        authorizations are to be looked up.  This is a required parameter.

category:
  [in]	string which contains the ROLES category code (e.g., HR, PAYR, UADM)

function:
  [in]	string which contains the Roles function name.  This is a required parameter.

qualifier:
  [in]	string which contains the Roles qualifier code.  This is a required parameter.

proxy_user:
  [in]	in cases where the application server is acting as a proxy for an
        end user to look up authorizations for others, this string will contain
        the kerberos principal of the user who wants to look up authorizations
        for others.  This parameter is not yet implemented and must be set to 
        the empty string ("").  This is a required parameter.

Return value:

This API will return a boolean true if the user specified in the kerberos_principal parameter is authorized to perform the given Function (within the given Category) for the given Qualifier that were specified in the category, function and qualifier parameters. If the user is not authorized for the given Function (within the given Category) and Qualifier, a boolean false will be returned.

listAuthorizationByPerson

For the specified user, the listAuthorizationsByPerson API returns an array of Roles authorizations within the specified Roles Function Category. syntax:
 public rolesAuthorization[] listAuthorizationsByPerson(	
   String kerberos_principal, 
   String category, 
   boolean isActive, 
   boolean willExpand, 
   String proxy_user)  
 throws rolesException

Parameters:

kerberos_principal:
[in]	string which contains the kerberos principal name for the user.  This is a required parameter.

category:
[in]	string which contains the ROLES category code.  This is a required parameter.

function:
[in]	string which contains the Roles function name.  This is a required parameter.

isActive:
[in]	boolean true or false.  Set to true if the user is marked as active in ROLES, otherwise set to false.  This is a required parameter.

willExpand:
[in]	Boolean true or false.  Setting this value to true, this API will return all implied and explicit authorizations for the specified user.  Setting this value to false, this API will return only the explicit authorizations for the specified user.  This is a required parameter.

proxy_user:
  [in]	in cases where the application server is acting as a proxy for an
        end user to look up authorizations for others, this string will contain
        the kerberos principal of the user who wants to look up authorizations
        for others.  This parameter is not yet implemented and must be set to 
        the empty string ("").  This is a required parameter.
Return value: This API will return array of authorizations for the user specified in the kerberos_principal parameter. This array is an array of Java Beans as described in the following pages. If no authorizations are found for the user, a null will be returned.

The rolesAuthorization class below describes the elements of the array that is returned by the listAuthorizationsByPerson API.

public class rolesAuthorization implements java.io.Serializable {
    
     private String category;
     private String qualifier;
     private String qualifierCode;
     private String function;
     private String name;
    
    public rolesAuthorization() 
    {
    }

    public String getCategory()
    {
        return category;
    }
    
    public void setCategory(String uCategory)
    {
        category = uCategory;
    }

    public String getQualifier()
    {
        return qualifier;
    }
    
    public void setQualifier(String uQualifier)
    {
        qualifier = uQualifier;
    }
    
    public String getFunction()
    {
        return function;
    }

    public String getQualifierCode()
    {
        return qualifierCode;
    }
    
 public void setQualifierCode(String uQualifierCode)
    {
        qualifierCode = uQualifierCode;
    }
    
    public void setFunction(String uFunction)
    {
        function = uFunction;
    }
    
    public String getName()
    {
        return name;
    }
    public void setName(String uName)
    {
        name = uName;
    }

    public String toString()
    {
        String s = "Name: ";
        if (name != null)
            s += name;
        s += "\n  Category: ";
        if (category != null)
            s += category;
        s += "\n  Qualifier: ";
        if (qualifier != null)
            s += qualifier;
        s += "\n  Function: ";
        if (function != null)
            s += function;
        return s;
    }

}

Code samples

The following code snippets illustrate how to implement the client side calls to the ROLES web service. All the marshalling code that is required talk to the web service can be generated from the web service WSDL. Once generated, the marshalling code can be found in the rolesService_pkg package.
For the isUserAuthorized API:

Public String getUserAuthorization(
  String UserName,
  String Category,
  String Function,
  String Qualifier)
{
  try
  {
    RolesServiceLocator sl = new RolesServiceLocator();
    String ServiceName = sl.getrolesAddress();
    Roles service = sl.getroles();
    boolean rResponse = service.isUserAuthorized(
      UserName,
      Category,
      Function, 
      Qualifier, 
      "");
  }
  catch(Exception e)
  {
    return(e.getMessage());
  }
  if (rResponse == true)
    return("authorized")
    return("not authorized");
}

For the listAuthorizationsByPerson API:

  public String listUserAuthorization(
         String UserName,
         String Category,
         boolean bisActive,
         boolean bwillExpand)
  {
    RolesAuthorization rResponse[] = null;
    StringBuffer sb = new StringBuffer();
    try
    {
      RolesServiceLocator sl = new RolesServiceLocator();
      String ServiceName = sl.getrolesAddress();
      Roles service = sl.getroles();
      rResponse = service.listAuthorizationsByPerson(UserName, Catagory, 
      bisActive, bwillExpand, "");
      catch(Exception e)
      {
        sb.append(e.getMessage());
        return(sb.toString());
      }

    if (rResponse == null)
    return ("");
    for (int i = 0; i < rResponse.length; i++)
    {
      sb.append("<BR>\r\n");
      sb.append("Name:  " + rResponse[i].getName());
      sb.append("<BR>\r\n");
      sb.append("  Category:  " + 
      rResponse[i].getCategory());
      sb.append("<BR>\r\n");
      sb.append("  Qualifier:  " + 
      rResponse[i].getQualifier());
      sb.append("<BR>\r\n");
      sb.append("  QualifierCode:  " + 
      rResponse[i].getQualifierCode());
      sb.append("<BR>\r\n");
      sb.append("  Function:  " + 
      rResponse[i].getFunction());
      sb.append("<BR>\r\n");
    }
    return(sb.toString);
  }