Gestionnaire de sécurité.
Les accès sensibles (écriture de fichiers, de propriétés système, etc.) sont contrôlés via l'appel de méthodes
checkXXX()
sur le gestionnaire de sécurité. Par exemple l'implémentation de FileOutputStream.write()
appelle
SecurityManager.checkWrite().
Les méthodes checkXXX()
du SecurityManager sont censées lever des exceptions lorsque les accès sont
interdits. Le SecurityManager effectue ce contrôle en examinant si la classe appelante a été chargée par un autre
ClassLoader que le ClassLoader primordial. Un tel ClassLoader peut par exemple être un AppletClassLoader, ou d'une
manière générale impliquer un CODEBASE distant, impliquant des droits limités. Cet examen est effectué via la
méthode inClassLoader()
du Gestionnaire de Sécurité.
Ainsi,
classLoaderDepth()
).
Ceci permet d'autoriser des classes système sûres (classes système de profondeur faible) à effectuer des
opérations sensibles même si ces classes ont été appelées par des classes non sûres (classes utilisateur de
grande profondeur).est représenté par une classe abstraite.
Java 2 offre plus de souplesse que le mode tout ou rien en introduisant le concept de permission. Le Gestionnaire
de Sécurité n'est plus seul à décider de l'autorisation en fonction du ClassLoader (sanbox ou non), mais délègue la
décision à un nouveau composant, le contrôleur d'accès (AccessController). Si l'on reprend notre exemple
l'implémentation de FileOutputStream.write()
appelle SecurityManager.checkWrite()
qui
appelle lui-même AccessControl.checkPermission()
On aboutit ainsi à un modèle de "capacité" (permission) à effectuer une opération (Capabilities model) plutôt qu'un modèle d'autorisation (la sandbox autorise ou non) : posséder (accéder à) un objet (directement) donne le droit de l'utiliser : c'est le modèle de l'objet gardé, où l'on demande l'accès à un objet à un gatekeeper. On peut exercer une permission par autorisation d'une autre partie, si l'autre partie nous donne l'objet permission.
on distingue :
java.security.manager
(java
-Djava.security.manager MonApplication
) ou par programmation (System.setSecurityManager (new
SecurityManager())
). Il n'est donc plus nécessaire de développer de classe dérivée du
SecurityManager pour personnaliser la politique de sécurité, ce Gestionnaire de Sécurité par défaut
exploitant la politique définie par les fichiers prévus à cet effet.Cependant, afin d'exploiter le nouveau modèle de permissions introduit dans Java 2, divers changements plus ou
moins transparents (nous allons voir pourquoi) ont été effectués :Une méthode checkPermission() a été les
implémentation de ces méthodes Mais en fait, elles font maintenant toutes appel à la méthode checkPermission()
qui se charge d'interroger l'Access Controler.
Tous les accès doivent donc maintenant être validés par le Contrôleur d'Accès, et non plus par le Gestionnaire de Sécurité. Ceci à pour inconvénient de devoir migrer les implémentations de Gestionnaire de Sécurité écrites pour Java 1.1.
Redéfinir les methodes checkXXX()
d'un SecurityManager n'est donc plus valide en Java 2, dans la
mesure ou cette redéfinition court-circuite l'appel à la vérification des permissions de Java 2. Il est donc
nécessaire, soit d'appeler systématiquement super.checkXXX (qui appelera checkPermission) dans les methodes
checkXXX() de notre SecurityManager, soit de réécrire le SecurityManager en prenant en compte la délégation du
contrôle des accès (permissions) à l'Access Controler. Il est en effet important, d'une manière ou d'une autre,
d'exploiter les permissions par défaut fixées dans Java 2, parce que Sun indique qu'elles sont plus sûres et
corrigent quelques failles de sécurité de Java 1.
La redéfinition des méthodes checkXXX() peut cependant se révéler toujours utile pour inclure de l'audit ou des affichages GUI lors des tentatives d'actions sensibles.
Un exemple d'accès contrôlé est :
MaClasse.maMethode()
FileOutputStream.write()
SecurityManager.checkWrite()
System.setSecurityManager()
).