2017-08-30 42 views
3

一個檢查調整我不能很好地在Java安全管理熟悉,因此想確認我的理解:一個java安全管理器,對於與NO安全管理器除了用於System.exit

我有一個Java進程隨機停止(關閉掛鉤運行),即使沒有人追蹤它的蹤跡。因此,我決定安裝一個安全管理器並覆蓋checkExit(int status)以確保停止的原因不是調用System.exit()。基本上,我寫了這個:

  System.setSecurityManager(new SecurityManager() { 
       @Override 
       public void checkExit(int status) { 
        Thread.dumpStack(); 
        super.checkExit(status); 
       } 
      }); 

我期待我的程序將照常運行,唯一的變化是一個堆棧跟蹤會如果System.exit傾倒()被調用。我發現情況並非如此。它無法啓動與此安全性異常:

java.security.AccessControlException: access denied ("java.util.PropertyPermission" "config" "read") 
     at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472) ~[na:1.8.0_74] 
     at java.security.AccessController.checkPermission(AccessController.java:884) ~[na:1.8.0_74] 
     at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) ~[na:1.8.0_74] 
     at java.lang.SecurityManager.checkPropertyAccess(SecurityManager.java:1294) ~[na:1.8.0_74] 
     at java.lang.System.getProperty(System.java:717) ~[na:1.8.0_74] 
     at Main.main(Main.java:161) ~[na:na] 

看來,安全管理器不復制的默認行爲和閱讀它似乎是它${JAVA_HOME}/jre/lib/security/java.policy這是相當嚴格的應用下,默認的策略之後。

當沒有安全管理器時,Java的真正默認行爲是什麼?是「允許一切」還是有其他事情發生?

如果我想複製默認行爲,除了上面的單個調整之外,應該如何安裝作爲安全管理器?

在最後一點上,我可以看到System.setSecurityManager()實際上預計java.lang.SecurityManager的實例,這意味着我被迫使用該實現(依賴於策略文件)。重寫該類中的方法以複製NO安全管理器的實際默認行爲的最有效方式是什麼?

編輯:按照下面的討論,這似乎做

  System.setSecurityManager(new SecurityManager() { 
       @Override 
       public void checkPermission(Permission perm) { 
        return; // no security manager behaviour 
       } 

       @Override 
       public void checkPermission(Permission perm, Object context) { 
        return; // no security manager behaviour 
       } 

       @Override 
       public void checkExit(int status) { 
        Thread.dumpStack(); 
        super.checkExit(status); 
       } 
      }); 

回答

2

你困惑。

看來,安全管理器不復制的默認行爲和閱讀它似乎是它在$ {JAVA_HOME} /jre/lib/security/java.policy這是相當嚴格的應用默認的策略之後。

一個SecurityManager的默認行爲是服從的Javadoc規定的合同,除通過默認.policy文件,這的確是非常嚴格的許可。安全管理器的缺席的默認行爲是允許任何事情和一切。

當沒有安全管理器時,Java的真正默認行爲是什麼?是否'允許一切'

是的。

還是還有其他事情發生?

No.

我應該安裝哪一個安全管理器,如果我想從以上單一調整複製的默認行爲,分開?

的安全管理器,它正是這麼做的。如果你希望它除了你已經實現的一個覆蓋以外什麼也沒有執行,你必須爲所有其他方法提供空的覆蓋。

+0

從javadoc:特殊方法'SecurityManager.checkPermission(java.security.Permission)'確定是否應該授予或拒絕由指定權限指示的訪問請求。默認實現調用 'AccessController.checkPermission(燙);' 它是安全的只是覆蓋'的checkPermission()',使其立即返回?編輯:有是的checkPermission()方法,並在看我的來源應該是確定的,如果我只是覆蓋這些2. – Alexandros

+0

不,你應該這樣它會返回重寫它除了*的兩個變種*中的'Permission'你的情況想通過調用'super.checkPermission()'並轉儲堆棧跟蹤來檢查。這當然很明顯? – EJP

+0

但我不希望(當不存在安全管理的java的默認行爲)來檢查什麼。所以,因爲一切都委託給的checkPermission,最小的變化有一個「DoNothingSecurityManager」將覆蓋只是2種方法?因此,使用第三次重寫來轉儲checkExit()上的堆棧跟蹤,我應該很好(現在檢查這個)。 – Alexandros