2012-01-02 5 views
21

Je suis en train de comprendre les bases de la sécurité Java et l'utilisation AccessController.doPrivileged() i a commencé avec un exemple de programmeutilisation AccessController

import java.security.AccessController; 
import java.security.PrivilegedAction; 
public class AccessSystemProperty { 
    public static void main(String[] args) { 
    System.out.println(System.getSecurityManager()); 
     AccessController.doPrivileged(
     new PrivilegedAction<Boolean>(){ 
      public Boolean run(){ 
       System.out.println(System.getProperty("java.home")); 
       return Boolean.TRUE; 
      } 
     } 
     ); 
    } 
} 

si je tente de passer au-dessus du code à l'aide de gérer la sécurité par défaut je reçois AccessControlException Mon stacktrace est

C:\>java -Djava.security.manager AccessSystemProperty 
[email protected] 
Exception in thread "main" java.security.AccessControlException: access denied (
java.util.PropertyPermission java.home read) 
     at java.security.AccessControlContext.checkPermission(Unknown Source) 
     at java.security.AccessController.checkPermission(Unknown Source) 
     at java.lang.SecurityManager.checkPermission(Unknown Source) 
     at java.lang.SecurityManager.checkPropertyAccess(Unknown Source) 
     at java.lang.System.getProperty(Unknown Source) 
     at AccessSystemProperty$1.run(AccessSystemProperty.java:9) 
     at AccessSystemProperty$1.run(AccessSystemProperty.java:8) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at AccessSystemProperty.main(AccessSystemProperty.java:6) 

bien vouloir me aider à obtenir une image claire de

1) lorsque nous devons utiliser AccessController.doPrivileged()?. (si SecurityManager est présent, nous utilisons AccessController.doPrivileged pourquoi cela échoue dans l'exemple ci-dessus) 2) quel est l'avantage réel que nous obtenons en utilisant AccessController et PrivilegedAction ?. 3) Avons-nous besoin d'un fichier de règles personnalisé pour l'exemple ci-dessus? Merci, Paul

Répondre

26

Vous utiliseriez AccessController.doPrivileged() pour donner certains privilèges de code que le code plus tôt dans la pile d'appel ON NE SAURAIT mais que les codes privilégiés ont en vertu NE de ce privilège soit accordé dans une politique. Par exemple, supposons que ClassA appelle des méthodes sur ClassB et que ClassB doive lire la propriété système java.home (à utiliser dans votre exemple) et que vous ayez spécifié que SecurityManager est présent selon votre exemple.

Supposons également que ClassB est chargé à partir d'un pot nommé « classb.jar » (mais de faire le travail exemple ClassA est pas chargé de ce pot), ce qui suit devrait être dans le fichier de politique de sécurité:

grant codeBase "file:/home/somebody/classb.jar" { 
    permission java.util.PropertyPermission "java.home", "read"; 
}; 

Maintenant, lorsque ClassB s'exécute et essaie de faire un System.getProperty() qui n'est pas encapsulé dans un AccessController.doPrivileged() sur "java.home". le gestionnaire de sécurité vérifiera la pile pour voir si chaque classe supérieure de la pile a PropertyPermission (directement ou implicitement) pour "java.home". Sinon, l'accès échouera.

Toutefois, si ClassB encapsule System.getProperty() dans un AccessController.doPrivileged(), le gestionnaire de sécurité se soucie seulement que le fichier de stratégie donne ClassB ce privilège et que l'accès est autorisé.

est ici un fragment de montrer ceci:

public void doStuff() { 

    try { 
     /* 
     * this will fail even if this class has permission via the policy file 
     * IF any caller does not have permission 
     */ 
     System.out.println(System.getProperty("java.home")); 
    } catch (Exception e1) { 
     System.out.println(e1.getMessage()); 
    } 
    AccessController.doPrivileged(new PrivilegedAction<Boolean>() { 
     public Boolean run() { 
      try { 
       /* 
       * this will be allowed if this class has permission via the policy 
       * file even if no caller has permission 
       */ 
       System.out.println(System.getProperty("java.home")); 
      } catch (Exception e) { 
       System.out.println(e.getMessage()); 
      } 

      return Boolean.TRUE; 
     } 
    }); 

Ainsi, dans le cas de votre exemple, il vous suffit de spécifier un fichier de politique contenant quelque chose de similaire à la strophe de subvention que j'ai mentionné ci-dessus.

+0

Salut Rob, Merci pour une telle explication claire et détaillée. J'essayais toujours de classe unique, donc je n'étais pas capable de comprendre la différence. Lorsque nous activons le gestionnaire de sécurité par défaut (en utilisant -Djava.security.manager) existe-t-il un fichier de politique utilisé pour restreindre l'accès? (Qui fait partie de JDK) <"> "le gestionnaire de sécurité vérifie la pile pour voir si chaque classe plus haut sur la pile a PropertyPermission ". <"> Ici vous vous référez StackTraceElement [] de Thread.currentThread(). GetStackTrace(); Ou la mémoire Stack? .Pourriez-vous s'il vous plaît expliquer un peu à ce sujet? –

+0

@PaulErric les fichiers de règles par défaut sont définis dans le fichier java.security et sont (généralement) policy.url.1 = fichier: $ {java.home} /lib/security/java.policy policy.url.2 = fichier : $ {user.home} /. java.policy. Ce lien a plus: http://docs.oracle.com/javase/1.4.2/docs/guide/security/PolicyFiles.html#DefaultImpl.Par pile, je veux dire la séquence d'appel des méthodes que vous pouvez voir dans les éléments stacktraceelements. –