目次||

7 GuardedObjectとSignedObject


7.1 java.security.GuardedObjectとjava.security.Guard

AccessControlContextクラスは、異なるコンテキストでアクセス制御の決定を行う必要がある場合に有用であることを説明しました。このようなシナリオは他にも存在します。たとえば、リソースの供給者がそのリソースの消費者と同じスレッドになく、消費者スレッドが供給者スレッドにアクセス制御コンテキスト情報を提供できない(コンテキストのセキュリティが厳しい、またはコンテキストが大きすぎて渡せないなどの理由のため)場合です。このような場合のために、下の図に示すように、リソースへのアクセスを保護するGuardedObjectというクラスを用意しています。

前述の説明を示す図

基本的な考え方は、リソースの供給者がリソースを表すオブジェクトを作成し、リソース・オブジェクトを内部に組み込むGuardedObjectを作成し、それからGuardedObjectを消費者に提供するというものです。GuardedObjectの作成時に供給者もGuardオブジェクトを指定し、Guardオブジェクト内部のセキュリティ・チェックの条件が満たされた場合にだけ、消費者を含むどこからでもリソース・オブジェクトを取得できるように設定します。

Guardは、インタフェースなので、どんなオブジェクトもGuardにすることができます。このインタフェースの唯一のメソッドは、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は時間、署名者、またはその他の呼出し側の識別情報、またはその他の関連情報をチェックできます。

GuardedObjectがオブジェクトを返すため、ある種の型情報が失われます。GuardedObjectは、連携するパーティ間で使用することを意図して設計されているため、受け取り側は受け取る(またはキャストする)オブジェクトの種類を知る必要があります。実際、GuardedObjectの一般的な使用法として、それをサブクラス化する(GuardedFileInputStreamクラスの形成など)ことが想定されているため、入力情報のカプセル化およびキャストは、サブクラス内で適切に実行できます。


7.2 java.security.SignedObject

このクラスは、ほかのセキュリティ・プリミティブの重要な構築ブロックです。SignedObjectには、別の直列化可能オブジェクト、および署名されるオブジェクトとその署名が含まれています。署名がnull値でない場合、これには、署名付きオブジェクトの有効なデジタル署名が含まれます。これを次の図に示します。

前のコンテキストがこのグラフィックスを説明しています。

基礎となる署名アルゴリズムは、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つだけある場合、どのgetメソッドも一意の値を返します。複数の署名がある場合には、一連の署名の中から任意の署名を1つ返します。

目次||

Copyright © 1993, 2020, Oracle and/or its affiliates. All rights reserved.