1

ユーザーエクスペリエンスを向上させるために、ユーザーがサードパーティの「プラグイン」をロードできる Java アプリケーションがあります。これらのプラグインで使用するための API は存在しますが、サードパーティ ソフトウェアは、セキュリティのために内部アプリケーション クラスへのアクセスを制限する必要があります。プラグインに制限されたパッケージは「com.example」で、許可されたパッケージは「com.example.api」です。API クラスは、難読化された内部クラスを呼び出します。

これを調査した後、 SecurityManager のいくつかのメソッド、checkMemberAccess(Class, int)checkPackageAccess(String)に出会いました。どちらも私の目標への実行可能なパスのようです。しかし、いくつかのテストとさらなる調査を行った結果、checkMemberAccess はリフレクション呼び出しにのみ適用され、checkPackageAccess はクラス ローダーが loadClass を呼び出したときにのみ呼び出されることがわかりました。

パッケージへのアクセスを制限する合理的な方法は何ですか (com.example.api ではなく com.example)?

4

1 に答える 1

2

プラグイン用のカスタム クラス ローダーを作成することをお勧めします。これにより、com.exampleそのクラス ローダーを使用してロードされたクラスからパッケージの存在が隠されます。通常、クラス ローダーはその親に委譲しますが、実際には、一部のみ、またはまったく委譲しない実装がいくつかあります。たとえば、アリはこの手法を使用していると思います。このようなクラス ローダーでロードすると、禁止された機能にリンクされたクラスはロードに失敗します。または、実装が遅延リンクを使用し、正常にロードされた場合でも、禁止されたコードの実行中に失敗します。

禁止されたパッケージへのリンク時のプラグイン アクセスを拒否すると、SecurityManager を使用して、リフレクションを介したランタイム アクセスを拒否したり、新しいクラス ローダーを回避するために使用される可能性のある新しいクラス ローダーの作成を拒否したりできます。

class RestrictingClassLoader extends URLClassLoader {
  @Override
  public Class<?> loadClass(String name) throws ClassNotFoundException {
    if (!name.startsWith("com.example.") || name.startsWith("com.example.api."))
      return super.loadClass(name);
    return findClass(name);
  }
}

class RestrictingSecurityManager extends SecurityManager {
  private boolean isRestricted() {
    for (Class<?> cls: getClassContext())
      if (cls.getClassLoader() instanceof RestrictingClassLoader)
        return true;
    return false;
  }
  // Implement other checks based on isRestricted().
}
于 2012-07-23T09:19:40.570 に答える