WebSphere eXtreme Scale Programming Guide > Security API
Client authorization programming
WebSphere eXtreme Scale supports Java™ Authentication and Authorization Service (JAAS) authorization out-of-the-box and also supports custom Authorization using the ObjectGridAuthorization interface.
The ObjectGridAuthorization plug-in is used to authorize ObjectGrid, ObjectMap and JavaMap accesses to the Principals represented by a Subject object in a custom way. A typical implementation of this plug-in is to retrieve the Principals from the Subject object, and then check whether or not the specified permissions are granted to the Principals.
A permission passed to the checkPermission(Subject, Permission) method can be one of the following permissions:
- MapPermission
- ObjectGridPermission
- ServerMapPermission
- AgentPermission
Refer to ObjectGridAuthorization API Documentation for more details.
MapPermissionThe com.ibm.websphere.objectgrid.security.MapPermission public class represents permissions to the ObjectGrid resources, specifically the methods of ObjectMap or JavaMap interfaces. WebSphere eXtreme Scale defines the following permission strings to access the methods of ObjectMap and JavaMap:
- read: Permission to read the data from the map. The integer constant is defined as MapPermission.READ.
- write: Permission to update the data in the map. The integer constant is defined as MapPermission.WRITE.
- insert: Permission to insert the data into the map. The integer constant is defined as MapPermission.INSERT.
- remove: Permission to remove the data from the map. The integer constant is defined as MapPermission.REMOVE.
- invalidate: Permission to invalidate the data from the map. The integer constant is defined as MapPermission.INVALIDATE.
- all: All above permissions: read, write, insert, remote, and invalidate. The integer constant is defined as MapPermission.ALL.
Refer to MapPermission API Documentation for more details.
You can construct a MapPermission object by passing the fully qualified ObjectGrid map name (in format [ObjectGrid_name].[ObjectMap_name]) and the permission string or integer value. A permission string can be a comma-delimited string of the previous permission strings such as read, insert, or it can be all. A permission integer value can be any previously mentioned permission integer constants or a mathematical value of several integer permission constants, such as MapPermission.READ|MapPermission.WRITE.
The authorization occurs when an ObjectMap or JavaMap method is called. The eXtreme Scale runtime checks different permissions for different methods. If the required permissions are not granted to the client, an AccessControlException results.
Table 1. List of methods and the required MapPermission Permission ObjectMap/JavaMap read boolean containsKey(Object) boolean equals(Object) Object get(Object) Object get(Object, Serializable) List getAll(List) List getAll(List keyList, Serializable) List getAllForUpdate(List) List getAllForUpdate(List, Serializable) Object getForUpdate(Object) Object getForUpdate(Object, Serializable) public Object getNextKey(long) write Object put(Object key, Object value) void put(Object, Object, Serializable) void putAll(Map) void putAll(Map, Serializable) void update(Object, Object) void update(Object, Object, Serializable) insert public void insert (Object, Object) void insert(Object, Object, Serializable) remove Object remove (Object) void removeAll(Collection) void clear() invalidate public void invalidate (Object, boolean) void invalidateAll(Collection, boolean) void invalidateUsingKeyword(Serializable) int setTimeToLive(int)
Authorization is based solely on which method is used, rather than what the method really does. For example, a put method can insert or update a record based on whether the record exists. However, the insert or update cases are not distinguished.
An operation type can be achieved by combinations of other types. For example, an update can be achieved by a remove and then an insert. Consider these combinations when designing the authorization policies.
ObjectGridPermissionA com.ibm.websphere.objectgrid.security.ObjectGridPermission represents permissions to the ObjectGrid:
- Query: permission to create an object query or entity query. The integer constant is defined as ObjectGridPermission.QUERY.
- Dynamic map: permission to create a dynamic map based on the map template. The integer constant is defined as ObjectGridPermission.DYNAMIC_MAP.
Refer to ObjectGridPermission API Documentation for more details.
The following table summarizes the methods and the required ObjectGridPermission:
Table 2. List of methods and the required ObjectGridPermission Permission action Methods query com.ibm.websphere.objectgrid.Session.createObjectQuery(String) query com.ibm.websphere.objectgrid.em.EntityManager.createQuery(String) dynamicmap com.ibm.websphere.objectgrid.Session.getMap(String)
ServerMapPermissionAn ServerMapPermission represents permissions to an ObjectMap hosted in a server. The name of the permission is the full name of the ObjectGrid map name. It has three actions:
1. replicate: permission to replicate a server map to near cache.
2. dynamicIndex: permission for a client to create or remove a dynamic index on a server
Refer to ServerMapPermission API documentation for more details. The detailed methods, which require different ServerMapPermission, are listed in the following table:
Table 3. Permissions to a server-hosted ObjectMap Permission action Methods replicate com.ibm.websphere.objectgrid.ClientReplicableMap.enableClientReplication(Mode, int[], ReplicationMapListener) dynamicIndex com.ibm.websphere.objectgrid.BackingMap.createDynamicIndex(String, boolean, String, DynamicIndexCallback) dynamicIndex com.ibm.websphere.objectgrid.BackingMap.removeDynamicIndex(String)
AgentPermissionAn AgentPermission represents permissions to the datagrid agents. The name of the permission is the full name of the ObjectGrid map, and the action is a comma-delimited string of agent implementation class names or package names.
Refer to AgentPermission API Documentation for more information.
The following methods in the class com.ibm.websphere.objectgrid.datagrid.AgentManager require AgentPermission.
com.ibm.websphere.objectgrid.datagrid.AgentManager#callMapAgent(MapGridAgent, Collection)
com.ibm.websphere.objectgrid.datagrid.AgentManager#callMapAgent(MapGridAgent)
com.ibm.websphere.objectgrid.datagrid.AgentManager#callReduceAgent(ReduceGridAgent, Collection)
com.ibm.websphere.objectgrid.datagrid.AgentManager#callReduceAgent(ReduceGridAgent, Collection)
Authorization mechanisms
WebSphere eXtreme Scale supports two kinds of authorization mechanisms: Java Authentication and Authorization Service (JAAS) authorization and custom authorization. These mechanisms apply to all authorizations. JAAS authorization augments the Java security policies with user-centric access controls. Permissions can be granted based not just on what code is running, but also on who is running it. JAAS authorization is part of the SDK v1.4 and later.
Additionally, WebSphere eXtreme Scale also supports custom authorization with the following plug-in:
- ObjectGridAuthorization: custom way to authorize access to all artifacts.
You can implement the own authorization mechanism if you do not want to use JAAS authorization. By using a custom authorization mechanism, you can use the policy database, policy server, or Tivoli Access Manager to manage the authorizations.
You can configure the authorization mechanism in two ways:
1. XML Configuration: You can use the ObjectGrid XML file to define an ObjectGrid and set the authorization mechanism to either AUTHORIZATION_MECHANISM_JAAS or AUTHORIZATION_MECHANISM_CUSTOM. Here is the secure-objectgrid-definition.xml file that is used in the enterprise application ObjectGridSample:
<objectGrids> <objectGrid name="secureClusterObjectGrid" securityEnabled="true" authorizationMechanism="AUTHORIZATION_MECHANISM_JAAS"> <bean id="TransactionCallback" classname="com.ibm.websphere.samples.objectgrid.HeapTransactionCallback" /> ... </objectGrids>2. Programmatic Configuration: To create an ObjectGrid using method ObjectGrid.setAuthorizationMechanism(int), you can call the following method to set the authorization mechanism. Calling this method applies only to the local WebSphere eXtreme Scale programming model when you directly instantiate the ObjectGrid instance:
/** * Set the authorization Mechanism. The default is * com.ibm.websphere.objectgrid.security.SecurityConstants. * AUTHORIZATION_MECHANISM_JAAS. * @param authMechanism the map authorization mechanism */ void setAuthorizationMechanism(int authMechanism);
JAAS authorizationA javax.security.auth.Subject object represents an authenticated user. A Subject is comprised of a set of principals, and each Principal represents an identity for that user. For example, a Subject can have a name principal, for example, Joe Smith, and a group principal, for example, manager.
Use the JAAS authorization policy, permissions can be granted to specific Principals. WebSphere eXtreme Scale associates the Subject with the current access control context. For each call to the ObjectMap or Javamap method, the Java runtime automatically determines if the policy grants the required permission only to a specific Principal and if so, the operation is allowed only if the Subject associated with the access control context contains the designated Principal.
You must be familiar with the policy syntax of the policy file. For detailed description of JAAS authorization, refer to the JAAS Reference Guide.
WebSphere eXtreme Scale has a special code base that is used for checking the JAAS authorization to the ObjectMap and JavaMap method calls. This special code base is http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction. Use this code base when granting ObjectMap or JavaMap permissions to principals. This special code was created because the Java archive (JAR) file for eXtreme Scale is granted with all permissions.
The template of the policy to grant the MapPermission permission is:
grant codeBase "http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction" <Principal field(s)>{ permission com.ibm.websphere.objectgrid.security.MapPermission "[ObjectGrid_name].[ObjectMap_name]", "action"; .... permission com.ibm.websphere.objectgrid.security.MapPermission "[ObjectGrid_name].[ObjectMap_name]", "action"; };A Principal field looks like the following example:
principal Principal_class "principal_name"
In this policy, only insert and read permissions are granted to these four maps to a certain principal. The other policy file, fullAccessAuth.policy, grants all permissions to these maps to a principal. Before running the application, change the principal_name and principal class to appropriate values. The value of the principal_name depends on the user registry. For example, if local OS is used as user registry, the machine name is MACH1, the user ID is user1, and the principal_name is MACH1/user1.
The JAAS authorization policy can be put directly into the Java policy file, or it can be put in a separate JAAS authorization file and then set by using the
-Djava.security.auth.policy=file:[JAAS_AUTH_POLICY_FILE]
JVM argument or by using the
-Dauth.policy.url.x=file:[JAAS_AUTH_POLICY_FILE]
property in the java.security file.
Custom ObjectGrid authorizationObjectGridAuthorization plug-in is used to authorize ObjectGrid, ObjectMap and JavaMap accesses to the Principals represented by a Subject object in a custom way. A typical implementation of this plug-in is to retrieve the Principals from the Subject object, and then check whether or not the specified permissions are granted to the Principals.
A permission passed to the checkPermission(Subject, Permission) method could be one of the following:
1. MapPermission
2. ObjectGridPermission
3. AgentPermission
4. ServerMapPermission
Refer to ObjectGridAuthorization API documentation for more details.
The ObjectGridAuthorization plug-in can be configured in the following ways:
1. XML Configuration:You can use the ObjectGrid XML file to define an ObjectAuthorization plug-in. Here is an example:
<objectGrids> <objectGrid name="secureClusterObjectGrid" securityEnabled="true" authorizationMechanism="AUTHORIZATION_MECHANISM_CUSTOM"> ... <bean id="ObjectGridAuthorization" className="com.acme.ObjectGridAuthorizationImpl" /> </objectGrids>
2. Programmatic Configuration: If you want to create an ObjectGrid using the API method ObjectGrid.setObjectGridAuthorization(ObjectGridAuthorization), you can call the following method to set the authorization plug-in. This method only applies to the local eXtreme Scale programming model when you directly instantiate the ObjectGrid instance.
/** * Sets the <code>ObjectGridAuthorization</code> for this ObjectGrid instance. * <p> * Passing <code>null</code> to this method removes a previously set * <code>ObjectGridAuthorization</code> object from an earlier invocation of this method * and indicates that this <code>ObjectGrid</code> is not associated with a * <code>ObjectGridAuthorization</code> object. * <p> * This method should only be used when ObjectGrid security is enabled. If * the ObjectGrid security is disabled, the provided <code>ObjectGridAuthorization</code> object * will not be used. * <p> * A <code>ObjectGridAuthorization</code> plugin can be used to authorize * access to the ObjectGrid and maps. Please refer to <code>ObjectGridAuthorization</code> for more details. * * <p> * As of XD 6.1, the <code>setMapAuthorization</code> is deprecated and * <code>setObjectGridAuthorization</code> is recommended for use. However, * if both <code>MapAuthorization</code> plugin and <code>ObjectGridAuthorization</code> plugin * are used, ObjectGrid will use the provided <code>MapAuthorization</code> to authorize map accesses, * even though it is deprecated. * <p> * Note, to avoid an <code>IllegalStateException</code>, this method must be * called prior to the <code>initialize()</code> method. Also, keep in mind * that the <code>getSession</code> methods implicitly call the * <code>initialize()</code> method if it has yet to be called by the * application. * * @param ogAuthorization the <code>ObjectGridAuthorization</code> plugin * * @throws IllegalStateException if this method is called after the * <code>initialize()</code> method is called. * * @see #initialize() * @see ObjectGridAuthorization * @since WAS XD 6.1 */ void setObjectGridAuthorization(ObjectGridAuthorization ogAuthorization);
Implement ObjectGridAuthorization
The boolean checkPermission(Subject subject, Permission permission) method of the ObjectGridAuthorization interface is called by theWebSphere eXtreme Scale run time to check whether the passed-in subject object has the passed-in permission. The implementation of the ObjectGridAuthorization interface returns true if the object has the permission, and false if not.
A typical implementation of this plug-in is to retrieve the principals from the Subject object and check whether the specified permissions are granted to the principals by consulting specific policies. These policies are defined by users. For example, the policies can be defined in a database, a plain file, or a Tivoli Access Manager policy server.
For example, we can use Tivoli Access Manager policy server to manage the authorization policy and use its API to authorize the access. For how to use Tivoli Access Manager Authorization APIs, refer to the IBM Tivoli Access Manager Authorization Java Classes Developer Reference for more details.
This sample implementation has the following assumptions:
- Only check authorization for MapPermission. For other permissions, always return true.
- The Subject object contains a com.tivoli.mts.PDPrincipal principal.
- The Tivoli Access Manager policy server has defined the following permissions for the ObjectMap or JavaMap name object. The object that is defined in the policy server must have the same name as the ObjectMap or JavaMap name in the format of [ObjectGrid_name].[ObjectMap_name]. The permission is the first character of the permission strings that are defined in the MapPermission permission. For example, the permission "r" that is defined in the policy server represents the read permission to the ObjectMap map.
The following code snippet demonstrates how to implement the checkPermission method:
/** * @see com.ibm.websphere.objectgrid.security.plugins. * MapAuthorization#checkPermission * (javax.security.auth.Subject, com.ibm.websphere.objectgrid.security. * MapPermission) */ public boolean checkPermission(final Subject subject, Permission p) { // For non-MapPermission, we always authorize. if (!(p instanceof MapPermission)){ return true; } MapPermission permission = (MapPermission) p; String[] str = permission.getParsedNames(); StringBuffer pdPermissionStr = new StringBuffer(5); for (int i=0; i<str.length; i++) { pdPermissionStr.append(str[i].substring(0,1)); } PDPermission pdPerm = new PDPermission(permission.getName(), pdPermissionStr.toString()); Set principals = subject.getPrincipals(); Iterator iter= principals.iterator(); while(iter.hasNext()) { try { PDPrincipal principal = (PDPrincipal) iter.next(); if (principal.implies(pdPerm)) { return true; } } catch (ClassCastException cce) { // Handle exception } } return false; }
Parent topic
Security API