argius note

プログラミング関連

復習:セキュリティマネージャ

J2EEサーバでJavaアプリケーションを動作させる場合や、Applet上で実行する場合は、いくつかの機能へアクセスが制限されます。代表的なものを以下に挙げます。

  • プロパティ (java.util.PropertyPermission)
  • ファイル (java.io.FilePermission)
  • ネットワーク (java.net.SocketPermission)
  • ランタイム機能 (java.lang.RuntimePermission)

これは、Javaのセキュリティの仕組みで、セキュリティマネージャ制御下でアプリケーションの動作が制限されるようになっています。初期のJavaでは、"sandbox"モデルというものが使われていました。
(詳細は、Oracle Technology Network for Java Developers | Oracle Technology Network | OracleOracle Technology Network for Java Developers | Oracle Technology Network | Oracle参照)


例として、Fruiをセキュリティマネージャ下で動作させる場合の単純なアクセス権のポリシを示します。

// frui.policy
grant {
    // property
    permission java.util.PropertyPermission "*", "read";
    // local file system
    permission java.io.FilePermission "<<ALL FILES>>", "read";
};
$ java -Djava.security.manager -Djava.security.policy=~/frui.policy \
> -jar /opt/Frui/frui.jar test
$ # =>エラーにならずに実行される


また、アプリケーション側では、アクセスできないリソースにアクセスを試みると、チェックされない例外がスローされてしまいます。

// セキュリティマネージャ制御下で権限なしの場合はチェックされない例外!
String s = System.getProperty("java.home");

セキュリティマネージャ制御下かどうかを調べるには、次のようにします。

SecurityManager security = System.getSecurityManager();
if (security != null) {
    // セキュリティマネージャ制御下
}

チェックされない例外を避けて処理させるには、次のようにします。(あまり良い御手本ではないかも知れません...)

void test() {
    String s;
    if (System.getSecurityManager() != null) {
        // この中だけにすれば冗長さを避けられる
        try {
            // ここだけJava1.5以降の場合
            s = AccessController.doPrivileged(new PrivilegedExceptionAction<String>() {
                public String run() throws Exception {
                    return System.getProperty("java.home");
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
            return; // 脱出
        }
    } else {
        s = System.getProperty("java.home");
    }
    System.out.println(s);
}


おまけ:Stewのポリシファイルも作ってみました。
Stew tutorial - PukiWiki