Java security managerの探索

29080 ワード

Java security managerの探索
setAccessbleからの導入
今日は前に書いたjava反射に関するコードを見て、最初からよく分からなかった問題を思い出しました.まず問題を引き出したコードを見てみましょう.
MyObject.java
  1. public class MyObject {
  2. public String name;
  3. public int age; public enum SEX {MALE, FEMALE} private SEX sex;
  4. public void sayHello(){
  5. System.out.println("Hello World!"); }
  6. }
  7. Visitor.java

    1. public class Visitor {
    2. public static void main(String[] args){
    3. Class> cls = MyObject.class; //System.setSecurityManager(new SecurityManager()); System.out.println("Security Manager:"+System.getSecurityManager()); System.out.println(System.getProperty("java.security.manager")); System.out.println(System.getProperty("user.dir")); System.out.println(System.getProperty("java.home")); try{ Constructor> constructor = cls.getConstructor(null); Field nameField = cls.getDeclaredField("name"); Field sexField = cls.getDeclaredField("sex"); Object obj = constructor.newInstance(); String name = (String)nameField.get(obj); //as to private member, we must access it by setting Without Java access control check sexField.setAccessible(true);
    4. Enum> sex = (Enum)sexField.get(obj);
    5. System.out.println("initial properties:\r
      "
      + "name:"+name+"\r
      "
      + "sex:"+sex+"\r
      "
      );
      /* * make some change for the properties of Object obj */ nameField.set(obj, "alan"); sexField.set(obj, SEX.MALE); name = (String)nameField.get(obj); sex = (Enum)sexField.get(obj); System.out.println("properties after changed:\r
      "
      + "name:"+name+"\r
      "
      + "sex:"+sex+"\r
      "
      );
    6. }catch(NoSuchMethodException e){
    7. e.printStackTrace(); }catch(Exception e){ e.printStackTrace(); } }
    8. }
    9. , java setAccessible(true), private , ?

      Field, Constructor, Method AccessibleObject, setAccesssible System.getSecurityManager , ,SecurityManager( ) null, override, 。

      , , , , , SecurityManager , 。

      SecurityManager

      , SecurityManager, , Policy , Policy , ${java.home}/jre/lib/java.policy, policy ProtectionDomain , 。

       
        
      1. grant CodeBase "file:///home/alan/*"
      2. { //permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; permission java.util.PropertyPermission "java.security.manager", "read"; //permission java.util.PropertyPermission "*", "read,write"; };
        の はProtectionDomainであり、grantで まるこのような はProtectionDomainであると に できる. の はパスをfile:///home/alan/* したコードには、システム のjava.security.manager を する があります.
        SecurityManagerにはcheckXXXなどの がたくさんあります. えばcheckRead、checkWrite、checkPermissionですが、checkPermissionは によく われています.そこのsetAccessibleではcheckPermissionが び されます.このコードを するときにjava-Djava.security.manager-cp xxx.jar com.xxx.Visitorを すると、デフォルトのpolicyファイルがロードされます.このファイルにはjavaコアが されているapiとextのコードがすべての を っていますが、 のユーザーコードは なシステム の しかありません.これで が されます:java-Djava.security.manager-cp test_sec.jar com.alan.test.security.y.Visitor java.security.AccessControlException: access denied (java.lang.reflect.ReflectPermission suppressAccessChecks) at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374) at java.security.AccessController.checkPermission(AccessController.java:549) at java.lang.SecurityManager.checkPermission(SecurityManager.java:532) at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:107) at com.alan.test.security.y.Visitor.main(Visitor.java:25)
        そのため、 のProtectionDomainを する があります.grant CodeBase "file:///home/alan/*" { permission java.lang.reflect.ReflectPermission "suppressAccessChecks"; permission java.util.PropertyPermission "*", "read,write"; };
        に、java-Djava.security.manager-Djava.security=/path/to/selfpolicy-cp xxx.jar com.xxx.Visitorを すると、 きな が られます.
        ProtectionDomainの
        ProtectionDomainは、AccessControllerによってスタック の び し を することによって られるので、ProtectionDomainの とcheckは、 び しスタックのスタックトップから び しスタックのスタックボトムまで があるか かを する. 、 に するには、すべての び しスタック の する ドメインに が です.そうしないと、 が されます.
        によっては、 び しスタックの (スタックの に い)のコードがコードを することを んでいる がありますが、このコードは び しスタックの では できません.AccessControllerクラスは、 できるコードがより できないコード を するために、doPrivileged()という4つの メソッドを ロードします(この できないコードは び しスタックのより にあり、この を する がありません).doPrivileged()メソッドが び されると、 の のメソッドが び されるように、 しいスタックフレームがスタックに し まれます.アクセスコントローラによって されるスタックチェックでは、1つの>doPrivileged()メソッドによって び されるスタックフレームが、チェックプロセスの を する.doPrivileged()を び すメソッドに けられた ドメインが された を する を っている 、AccessControllerはすぐに ります.これにより、スタックの のコードでもこの を する がない があります.
        の の からのリンクhttp://zhanjia.iteye.com/blog/1842733