Programmation d'autorisations client

WebSphere eXtreme Scale prend en charge l'autorisation JAAS (Java Authentication and Authorization Service) déjà prête à être utilisée et prend également en charge l'autorisation personnalisée en utilisant l'interface ObjectGridAuthorization.

Le plug-in ObjectGridAuthorization permet d'autoriser les accès ObjectGrid, ObjectMap et JavaMap aux principaux représentés par un objet Subject d'une manière personnalisée. Une implémentation type de ce plug-in est d'extraire les principaux d'un objet Subject et de vérifier ensuite si les droits d'accès spécifiés sont ou non accordés à ces principaux.

Les droits d'accès passés à la méthode checkPermission(Subject, Permission) peuvent être de l'un des types suivants :

Pour plus de détails, voir la documentation de l'API ObjectGridAuthorization.

MapPermission

La classe publique com.ibm.websphere.objectgrid.security.MapPermission représente les droits d'accès sur les ressources ObjectGrid, particulièrement les méthodes des interfaces ObjectMap ou JavaMap. WebSphere eXtreme Scale définit les chaînes suivantes de droits d'accès permettant d'accéder aux méthodes d'ObjectMap et de JavaMap :

Pour plus de détails, voir la documentation de l'API MapPermission.

Vous pouvez construire un objet MapPermission en passant le nom qualifié complet de la mappe ObjectGrid (au format [ObjectGrid_name].[ObjectMap_name]) et la chaîne de droit d'accès ou la valeur de type entier. Une chaîne de droit d'accès peut se présenter sous la forme d'une chaîne des permissions évoquées plus haut (read, insert ou all, par exemple), séparées par des virgules. Une valeur de permission de type entier pourra être n'importe laquelle des constantes entières mentionnées plus haut ou une valeur mathématiques de plusieurs constantes entières, comme MapPermission.READ|MapPermission.WRITE, par exemple.

L'autorisation se produit lors de l'appel d'une méthode ObjectMap ou JavaMap. Le moteur d'exécution vérifie différentes permissions pour différentes méthodes. Le refus des droits requis au client génère une exception AccessControlException.

Tableau 1. Liste des méthodes et de la MapPermission requise
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)

L'autorisation se base uniquement sur la méthode utilisée et non sur l'action effective de cette méthode. Exemple : une méthode put peut aussi bien insérer qu'actualiser un enregistrement en fonction de l'existence de cet enregistrement. Mais, pour l'autorisation, aucune différence ne sera faite entre l'insertion et l'actualisation.

Un type d'opération peut être réalisé par la combinaison d'autres types. Une actualisation, par exemple, pourra être réalisée par un remove et par un insert. Vous devez envisager ces combinaisons possibles lorsque vous concevez vos règles d'autorisation.

ObjectGridPermission

Un com.ibm.websphere.objectgrid.security.ObjectGridPermission représente les droits d'accès à l'ObjectGrid :
  • Query : permission de créer une requête sur des objets ou sur des entités. La constante entière est définie comme ObjectGridPermission.QUERY.
  • Dynamic map : permission de créer une mappe dynamique à partir du modèle de mappe. La constante entière est définie comme ObjectGridPermission.DYNAMIC_MAP.
Pour plus de détails, voir la documentation de l'API ObjectGridPermission.

Le tableau suivant récapitule les méthodes et l'ObjectGridPermission requise :

Tableau 2. Liste des méthodes et de l'ObjectGridPermission requise
Action Méthodes
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)

ServerMapPermission

Une ServerMapPermission représente les droits d'accès sur un ObjectMap hébergé sur un serveur. Le nom du droit d'accès n'est autre que le nom complet de la mappe ObjectGrid. Cette autorisation comporte les actions suivantes :

Pour plus de détails, voir la documentation de l'API ServerMapPermission. Le tableau suivant répertorie les méthodes détaillées, qui requièrent différents ServerMapPermission :
Tableau 3. Droits d'accès à un ObjectMap hébergé sur serveur
Action Méthodes
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)

AgentPermission

Un AgentPermission représente les droits d'accès aux agents de grille de données. Le nom du droit d'accès n'est autre que le nom complet de la mappe ObjectGrid et l'action est une chaîne, délimitée par des virgules, constituée par les noms des classes d'implémentation ou des packages d'agents.

Pour plus d'informations, voir la documentation de l'API AgentPermission.

Les méthodes suivantes de la classe com.ibm.websphere.objectgrid.datagrid.AgentManager requièrent 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)

Mécanismes d'autorisation

WebSphere eXtreme Scale prend en charge deux sortes de mécanismes d'autorisation : l'autorisation JAAS (Java Authentication and Authorization Service) et l'autorisation personnalisée. Ces mécanismes s'appliquent à la totalité des autorisations. L'autorisation JAAS augmente les règles Java de sécurité en les dotant de contrôles d'accès centrés sur l'utilisateur. Les droits d'accès peuvent être accordés non seulement en fonction du code en cours d'exécution, mais également en fonction de qui exécute ce code. L'autorisation JAAS fait partie de la version SDK 5 et des versions suivantes.

En outre, WebSphere eXtreme Scale prend également en charge l'autorisation personnalisée grâce au plug-in suivant :

Si vous ne souhaitez pas utiliser l'autorisation JAAS, vous pouvez implémenter votre propre mécanisme d'autorisation. Le recours à un mécanisme d'autorisation personnalisée permet d'utiliser la base de données des règles, le serveur de règles ou Tivoli Access Manager pour gérer les autorisations.

Il existe deux moyens de configurer le mécanisme d'autorisation :

Autorisation JAAS

Un objet javax.security.auth.Subject représente un utilisateur authentifié. Un Subject est constitué d'un groupe de principaux et chaque principal représente une identité pour l'utilisateur. Exemple : un Subject peut avoir un principal name (Jean Dupont, par exemple) et un principal group (manager, par exemple).

L'autorisation JAAS permet d'accorder des droits d'accès à des principaux spécifiques. WebSphere eXtreme Scale associe le Subject au contexte actuel de contrôle d'accès. A chaque appel aux méthodes ObjectMap ou Javamap, l'environnement d'exécution Java détermine automatiquement si la règle accorde le droit d'accès requis uniquement à un principal spécifique et, si c'est le cas, l'opération n'est autorisée que si le Subject associé au contexte de contrôle d'accès contient bien le principal désigné.

Vous devez être familiarisé avec la syntaxe du fichier de règles. Vous trouverez une description détaillée de l'autorisation JAAS dans le Guide de référence JAAS.

Un codebase spécial de WebSphere eXtreme Scale permet de vérifier l'autorisation JAAS sur les appels aux méthodes ObjectMap et JavaMap. Il s'agit du codebase spécial http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction. Utilisez-le pour l'octroi de droits d'accès d'ObjectMap ou de JavaMap à des principaux. Ce code spécial a été créé parce que le fichier JAR d'eXtreme Scale dispose de tous les droits d'accès.

Le modèle de la règle permettant d'accorder la permission MapPermission est :

grant codeBase "http://www.ibm.com/com/ibm/ws/objectgrid/security/PrivilegedAction" 
   <zones principales>{
    permission com.ibm.websphere.objectgrid.security.MapPermission 
               "[ObjectGrid_name].[ObjectMap_name]", "action";
    ....
    permission com.ibm.websphere.objectgrid.security.MapPermission 
               "[ObjectGrid_name].[ObjectMap_name]", "action";
  };
Une zone Principal se présente comme dans l'exemple suivant :
principal Principal_class "principal_name"

Dans cette règle, seuls les droits d'accès insert et read sont accordés à ces quatre mappes vers un certain principal. L'autre fichier de règles, fullAccessAuth.policy, accordent toutes les autorisations à ces mappes à un principal. Avant d'exécuter l'application, modifiez le principal_name et la classe principal. La valeur de principal_name dépend du registre des utilisateurs. Par exemple, si le système d'exploitation local est utilisé comme registre d'utilisateurs, le nom de machine est MACH1, l'ID utilisateur est user1 et principal_name est MACH1/user1.

Avant d'être définie de l'une des deux manières suivantes, la règle d'autorisation JAAS peut être placée directement dans le fichier de règles Java ou dans un fichier d'autorisation JAAS distinct :

Autorisation ObjectGrid personnalisée

Le plug-in ObjectGridAuthorization permet d'autoriser ObjectGrid, ObjectMap et JavaMap à accéder de manière personnalisée aux principaux représentés par un objet Subject. La plupart du temps, ce plug-in est implémenté pour extraire les principaux d'un objet Subject et vérifier ensuite si les permissions spécifiées sont ou non accordées à ces principaux.

Les droits d'accès passés à la méthode checkPermission(Subject, Permission) peuvent être de l'un des types suivants :

Pour plus de détails, voir la documentation de l'API ObjectGridAuthorization.

Le plug-in ObjectGridAuthorization peut être configuré de l'une des manières suivantes :

Implémenter ObjectGridAuthorization

La méthode Boolean checkPermission(Subject subject, Permission permission) de l'interface ObjectGridAuthorization est appelée par l'environnement d'exécution WebSphere eXtreme Scale pour vérifier que l'objet subject envoyé a l'autorisation d'envoi. L'implémentation de l'interface ObjectGridAuthorization retourne true si l'objet a l'autorisation et false s'il ne l'a pas.

La plupart du temps, ce plug-in est implémenté pour extraire les principaux d'un objet Subject et vérifier ensuite, en consultant des règles spécifiques, si les droits d'accès spécifiés sont ou non accordés à ces principaux. Ce sont les utilisateurs qui définissent ces règles. Les règles peuvent ainsi aussi bien être définies dans une base de données, dans un fichier texte ou sur un serveur de règles Tivoli Access Manager.

Nous pouvons, par exemple, utiliser un serveur de règles Tivoli Access Manager pour gérer la règle d'autorisation et utiliser son API pour autoriser l'accès. Pour savoir comment utiliser les API Tivoli Access Manager Authorization, voir le guide IBM® Tivoli Access Manager Authorization Java Classes Developer Reference.

Cet exemple d'implémentation part des présuppositions suivantes :

Le fragment de code suivant montre comment implémenter la méthode checkPermission :

/**
* @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;
}