Java security managerの探索
29080 ワード
Java security managerの探索
setAccessbleからの導入
今日は前に書いたjava反射に関するコードを見て、最初からよく分からなかった問題を思い出しました.まず問題を引き出したコードを見てみましょう.
MyObject.java
setAccessbleからの導入
今日は前に書いたjava反射に関するコードを見て、最初からよく分からなかった問題を思い出しました.まず問題を引き出したコードを見てみましょう.
MyObject.java
public class MyObject {
public String name;
public int age;
public enum SEX {MALE, FEMALE}
private SEX sex;
public void sayHello(){
System.out.println("Hello World!");
}
}
Visitor.java
public class Visitor {
public static void main(String[] args){
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);
Enum> sex = (Enum)sexField.get(obj);
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
");
}catch(NoSuchMethodException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
}
}
, 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 , 。
grant CodeBase "file:///home/alan/*"
{
//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