目次 | 前へ | 次へ |
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 クラスのいくつかは直列化可能です。直列化すると、バイトストリームの形式でオブジェクトにアクセスできます。このとき、作成された環境の外部からアクセスすることもできます。
コンテキストハンドルが (初期コンテキストを取得するか、またはディレクトリから検索または作成することによって) 作成された場合は、それにいくつかの環境プロパティーを指定できます。コンテキストハンドルの作成にセキュリティー関連のプロパティーが必要な場合があります (ユーザーをそのディレクトリに「ログイン」させるユーザー情報など)。サービスプロバイダでは、信頼されていないコードから重要な情報を保護する必要があります。
サービスプロバイダは、コンテキストの環境を、信頼されていないコードによる改ざんまたはそれ以外の変更から保護する必要があります。また、重要な環境プロパティーを、信頼されていないコードによる読み取りから保護する必要があります。これらを保護するにはいくつかの方法があります。たとえば、スレッドの実行コンテキストまたは信頼レベル、あるいはその両方が、コンテキストハンドルを作成したスレッドの初期属性と異なる場合は、そのコンテキストハンドルの使用を禁止します。または、重要な環境プロパティーへのアクセスなど、特定の操作を禁止します。あるいは、重要な環境プロパティーを返さないか信頼されたコードにだけ返します。
信頼されていないコード (信頼されていないアプレットのコードなど) は、ネットワークへのアクセスが制限されます。たとえば、信頼されていないアプレットからは、ダウンロード元のホスト以外にはネットワーク接続を作成できません。セキュリティーモデルをより詳細に調整すると、サービスプロバイダ自体から、信頼されたコードとして、信頼されていないアプレットからは接続できないホストに接続できます。この場合、サービスプロバイダでは、セキュリティーマネージャーに定義されているセキュリティーが低下しないように注意する必要があります。信頼されていないアプレットからディレクトリにアクセスしても、セキュリティー上の問題が発生しないことが保証されている場合は、信頼されていないコードに対してサービスを提供することもできます。たとえば、信頼されていないコードからディレクトリに対する「匿名」のアクセスを許可しても、セキュリティー問題が発生しないことがありますが、これはそのディレクトリでは、匿名のクライアント (Java プログラミング言語またはその他の言語で作成) からそのデータへのアクセスがすでに許可されているためです。
ほとんどのネームおよびディレクトリサービスは、ネットワーク経由でアクセスされます。要求されたデータがサーバーの認証およびアクセス制御メカニズムによって保護されている場合でも、一部のプロトコルでは、応答として送信されるデータが保護されない (暗号化されない) ことがあります。この問題は、JNDI を使用しているクライアントだけでなく、ディレクトリにアクセスしているすべてのクライアントで発生します。サービスプロバイダは、ネットワーク経由で関連するディレクトリを使用するときに発生するセキュリティー上の問題について、ドキュメントに明記する必要があります。
ネットワークアクセスと同様に、信頼されていないコードは、ローカルファイルシステムへのアクセスが制限されます。サービスプロバイダにローカルファイルに対するアクセス特権が与えられている場合は、実行環境およびプラットフォームに定義されているセキュリティーポリシーが低下しないように、十分な対策が必要です。
特権付きセクションのない、完全に Java プログラミング言語で記述されたサービスプロバイダは、Java プログラミング言語で記述されたほかのコードに与えられるのと同じセキュリティーポリシーで制御されます。そのサービスプロバイダからアクセスする保護されたリソースは、すべて同じセキュリティーマネージャーおよびアクセスコントローラによって制御されます。
サービスプロバイダに特権付きのコードセクションまたはネイティブメソッドが含まれる場合、そのサービスプロバイダは、実行環境およびプラットフォームに定義されているセキュリティーポリシーが保持されるように特に注意する必要があります。