2012-01-02 4 views
21
私はJavaのセキュリティとAccessController.doPrivilegedの()の使用 の基本を理解しようとしています

私は、サンプルプログラムを開始し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; 
      } 
     } 
     ); 
    } 
} 

私はデフォルトのセキュリティを使用してコード上で実行しようとした場合、私はにAccessControlExceptionを取得しています管理 私のスタックトレースは

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) 
親切

1の鮮明な画像を得るために私を助けていますAccessController.doPrivileged()を使用する必要がある場合)?(SecurityManagerが存在する場合、上記の例ではこれがなぜ失敗しているのかAccessController.doPrivilegedを使用します) 2)AccessControllerおよびPrivilegedActionを使用して実際に得られる利点は何ですか? 3)上記の例のためにカスタムポリシーファイルが必要ですか? おかげで、 ポール

答えて

26

あなたは()のコードは、以前の呼び出しスタックの必要はないが、その特権コードがポリシーで許可されているその特権のおかげで持っている特定のコードの権限を付与するためにAccessController.doPrivilegedのを使用します。

たとえば、ClassAがClassBでメソッドを呼び出し、ClassBがjava.homeシステムプロパティを読み込み(例から借用する必要がある)、あなたの例に従ってSecurityManagerが存在すると指定したと仮定します。

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

はまた、ClassBのは「classb.jar」という名前のjarファイルからロードされます(ただし、例がにClassAがその瓶からロードされていない動作させるために)ことを前提とし、以下では、セキュリティポリシーファイルにする必要があります

ClassBが実行され、 "java.home"上のAccessController.doPrivileged()でラップされていないSystem.getProperty()を実行しようとします。セキュリティマネージャはスタックをチェックして、スタック上の上位のすべてのクラスが "java.home"のPropertyPermission(直接か暗黙かに関わらず)を持っているかどうかを調べます。そうでない場合、アクセスは失敗します。

ただし、ClassBがAccessController.doPrivileged()にSystem.getProperty()をラップすると、securitymanagerはポリシーファイルがClassBにその特権を与えてアクセスが許可されていることを気にします。ここで

はこれを表示するフラグメントです:

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; 
     } 
    }); 

は、だからあなたの例の場合、あなたはちょうど私が上記の参照の許可スタンザに似たものを含むポリシーファイルを指定する必要があります。

+0

こんにちはロブ、そのような明確で詳細な説明に感謝します。私はいつもシングルクラスからやっていたので、違いを理解することはできませんでした。既定のセキュリティマネージャ(-Djava.security.managerを使用)を有効にしているときに、アクセスを制限するために使用されるポリシーファイル(JDKの一部)があります "セキュリティマネージャはスタックをチェックして、スタックの上位にはPropertyPermissionがあります。 <">ここではStackTraceElement []をThread.currentThread()。getStackTrace();から参照しています。またはスタックメモリ?あなたはこれについて少し説明してください。 –

+0

@PaulErricデフォルトのポリシーファイルはjava.securityファイルで定義され、通常はpolicy.url.1 = file:$ {java.home} /lib/security/java.policy policy.url.2 = fileです。 :$ {user.home} /。java.policy。このリンクの詳細は、http://docs.oracle.com/javase/1.4.2/docs/guide/security/PolicyFiles.html#DefaultImplを参照してください。スタックとは、stacktraceelementsで見ることのできるメソッドの呼び出しシーケンスを意味します。 –