目次 | 前の項目 | 次の項目 | Java セキュリティアーキテクチャ |
AccessControlContext クラスは、異なるコンテキストでアクセス制御を行う場合に有用であることを説明しました。このような状況はほかにも存在します。 たとえば、リソースの供給者がリソースの消費者と同じスレッドにない場合、および消費者スレッドが供給者スレッドにアクセス制御コンテキスト情報を提供できない場合 (コンテキストのセキュリティのため、コンテキストが大きすぎて渡せないため、その他の理由による) です。このような場合のために、下の図に示すように、リソースへのアクセスを保護する GuardedObject というクラスが提供されます。基本的な考え方は、リソースの供給者がリソースを表すオブジェクトを作成し、リソースオブジェクトを内部に組み込む GuardedObject を作成し、それから GuardedObject を消費者に提供するというものです。GuardedObject の作成時に供給者も Guard オブジェクトを指定し、Guard オブジェクト内部のセキュリティチェックの条件が満たされた場合にだけ、消費者を含むどこからでもリソースオブジェクトを取得できるように設定します。
Guard は、インタフェースなので、どんなオブジェクトも Guard にすることができます。このインタフェースの唯一のメソッドは、
checkGuard
です。checkGuard
は、Object 引数を取得し、特定のセキュリティチェックを実行します。java.security の Permission クラスは、Guard インタフェースを実装します。たとえば、システムスレッドが /a/b/c.txt というファイルを読み取り用に開くよう要求されたとします。 しかし、システムスレッドは、誰が要求したのか、どんな状況で要求が行われたのかわかりません。このため、サーバ側では、正確なアクセス制御を行えません。システムスレッドは、次に示すように、GuardedObject を使ってアクセス制御検査を遅延させることができます。
FileInputStream f = new FileInputStream("/a/b/c.txt"); FilePermission p = new FilePermission("/a/b/c.txt", "read"); GuardedObject g = new GuardedObject(f, p);
これでシステムスレッドは、g を消費者スレッドに渡すことができます。そのスレッドがファイル入力ストリームを取得するには、次のメソッドを呼び出す必要があります。
FileInputStream fis = (FileInputStream) g.getObject();
次にこのメソッドは、Guard オブジェクト p でcheckGuard
メソッドを呼び出します。 p は Permission なので、checkGuard
メソッドは実際には次のようになります。
SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkPermission(this);
これにより、適切なアクセス制御検査が消費者コンテキスト内で確実に実行されます。事実、頻繁に使用されるハッシュテーブルおよびアクセス制御の一覧は、多くの場合置き換えられ、GuardedObject のハッシュテーブルが保存されます。GuardedObject および Guard のこの基本的なパターンは、非常に一般的です。 基本的な Guard および GuardedObject クラスを継承することにより、開発者は強力なアクセス制御ツールを容易に入手することができます。たとえば、メソッドごとの呼び出しは、各メソッドに適切な Guard を設定することにより実現できます。 また Guard は日時、署名者、呼び出し側の ID、その他該当する情報を検査できます。
GuardedObject がオブジェクトを返すため、ある種の型情報が失われます。GuardedObject は、連携するパーティ間で使用することを意図して設計されているため、受け取り側は受け取る (またはキャストする) オブジェクトの種類を知る必要があります。実際、GuardedObject の一般的な使用法として、それをサブクラス化する (GuardedFileInputStream クラスなど) ことが想定されているため、入力情報のカプセル化およびキャストは、サブクラス内で適切に実行できます。
このクラスは、他のセキュリティプリミティブの重要な構築ブロックです。SignedObject には、別の直列化可能オブジェクト、および署名されるオブジェクトとその署名が含まれています。署名が null 値でない場合、SignedObject には、署名付きオブジェクトの有効なデジタル署名が含まれます。これを次の図に示します。背後の署名アルゴリズムは、
sign
メソッド呼び出しへのパラメータとしての Signature オブジェクトによって設定されます。 アルゴリズムは、DSA および SHA-1 を使用する NIST 標準 DSA になります。アルゴリズムは、SHA/DSA などと同じ署名規約を使用して指定されます。署名付きオブジェクトは、元のオブジェクトの「ディープコピー」(直列化表現) です。ひとたびコピーが作成されると、元のオブジェクトをさらに操作してもコピーに影響が及ぶことはありません。署名付きのオブジェクトは、不変のオブジェクトです。
Signature signingEngine = Signature.getInstance(algorithm,provider); SignedObject so = new SignedObject(myobject, signingKey, signingEngine);
検査の一般的な例 (SignedObject であるso
を受け取る) は、次のとおりです。 アルゴリズム名がわかっている場合は、最初の行は必要ありません。
String algorithm = so.getAlgorithm(); Signature verificationEngine = Signature.getInstance(algorithm, provider); so.verify(verificationEngine);
SignedObject のアプリケーションには、潜在的に以下が含まれます。
このクラスは、1 つの署名付きオブジェクトに複数の署名を行えるように、将来サブクラス化されることが予定されています。その場合には、基底クラス内にある既存のメソッド呼び出しは、セマンティクスが完全に互換性のあるものになります。特に、署名が 1 つだけある場合、どのget
メソッドも固有の値を返します。 複数の署名がある場合には、一連の署名の中から任意の署名を 1 つ返します。