Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

署名付きアプレットでのaccess denied (java.io.FilePermission)について

はじめまして。
Hughesと申します。

別サイトでも同様の質問をしているのですが、併せてこちらにも質問を書き込ませていただきます。

「てめーがっつくなよ!」と不快な思いをさせてしまった場合は大変申し訳ありません・・。

以下、別サイトで投稿した内容をコピペします。
どなたか参考になる事だけでもあれば、是非ともご享受お願い致します。

====================================
はじめまして。
Hughesと申します。

今回、掲題の件についてかなり悩んでおり、色々と調査をしたのですが、解決策がどうしても見つからない為、皆様のお力をお借りしたく書き込みさせていただきました。
半分、泣きが入っている状態です・・・。


現在、Applet を作成しており、Applet にファイルをドロップして画像を貼り付けた後、その Applet から HTTPClientAPI を用いて Servlet にファイルを転送するというような処理が走っております。
大きな処理の流れとしては以下のようになります。
1.アプレット画面(JSPに貼り付けている)にローカルの画像を貼り付ける
 (その際、ファイルのパスを保持しております)
2.保持したパスを元にファイルを取得(Fileオブジェクトを生成)
3.HTTPClientを用いて稼動中のServletにHTTPRequest(POST)に取得したファイルを添付して転送

この3の部分の、HTTPRequestにファイルを添付する際に、掲題の例外が発生しております。

署名付きアプレットですので、AllPermissionがもらえるはずなので、Fileの読み書きはできているのですが、何故か添付する際に例外が発生してしまいます。

その際のコードの記述は以下のようになっております。
------------------------------------------------
01: File srcFile = new File("C:/temp/sample.jpg");
02: 
03: PostMethod postMethod = new PostMethod("http://localhost/app/FileTrans";);
04: 
05: FilePart filePart = new FilePart("UploadFile", srcFile, null, "Shift_JIS");
06: Part[] part = {filePart};
07: postMethod.setRequestEntity(new MultipartRequestEntity(part, postMethod.getParams()));
------------------------------------------------
上記コードの05行目で当例外が発生しております。

どなたか解決策、または何か知っている事がございましたら、何卒ご享受お願い致します。 

22

回答

6815

閲覧

22件の回答

評価

0

すみません、肝心の例外の内容を記述し忘れていました。
以下にアプレットが吐き出したその時のエラーログを記述します。
------------------------------------
java.security.AccessControlException: access denied (java.io.FilePermission C:\temp\sample.jpg 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.checkRead(Unknown Source)
    at java.io.File.isFile(Unknown Source)
    at org.apache.commons.httpclient.methods.multipart.FilePartSource.<init>(FilePartSource.java:67)
    at org.apache.commons.httpclient.methods.multipart.FilePart.<init>(FilePart.java:144)

評価

0

「AccessControlException ローカルファイル アプレット」で検索してみました。
最初に引っかかったところにそれっぽいものが。


>「てめーがっつくなよ!」と不快な思いをさせてしまった場合は大変申し訳ありません・・。
こちらも、「マルチポスト」で検索されると良いでしょう。
不快になるかどうかは人によりますけどね。

評価

0

mio様

ご回答ありがとうございます。
ご提示いただいたサイトですが、実はもうここらへんのサイトは見尽くしておりまして・・。
私の説明に不足がありました為、お手間を取らせて申し訳ありませんでした。

以下、追記とさせて頂きます。

【条件】
・java.policy (Javaポリシーファイル)は使用しない
 (各端末にポリシーファイルを配布するのが不可能な為)

【判明している事】
・ポリシーファイルをローカルに置いて実行した場合は正常に動く
・ローカルアプレットビューワで実行した場合は正常に動く
・ローカルでHTMLファイルにアプレットをベタ貼り(<object>タグを使用)で実行した場合は正常に動く


今回の実行環境は、WEBサーバ上にアプレットのjarを配置し、それをJSPにベタ貼りしてアプレットを呼び出しております。
つまりは、サーバからアプレットを通して、ローカルファイルを読み込むといった内容になります。(あくまでイメージです)

なお、別システムにおいて、似たような形式のアプレットが存在するのですが、そちらは正常に動作しました。(ファイルの転送が成功しました)
記述内容はほぼ同じにしているのですが、何故か今現在作っているアプレット側だけが動きません。

強いて言えばその別のアプレットは、HttpClientAPIにおいて、非推奨のクラスを使っている事くらいです。
(これも試してみましたがダメでした)

唯一違う物と言えば、電子署名のstoreファイルが違う事くらいでしょうか・・・。
署名そのものに、ポリシーの設定(各権限の設定)ができるとは思えず、こちらの方は別storeファイルを用いております。


拙い文章の為、読みにくい・わかりにくい箇所が多々あるかと思いますので、お気づきの点またはご不明な点がございましたら、ご指摘お願い致します。

評価

0

>色々と調査をした
という文章からは、何をやったのかが分かりませんので。「やってない」と見なされても仕方がないです。

>【条件】
>【判明している事】
このへん、滅茶苦茶重要なんですが…。どこで質問するにしても、これがあるとないとでは大違いです。

ただ、ローカルで起動するHTMLではローカルにアクセスできるのが当たり前なので、それは意味がない気がしますが。

>唯一違う物と言えば、電子署名のstoreファイルが違う事くらいでしょうか・・・。
電子署名については詳しくないんでなんとも言えませんが、うまくいくものと違うものがあるなら、
その全てについて、「〜だろう」という前提条件なしに実験して結果を見てみるのが、先決じゃないでしょうか。

評価

0

さらに追記です。

現在、このアプレットにドロップされた画像に対し、アクセスをしてるであろう箇所は3箇所ございます。

1.ドロップ時、画像のサムネイルをアプレット上に表示する時
2.Fileオブジェクト生成時
3.Multipartに画像(2のファイル)を添付する時

もしかしたら2のタイミングで実際にファイルにアクセスしてるのかは私の中の知識では曖昧ですが、1に関してはきっちりとサムネイルは表示されております。
従って、この時点ではファイルは読み込めてるのではないかと思うのですが・・・やはり3のところで読み込めないというエラーが発生してしまいます。

また、FilePartクラスをnewする時に発生していますが、ソースを追ったところ(ログに書いてありますけど・・)、FilePartSourceクラスの中で、受け取ったFileオブジェクトのisFile()メソッド実行時に当該事象が発生しているようです。

評価

0

mio様

ご回答・ご指摘ありがとうございます。

>>【条件】
>>【判明している事】
>このへん、滅茶苦茶重要なんですが…。どこで質問>するにしても、これがあるとないとでは大違いです。

まさに仰る通りだと思います。
あまりこういった場を利用する事がないので、何を書けば伝わりやすいか?という知識が欠けておりました。
以降、これらにも十分気をつけたいと思います。


>storeファイルが違う

これについてですが、その別アプレットで使っている署名ファイルは、過去の遺産みたいになってまして既に入手が不可能になっているのです・・。

仕方がないので、自己署名という形で、新たに署名ファイルを生成して、アプレットJARに紐付けた次第です。

評価

0

>2.Fileオブジェクト生成時
少なくとも、この時点では何もしてません。
でなければ、#exists()や#createNewFile()は存在できませんから。

評価

0

>なお、別システムにおいて、似たような形式のアプレットが存在するのですが、そちらは正常に動作しました。(ファイルの転送が成功しました)

同様のシステムでちゃんと動く物があるのであれば、今回の物でも同じ環境にしてやれば動くはずです。

その動くシステムはJDK1.1時代の物でしょうか?
JDK1.2いわゆるJava2以降セキュリティの考え方は大幅に変わっていますので、そういった環境の違いがあるのであれば動かないかも知れません。

ちゃんと動くシステムは、今回の動かないクライアントの環境でも動くのでしょうか?

javaコンパイラはclassファイルの互換性を1.1時代にすることができるのでEclipseでしたらコンパイラーの準拠レベルを1.3にしてみる価値はあるかもしれません。
これでclassファイルは1.1互換となります。

Javaのセキュリティの変遷については以下で確認できます。
http://java.sun.com/j2se/1.5.0/ja/docs/ja/guide/security/spec/security-spec.doc1.html

評価

0

こんにちわ。
ふと気になったのですが、WebサーバはUnix系でしょうか。

なんとなく、アクセス権限(ls -al で見ることの出来るアレ)
で引っかかっている気がするのですが。

Unix系だと、ユーザ毎、ファイル毎、ディレクトリ毎に権限ありますから。


Unix系だとしたら
 ・ファイルの権限(otherにrが付くか)
 ・ディレクトリの権限(otherにrが付くか)
を確認すると良いでしょう。


Unix系でないとしたら、横槍入れて申し訳ないです>ALL

評価

0

>java.security.AccessControlException: access denied (java.io.FilePermission C:\temp\sample.jpg read)
を見る限り、Unixではないようです。

考えられるのは、それアプレットのメソッドをJavaScript経由で呼び出していませんか?
JavaScript経由で呼び出すアプレットのメソッドは、たとえ署名付気アプレットでもAllPermissionにはなりません。

評価

0

<皆様>

ご回答・ご指摘誠にありがとうございます。
また、返信が遅れました事、深くお詫び申し上げます。


<mio様>

>回答内容 >2.Fileオブジェクト生成時
>少なくとも、この時点では何もしてません。
>でなければ、#exists()や#createNewFile()は存在できませんから。 

そうですよね・・。
自分で投稿後に気付き「馬鹿な事言っちゃったなぁ・・」と反省致しました。

つまりは、3の部分で初めてローカルファイルに対してアクセスしてるという事になりそうなわけですね。
サムネイルのところとは只今確認をしたところ、Fileクラスからパスだけ取得している状態でした。


<tama様>

>ちゃんと動くシステムは、今回の動かないクライアントの環境でも動くのでしょうか?

はい、私の端末から、直接ローカルファイルをアップロードする事ができました。


>その動くシステムはJDK1.1時代の物でしょうか?
>JDK1.2いわゆるJava2以降セキュリティの考え方は大幅に変わっていますので、そういった環境の違いがあるのであれば動かないかも知れません。
>javaコンパイラはclassファイルの互換性を1.1時代にすることができるのでEclipseでしたらコンパイラーの準拠レベルを1.3にしてみる価値はあるかもしれません。
>これでclassファイルは1.1互換となります。

はい、その通りです。
この「動くシステム」は、JDK1.1時代の代物です。

Java2以降のセキュリティの考え方が大幅に変わっているというのは知りませんでしたので、これは是非試してみたいと思います。


<すったか様>

>ふと気になったのですが、WebサーバはUnix系でしょうか。

WebサーバはUnix系でございます。
ただし、今回の事象の場合は、サーバ上のファイルにアクセスしているのではなく、クライアント(端末)のファイルにアプレットからアクセスをしております。
ちなみに、クライアントは全部Windowsとなっております。


<つばさ様>

>考えられるのは、それアプレットのメソッドをJavaScript経由で呼び出していませんか?
>JavaScript経由で呼び出すアプレットのメソッドは、たとえ署名付気アプレットでもAllPermissionにはなりません。 

これについても一度調査を致しました。(すみません書き忘れていました・・)

”JavaScript経由で呼び出すアプレット”というものがどうもイメージが湧き辛くて・・。
よろしければ、具体的な内容を教えて頂けないでしょうか?

現在のこちらのアプレット呼び出し周りの作りとしては以下のような形になっております。

------------ A.jsp ---------------
<body>
    <input type="button" value="applet" onClick="javascript:window.open('B.jsp');">
</body>
----------------------------------

-------------B.jsp ---------------
<body>
    <object name="applet" classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" width="200" height="200">
        <param name="codebase" value="applet/">
        <param name="archive" value="applet.jar,commons-codec-1.3.jar,commons-httpclient-3.0.1.jar,commons-logging.jar">
        <param name="code" value="applet.ImageDrop.class">
        <param name="type" value="application/x-java-applet;jpi-version=1.4.2">
        No Java 2 SDK, Standard Edition v 1.4.2 support for APPLET!!
    </object>
</body>
----------------------------------

なお、コードは割愛して書いております。
何卒、ご了承下さいませ。

評価

0

tama様

コンパイル準拠レベルは既に1.3となっておりました・・。
ずっと1.4でしてると思っていたのでちょっぴりショックでした。

評価

0

なるほど・・
1.1用のクラスだとjava.lang.SecurityManagerとかは呼ばれないような記憶があったのですが気のせいだったのかなー

あとは org.apache.commonsのjarが1.1用じゃないとか。
だから、ファイルは読めるけどPOSTできないってことですかね?

動いている方のjarを使ってみたらどうでしょう

評価

0

jarsigner -verify -verbose hoge.jar
で利用しているjarを動いているものと比較してみて署名の内容を確認するのもいいかもしれません。

評価

0

tama様

ご指摘の通り、commons-httpclientが、1.1用のものではありませんでしたので実際に試してみました。

動いてる方のjarに入れ替えて、再度実行したのですが、同様の事象が発生してしまいました・・。(try1)

ちなみに、コンパイル準拠レベルを1.4にして、commons-httpclientは新しいものを使用して実行してみましたら、こちらも同様に動作致しませんでした・・。(try2)

実行環境は以下の通りでした。

--- try 1 ---
コンパイル準拠レベル 1.3
commons-httpclient-2.0.2
commons-logging

--- try 2 ---
コンパイル準拠レベル 1.4
commons-httpclient-3.0.1
commons-codec-1.3
commons-logging

評価

0

うーん、同じ環境にすれば動くと思ったんですが、なぜでしょう・・

実際はコンパイラも違うでしょうし
あと違うとすると署名ツールくらいですか
1.1時代はjavakeyツールで署名してたはずなので・・
http://java.sun.com/j2se/1.4/ja/docs/ja/tooldocs/win32/jarsigner.html
この当たりを参考にして調べるしかないですかね

ところで、その動く方のソースをコンパイル準拠レベル 1.3でコンパイルして署名したら動くんですか?
動かないのであれば今の環境では無理かも知れません。
そうなると、当時のJDKでコンパイルするくらいしか思いつきません。

評価

0

tama様

実際に動いているjarの署名内容を確認致しました。
そのjarを取得するのにちょっと手間が掛かってしまった為に返信が遅れまして申し訳ありません。

結果だけを申しますと、署名内容は全く一緒でした・・。
アルゴリズムさえも一緒でした。


>ところで、その動く方のソースをコンパイル準拠レベル 1.3でコンパイルして署名したら動くんですか?

こちらにつきましては、試すことは不可能なんです。
具体的な事情はお書きする事は出来ませんが、一言で言うとこのjarが動く環境を作る事が無理なんです。

それとまた書き忘れていたのですが、特権モード?というものでも実行してみましたが、その時も動きませんでした。

評価

0

先にも書いたように、当時のJDKでコンパイルするくらいしか思いつきません。
まあ、今やっていることは弱い1.1のセキュリティーの元でポリシーファイルも無し、かつオレオレ証明書で動かそうとしているわけで。
実際に動いている物があるんだから、動くはずが元になっていますから、当時に戻るしかないように思います。

RSA証明付きアプレットにするのであれば、現在の環境でも可能だと思いますが・・
いわゆるCA証明書発行局(VeriSignなど)から証明書を正式に発行してもらう必要がありますし、維持にお金も掛かります。
VeriSignなどのデジタル証明書はJREにはじめからインストールされているので、ユーザが利用を認証すればAllPermissionがもらえるはずです(使ったこと無いので分かりませんが・・)

RSA証明付きアプレットでオレオレ証明書を作って自己証明しても、AllPermissionは与えられず結局ポリシーファイルが必要になるようです。

参考になるか分かりませんが、こちらもご覧下さい。
http://sdc.sun.co.jp/java/docs/products/plugin/1.3/docs/ja/rsa_signing.html

評価

0

やっと解決しました!!!!

すみません、これからすぐに動くやつを組み込まなければいけませんので、後で必ずきちんと詳細報告を致します。

先立ってお知らせ致しました。

評価

0

まず結論から述べると、JSPの<object>タグのarchive属性で指定しているJARファイル全てに署名をする事で動作致しました。

・applet.jar は commons-httpclient-3.0.1.jar に依存
・commons-httpclient-3.0.1.jar は commons-logging.jar と commons-codec-1.3.jar に依存


以上を踏まえた上で、applet.jar のみに署名を施している場合
・applet.jar のクラス内ではローカルファイルへのアクセスは可能
・commons-httpclient-3.0.1.jar のクラス内でのローカルファイルへのアクセスは不可能

という事象が起因で例外が発生していたようです。


こちらの拙い説明にもかかわらず、ご指摘・アドバイスを頂けたmio様、tama様、すったか様、つばさ様、本当に本当に有難うございました。

評価

0

なるほど、そういうことでしたか
てっきり全部に署名しているとばっかり思ってました^^;
解決して何よりです。

評価

0

そうですよね。
私の説明だと、applet.jarにしか署名してないというのは伝わらないですよね。

私の至らなさで皆様の大事な時間を割いた事、深くお詫び致しますと共に、改めてお礼を申し上げます。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。