axis2のセキュリティポリシー

特に必要性はないのだがふと気になってセキュリティマネージャを有効にしてaxis2のサービスを動かしてみた。


まあSecurityException出まくりで動かないこと(笑)


一つ一つSecurityExceptionを解決しながらとりあえず動くところまでやってみたところ、axis2の動作に必要なポリシーは下記の通り。

grant codeBase "file:/tomcat/webapps/axis2/-" {
  // ログの出力先
  permission java.io.FilePermission "ログ出力フォルダ${/}-", "read, write, delete";
  permission java.util.PropertyPermission "org.apache.axis2.classloader.JarFileClassLoader", "read";
  permission java.lang.RuntimePermission "getProtectionDomain";
  permission java.lang.RuntimePermission "createClassLoader";
  permission java.util.PropertyPermission "java.io.tmpdir", "read";
  permission java.io.FilePermission "${java.io.tmpdir}", "read, write";
  permission java.io.FilePermission "${java.io.tmpdir}${/}-", "read, write, delete";
  permission java.lang.RuntimePermission "getClassLoader";
  permission java.lang.RuntimePermission "setContextClassLoader";
  permission java.io.FilePermission "${java.home}${/}lib${/}wsdl.properties", "read";
  permission java.util.PropertyPermission "org.apache.ws.commons.extensions.ExtensionRegistry", "read";
  permission java.lang.RuntimePermission "shutdownHooks";
  permission java.lang.RuntimePermission "accessDeclaredMembers";
};

これ以外にもcommons-loggingやlog4jが使用しているシステムプロパティなどの設定が要るには要るが、なくてもとりあえずは動く。


困ったのがアーカイブ形式のモジュール。
これらはaxis2の起動時に${java.io.tmpdir}に展開されてそこから読み込む形になるのでcodeBaseの書きようが無い。
まあ下記のようにしてもいいのだが、モジュールはともかくサービスにaxis2ディレクトリ内すべてのread権限を与えるのもどうかと思うので、tomcatのWebappClassLoaderを参考にDeploymentClassLoader#getPermissionsをオーバーライドしてみた。

// アーカイブ形式のすべてのモジュールとサービスにaxis2ディレクトリ以下の読込み権限付与
grant codeBase file:${java.io.tmpdir}/- {
  permission java.io.FilePermission "$[/}tomcat${/}webapps${/}axis2${/}-", "read";
};

org.apache.axis2.deployment.DeploymentClassLoader

private static final String FILE_SEPARATOR = System.getProperty("file.separator");
private Map<String, PermissionCollection> loaderPC = new HashMap<String, PermissionCollection>();
private List<Permission> permissionList = new ArrayList<Permission>();
public void addPermission(String path) {
  path = path.replace('/', FILE_SEPARATOR.charAt(0));
  path = path.replace('\\', FILE_SEPARATOR.charAt(0));
  if (path.endsWith(FILE_SEPARATOR)) {
    path += "-";
  } else {
    path += FILE_SEPARATOR + "-";
  }
  permissionList.add(new FilePermission(path, "read"));
}
@Override
protected PermissionCollection getPermissions(CodeSource codeSource) {
  String codeUrl = codeSource.getLocation().toString();
  PermissionCollection pc;
  if ((pc = loaderPC .get(codeUrl)) == null) {
    pc = super.getPermissions(codeSource);
    if (pc != null) {
      Iterator<Permission> perms = permissionList.iterator();
      while (perms.hasNext()) {
        pc.add(perms.next());
      }
      loaderPC.put(codeUrl,pc);
    }
  }
  return pc;
}

org.apache.axis2.deployment.ModuleBuilder#populateModule

if (System.getSecurityManager() != null) {
  // モジュールアーカイブがあるディレクトリの親ディレクトリの読込みアクセスを付与する
  ((DeploymentClassLoader)module.getModuleClassLoader()).addPermission(new File(((URLClassLoader)this.module.getModuleClassLoader().getParent()).getURLs()[0].getFile()).getParent());
}
if (moduleClassAtt != null) {

org.apache.axis2.deployment.repository.util.DeploymentFileData#setClassLoader

classLoader = Utils.getClassLoader(parent, this.file, isChildFirstClassLoading);
// サービスディレクトリ内の読込みアクセスを付与する
if (classLoader instanceof DeploymentClassLoader && System.getSecurityManager() != null) {
  ((DeploymentClassLoader)classLoader).addPermission(this.file.getAbsolutePath());
}

アーカイブ形式のサービスの設定はまた別。


これでとりあえず設定ファイル等の読込みはできるようになるが、これ以外のpermissionを付与しようと思ったらどうしたらいいのか?
catalina.policyの変更はともかくとして、あるサービス限定のpermissionをaxis2からどうやって設定するか・・・
独自のpolicyファイルを用意して自力で解析するか?