javaのjvm学習ノート12(コントローラにアクセスするスタックチェック機構)

9813 ワード

ローディングを歓迎します。出所を説明してください。http://blog.csdn.net/yfqnihao
                           本節のソースコード:http://download.csdn.net/detail/yfqnihao/4863854
                           このセクションでは、jvmがコントローラにアクセスするスタック検証メカニズムを簡単に説明します。
                           この授業では、私たちはやはり実践を主として、何がスタック検査のメカニズムですか?百回言ったほうがいいです。自分の実際のコードを確認してから、環境を確認します。
                           第一歩は、システム環境を設定する。(copy、少年)
path=%JAVA_HOME%/bin
JAVA_HOME=C:/Java/jdk1.6.0_01
CLASSPATH=.;%JAVA_HOME%/lib/dt.jar;%JAVA_HOME%/lib/tools.jar    
                           第二のステップは、ポリシーファイルの実行環境を設定します。
最初のクラスDorer:
package com.yfq.test;

public abstract interface Doer {
	void doYourThing();
}
第二のクラスFriend:
 
package com.yfq.test.friend;

import java.security.AccessController;
import java.security.PrivilegedAction;

import com.yfq.test.Doer;

public class Friend implements Doer{
	private Doer next;
	private boolean direct;
	
	public Friend(Doer next,boolean direct){
		this.next=next;
		this.direct=direct;
	}
	
	@Override
	public void doYourThing() {
		System.out.println("Im a Friend");

		if (direct) {
			next.doYourThing();
		} else {
			AccessController.doPrivileged(new PrivilegedAction() {

				@Override
				public Object run() {
					next.doYourThing();
					return null;
				}

			});

		}
	}
}
三つ目のクラスStranger:
  
package com.yfq.test.stranger;

import java.security.AccessController;
import java.security.PrivilegedAction;

import com.yfq.test.Doer;

public class Stranger implements Doer {

	private Doer next;
	private boolean direct;

	public Stranger(Doer next, boolean direct) {
		this.next = next;
		this.direct = direct;
	}

	@Override
	public void doYourThing() {
		System.out.println("Im a Stranger");

		if (direct) {
			next.doYourThing();
		} else {
			AccessController.doPrivileged(new PrivilegedAction() {

				@Override
				public Object run() {
					next.doYourThing();
					return null;
				}

			});

		}
	}


}
第四種類のTextFileDisplayer:
import java.io.CharArrayWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import com.yfq.test.Doer;


public class TextFileDisplayer implements Doer{
	String fileName;
	public TextFileDisplayer(String fileName){
		this.fileName=fileName;
	}
	@Override
	public void doYourThing() {
		try {
			FileReader fr = new FileReader(fileName);
			try {
			CharArrayWriter caw = new CharArrayWriter();
			int c;
				while((c=fr.read())!=-1){
					caw.write(c);
				}
				System.out.println(caw.toString());
			} catch (IOException e) {
				e.printStackTrace();
			}finally{
				if(fr!=null){
					try {
						fr.close();
						fr=null;
					} catch (IOException e) {
						e.printStackTrace();
					}
					
				}
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		
	}

}
 
                                ステップ3、メモを参考にします。http://blog.csdn.net/yfqnihao/article/details/8267669FriendとStrangerを梱包して署名し、ecpliseコンパイルディレクトリbin/jarsの下に置いて、生成した鍵の保存ファイルをbinと同じレベルのディレクトリの下に置く。(先に私がアップロードしたソースコードのjarバッグを使ってもいいです。でも、手を動かして練習してください。)
                                 ステップ4で、ポリシーファイルを設定します。
keystore "ijvmkeys.keystore";

grant signedby "friend.keystore" {   
    permission java.io.FilePermission "d:/answer.txt", "read"; 
    permission java.io.FilePermission "d:/question.txt", "read";  
}; 

grant signedby "stranger.keystore" {   
       permission java.io.FilePermission "d:/question.txt", "read"; 
}; 
 

grant codeBase "file:D:/workspace/MyAccessControlerStack/bin/*" {   
    permission java.io.FilePermission "d:/answer.txt", "read"; 
    permission java.io.FilePermission "d:/question.txt", "read"; 
}; 
                                    第五ステップ、新しいクラスを作成します。このクラスにはFriend、Strange、Text FileDisplayerのquestions.txtに対する読み取り権限を検証するための主な関数があります。
import com.yfq.test.friend.Friend;
import com.yfq.test.stranger.Stranger;


public class Example2 {
	public static void main(String[] args) {
		TextFileDisplayer tfd=new TextFileDisplayer("d:/question.txt");
		Friend friend = new Friend(tfd,true);
		Stranger stranger = new Stranger(tfd,true);
		stranger.doYourThing();
	}
}
                                 第六ステップ運転、cmdウィンドウ入力:java-classipath.jars/friend.jar;jars/stranger.jar-Djava.security.manager-Djava.security.policy=D:/workspace/MyAccess ControlerStock/src/myPolicy.txt Example 2
   
説明:
ここからは、コントローラにアクセスするスタックチェック機構を直感的に発見することはできません。Example 2のmain関数を見て、私たちはstrangeがdoYour Thingを実行する時、このような過程を経て、
Example 2------>Apple Class LoaderにProtection domianにロードされます。Example 2において----------は、main関数を実行します。
Text FilDisplayer--->Appless Loaderは、現在のスレッドが搭載タイプText FilDisplayerの権限があるかどうかを判断します。Text FileDisplayer中
Friend--->Apple Class Loaderは、現在のスレッドに搭載タイプText FilDisplayerの権限があるかどうかを判断します。Friendr中()
Stranger--->Apple Class Loaderは、現在のスレッドに搭載タイプText FilDisplayerの権限があるかどうかを判断します。Stranger中
Strangerの例の対象者であるstrangerがdoYour Thing方法を実行します。Friendの実力引用を直接呼び出してdoYour Thing方法を実行します。Friendの実例はTextFileDisplayerのdoYour Thing方法を直接呼び出します。
questions.txtのテキスト内容を出力します。
この過程で、Access Controlerはいったいいつ実行されますか?どうやって実行されますか?下の図を見てみます。
 
上の図はAccess Controler Controletで、つまりコントローラの文脈にアクセスし、それぞれの関数が呼び出された時の保護ドメインの圧着過程を大体説明しました。スタックの一番上にある圧着スタックが終わったら、先進的なルールに従って、Access Controlerは自分のcheckPermission方法を呼び出して、各層の権限を検査します。(上の保護領域配列の中で、BOOTSTRAP保護域というのはシステム保護領域であり、その権限はSecurityConts.ALL PERMISSIONであり、これは彼が何でもできることを意味する)Access Controlerの保護ドメイン配列のメンバーは自分のimplies方法を呼び出します。Protection Domainのimplies方法は先に戦略ファイルが配置されているかどうかを確認します。もしあれば、現在の保護領域をPolicyに渡します。彼が配置ファイルからPermission Collectionを取り出してからPermissionを呼び出して、各Permission検査のimplies方法が設定されていません。特定の設定ファイルは、現在の保護ドメインのPermissionColleconのメンバーのimpliesを直接呼び出して、Permissionのimplies方法を呼び出します。
Examples 2で読み取られたのはquestions.txtテキストであり、また私達の戦略ファイルの中でFriend、Strange、TextFileDisplayerがその読み取り権限を持っているので、順調に実行しました。
                                      ステップ7:私たちの予想が正しいことを確認するために、Example 2を以下のように修正します。
                                      
import com.yfq.test.friend.Friend;
import com.yfq.test.stranger.Stranger;


public class Example {
	public static void main(String[] args) {
		TextFileDisplayer tfd=new TextFileDisplayer("d:/answer.txt");
		Friend friend = new Friend(tfd,true);
		Stranger stranger = new Stranger(tfd,true);
		stranger.doYourThing();
	}
}
ここでは、私たちはquestions.txtをanswer.txtに変えただけです。このファイルについては、Strangerは読み取り権限がないことを知っています。これから実行してみます。
                                        第8ステップ、cmdウィンドウはjava-classpathを入力します。jars/friend.jar;jars/stranger.jar-Djava.security.manager-Djava.security.policy=D:/work space/MyAcControler Stark/srStark/mysc/mysc/mysc.Exple    
私たちはAccess Controler Controtextの図を見に来ました。
前の安全検査は全部通過しましたが、STRANDGER保護ドメインに着いた時は、Stranger'がanswer.txtを読む権限がないので、implies方法はAccess Control Exceptionを投げました。
Access Controlerのスタック検証メカニズムはどのようなメリットをもたらすことができますか?
答えは明らかです。私たちの第七段階のように、権限のないクラスに「破壊」を達成するために、高級な権限を持つクラスを呼び出させようとしています。このような幻想を実現するのは容易ではないが、実現することができないわけではない。次の方法を勉強します。この方法はdoPrivilegedといいます。
                                   第九段階では、上のExampleクラスを修正します。
import com.yfq.test.friend.Friend;
import com.yfq.test.stranger.Stranger;


public class Example3 {
	public static void main(String[] args) {
		TextFileDisplayer tfd=new TextFileDisplayer("d:/answer.txt");
		Friend friend = new Friend(tfd,false);
		Stranger stranger = new Stranger(friend,true);
		stranger.doYourThing();
	}
}
私たちはfriendの初期化パラメータを少し調整しただけです。new Friend(tfd、true)をnew Friend(tfd、false)に変更しました。この調整によってfriendのdoyourThing方法は直接next.doyourThing()を実行するのではなく、Access Controller.doPrived(登録方法)に再入力されました。
                                      第10歩、cmdウィンドウで入力します。java-classpath.jars/friend.jar;jars/stranger.jar-Djava.security.manager-Djava.security=D:/workspace/MyAcceControler Stark/srStark/mc.Explxt 3
アウトプットを表示します。成功した以上、アンスパワー.txtを見る権限がないStrangeがanswer.txtを見る操作を完成しました。これはどういうことですか?もう一度見てみます。先ほどAccess Control Controtxtを示す図です。
私たちはFriendにdoPrivileged()をインストールしていますので、doPrivileged()はこの方法がスタックに押し込まれています。また、Strangerの前で、doPrivileged()が実行されると、私の匿名の内部カテゴリFriendドル1を呼び出して、そのrun方法を実行します。これはBootStrapの呼び出しであることが分かりました。Access Control Control Contectはもう一つの判断を実行し続けます。誰がこのdoPrivilegedをインストールしたかを判断します。だからFreendのdoYourThing()に実行して、answer.txtを開く権限があると判定しました。
このようにすることで、私たちに権限を持たないスランガーが「オフロード」できるようになります。
しかし、オフロードはまだ条件があります。第9ステップのように、「オフロード」を実行する方法スタックフレームは、FriendのdoYourThingのスレッドスタックフレームに組み込まれています。Friendはanswer.txtを読み取る権限を持っています。これによって、run方法に脱獄の機会ができます。
                                   第11ステップ、Example 3を修正して自分の観点を検証します。
import com.yfq.test.friend.Friend;
import com.yfq.test.stranger.Stranger;


public class Example4 {
	public static void main(String[] args) {
		TextFileDisplayer tfd=new TextFileDisplayer("d:/answer.txt");
		Stranger stranger = new Stranger(tfd,false);
		Friend friend = new Friend(stranger,true);
		stranger.doYourThing();
	}
}
                                      第12ステップ、cmdウィンドウはjava-classpathを入力します。jars/friend.jar;jars/stranger.jar-Djava.security.manager-Djava.security.policy=D:/work space/MyAcControler Stark/srStark
異常が発生しました。この異常はstrange$1という内部類の方法スタックフレームがstrangeのdoYour Thingの方法スタックフレームに組み込まれていますが、strangeの保護領域はstrangeという類の対象がanswer.txtのファイルを読み込む権限がないため、runのこの方法は仕方がありません。
まとめ:
            このセクションでは、アクセス制御装置が保護ドメイン権限を検証するプロセスを学んだが、それはスタックのチェック機構(先進的なポスト)をとっており、その各方法は、常にスレッドスタックフレームに関連して呼び出されており、もし私たちが「脱獄」しなければならないならないならば、その予約条件は、doPrivileged()方法のスタックフレームを呼び出して、少なくとも脱獄操作を実行する権限が必要である。
 
writed by:keycoding