目次 | 前の項目 | 次の項目 | JNDI API |
JNDI には、セキュリティマネージャをインストールする場合とインストールしない場合の主に 2 種類の設定があります。
セキュリティマネージャをインストールしないで Java アプリケーションを実行している場合は、信頼されたコードとしてローカルクラスパスからサービスプロバイダにアクセスできます。サービスプロバイダがローカルファイルにアクセスしたり、ネットワーク上の任意の場所にあるネーミングサーバまたはディレクトリサーバにネットワーク接続したりするときにも、制限は存在しません。
インストールされたセキュリティマネージャとともに動作するアプレットまたはアプリケーションの場合は、同じアプレットまたはアプリケーション内で、信頼されたコードと信頼されていないコードが混在します。この場合は、「コンテキストハンドルの共有」および「コンテキスト環境」を参照してください。インストールされたセキュリティマネージャとともに動作するアプレットまたはアプリケーションでは、サービスプロバイダにアクセスするときにさまざまな制限が適用されます。 特に、リソースが限られている場合 (ファイルシステム、ネットワーク接続など) は、大きく制限されます。
JNDI パッケージのクラスには、ネイティブメソッドは組み込まれていません。これらのクラスは、アプレットまたはアプリケーション内で実行するときに、特にインストールする必要はありません。
JNDI では、いくつかのシステムプロパティが使用されます (「アプリケーションスコープまたはアプレットスコープの JNDI 標準プロパティ」を参照)。システムプロパティを使用すれば、プログラミングをほとんど行わずに、アプレットおよびアプリケーションを簡単に構成することができます。ただし、アプレットまたはアプリケーションが実行されているプラットフォームにセキュリティマネージャをインストールした場合は、そのアプレットまたはアプリケーションから一部またはすべてのシステムプロパティへのアクセスが制限されることがあります。JNDI では、これらのプロパティを、リソースファイルのアプレットパラメータ、またはコンテキストに渡す環境プロパティとして指定できます。
Java 2 プラットフォームでは、JNDI クラスは「アプリケーションスコープまたはアプレットスコープの JNDI 標準プロパティ」内のシステムプロパティにアクセスするときに、
doPrivileged
ブロックを使用します。
JNDI には、ネーミングサーバおよびディレクトリサーバにアクセスするための、セキュリティモデルまたは共通のセキュリティインタフェースが定義されていません。ディレクトリサービスに対する認証またはアクセス制御に必要な操作など、セキュリティ関連の操作は、各サービスプロバイダによって処理されます。JNDI では、サービスへの接続を確立するときに、アプリケーションまたはアプレットからセキュリティ関連の情報をサービスプロバイダに渡すことができます。 ただし、JNDI 自体は、セキュリティ関連の動作には関与しません。
JNDI では、セキュリティ関連の問題は、セキュリティ関連の例外としてクライアントに通知されます。
JNDI サービスプロバイダは、ファイルシステムまたはネットワークなどの保護されたリソースにアクセスするときに、セキュリティマネージャによって適切に制御されます。一部のサービスプロバイダでは、Java 2 プラットフォームのセキュリティアーキテクチャによってディレクトリアクセスが制御されます (たとえば、管理関連のアプレットで特別なポートへのアクセスを可能にするなど)。
ネームサービスおよびディレクトリサービスには通常、格納されている情報を保護するための独自のセキュリティシステムが組み込まれています。たとえば、特定のディレクトリでは、ディレクトリ内の情報の読み取りまたは更新を行うときに、最初にディレクトリに「ログイン」する必要があります。一部のサービスでは、名前空間またはディレクトリの特定の部分に匿名でアクセスすることができます。
セキュリティ上の理由により、サービスにログインしたあとで、信頼されていないコードと特権を共有しないようにする必要があります。
ここでは、
Context
インスタンスへの参照を、「コンテキストハンドル」と表現します。これは、Reader
、Writer
、InputStream
、およびOutputStream
インスタンスへの参照が、「ファイルハンドル」と呼ばれることと似ています。コンテキストハンドルは、その他の保護されたリソースと同様に処理する必要があります。信頼されたコードによってコンテキストハンドルが取得された場合は (アクセスはディレクトリサーバで認証される)、認証または信頼されていないコードに対してそのコンテキストの使用が保護されます。これは、アプリケーションまたはアプレットのコード、あるいはその両方によって、ファイルハンドルが保護されることと似ています。たとえば、信頼されたコードによって出力ファイルが開かれた場合 (特権は、コードの信頼性に基づいて与えられる)、ファイルハンドルをその他コードに渡すときには、コードの信頼性に注意する必要があります。
また、コンテキストハンドルのアクセス権を信頼されていないコードに与えると、ディレクトリ内の情報に対してアクセスまたは更新を行うとき、あるいはコンテキストに関連付けられたセキュリティ環境プロパティにアクセスするときに、そのコンテキストハンドルが不正に使用されることがあります。
JNDI では、環境に応じた形式で、アプリケーションまたはアプレットからコンテキストに設定および情報を渡すことができます。アプリケーションまたはアプレットでは、コンテキストから現在の環境を取得することもできます。コンテキストの環境の詳細は、「構成」および「付録 A」を参照してください。
コンテキストの環境に含まれている情報は、重要なものが多く、信頼されていないアクセスから保護する必要があります。特に、環境プロパティ
java.naming.security.principal
およびjava.naming.security.credentials
には、信頼されていないコードには渡してはならない情報も含まれています。サービスプロバイダには、これらのプロパティに対するアクセスを防止するための対策が必要です (「サービスプロバイダに必要な操作」を参照)。重要な環境プロパティは、クライアントアプリケーションおよびアプレットから信頼されていないコードに渡さないようにする必要があります。
JNDI が JDK 1.1.x プラットフォーム上で動作しているときは、RMI クラスローダが使用されます。クラスは、セキュリティマネージャがインストールされ、ロードが許可されている場合にだけロードできます。このようなクラスがロードされると、セキュリティマネージャに定義したセキュリティコンテキスト内で実行されます。
JNDI が Java 2 プラットフォーム上で動作しているときは、
java.net.URLClassLoader
によって、コードベースに指定されている位置からクラスがロードされます。 クラスのロードを正常に行うには、アプリケーション、JNDI クラス、およびサービスプロバイダのクラスに対して、コードベースに指定されている URL に応じて許可を与える必要があります。たとえば、URL スキーマが「http」または「ftp」の場合は、適切なjava.net.SocketPermission
をアプリケーションに与える必要があります。 URL スキーマが「file」の場合は、java.io.FilePermission
を与える必要があります。
いくつかの JNDI クラスは、直列化することができます。直列化すると、バイトストリームの形式でオブジェクトにアクセスできます。 このとき、作成された環境の外部からアクセスすることもできます。直列化されたオブジェクトに関連したセキュリティについては、次の URL にあるドキュメントを参照してください。
http://java.sun.com/products/jdk/1.2/ja/docs/ja/guide/serialization/spec/security.doc.html
初期コンテキストの取得またはルックアップを行うか、ディレクトリから初期コンテキストを作成したときに、コンテキストハンドルが作成されます。 そのコンテキストハンドルに対して環境プロパティを指定できます。コンテキストハンドルの作成されるときに、セキュリティ関連のプロパティが必要になることがあります (ディレクトリ内のユーザの「ログ」を記録するユーザ情報など)。サービスプロバイダでは、信頼されていないコードから重要な情報を保護する必要があります。
サービスプロバイダでは、コンテキストの環境を、信頼されていないコードによる改変または変更から保護する必要があります。また、重要な環境プロパティを、信頼されていないコードによる読み取りから保護する必要があります。これらを保護するにはいくつかの方法があります。 たとえば、スレッドの実行コンテキストまたは信頼レベル、あるいはその両方が、コンテキストハンドルを作成したスレッドの初期属性と異なる場合は、そのコンテキストハンドルの使用を禁止します。または、重要な環境プロパティへのアクセスなど、特定の操作を禁止します。あるいは、重要な環境プロパティを返さないか信頼されたコードにだけ返します。
信頼されていないコード (信頼されていないアプレットのコードなど) は、ネットワークへのアクセスが制限されています。たとえば、信頼されていないアプレットからは、ダウンロード元のホスト以外にはネットワーク接続を作成できません。セキュリティモデルをより詳細に調整すると、サービスプロバイダ自体から、信頼されたコードとして、信頼されていないアプレットからは接続できないホストに接続することができます。この場合、サービスプロバイダでは、セキュリティマネージャに定義されているセキュリティが低下しないように注意する必要があります。信頼されていないアプレットからディレクトリにアクセスしても、セキュリティ上の問題が発生しないことが保証されている場合は、信頼されていないコードに対してサービスを提供することもできます。たとえば、信頼されていないコードからディレクトリに対する「匿名」のアクセスを許可しても、セキュリティ問題が発生しないことがあります。 このディレクトリでは、匿名のクライアント (Java プログラミング言語またはその他の言語で作成) からそのデータへのアクセスがすでに許可されているためです。
ほとんどのネームサービスおよびディレクトリサービスには、ネットワーク経由でアクセスします。要求されたデータがサーバの認証およびアクセス制御機構によって保護されている場合でも、一部のプロトコルでは、応答として送信されるデータが保護されない (暗号化されない) ことがあります。この問題は、JNDI を使用しているクライアントだけでなく、ディレクトリにアクセスしているすべてのクライアントで発生します。サービスプロバイダは、ネットワーク経由で関連するディレクトリを使用するときに発生するセキュリティ上の問題について、ドキュメントに明記する必要があります。