この章では、Java Platform, Standard Edition(JavaSE)、Java Authentication and Authorization Service(JAAS)、Java Platform, Enterprise Edition(JavaEE)およびJava Authorization Contract for Containers(JACC)のセキュリティ・モデルの概要を説明します。
この章で説明する内容は包括的なものではありません。詳細は、関連するインターネット・サイトを参照してください。
この章の内容は次のとおりです。
認証では、サービスにアクセスしようとしているものが何であるかをチェックします。どのシステムやアプリケーションでも、リソースにどのようなエンティティやコール元がアクセスしようとしているかを見極めることが重要です。多層アプリケーションのエンティティまたはコール元として考えられるものには、実際の人間であるユーザー、ビジネス・アプリケーション、ホスト、別のエンティティにかわって機能する(別のエンティティを偽装する)エンティティなどがあります。
ユーザー名やパスワードのような認証情報は、XMLファイル、データベース、ディレクトリ・サービスなどのユーザー・リポジトリに格納しておきます。ログインなどによって対象がアプリケーションにアクセスしようとすると、セキュリティ・プロバイダはユーザー・リポジトリでその対象の認証情報を検索し、対象がどのようなエンティティであるかを検証します。セキュリティ・プロバイダとは、認証や認可など、特定のセキュリティ・サービスの実装を提供するモジュールです。Oracle Internet Directoryはリポジトリの一例です。
認可では、リソースに対してタスクを実行できる対象はどれであるかを確認します。リソースは通常、Webアプリケーションの場合はURLパターン、EJBの場合はメソッド・パーミッションで表現します。認証はロールベースなので、アプリケーションで定義されたロールごとに適切なパーミッションが割り当てられます。
Javaセキュリティ・モデルでは、クラスを実行環境にロードするときに、そのクラスで実行できる操作を制御することが基本になっています。そのため、このモデルはコード中心またはコードベースのモデルと呼ばれます。
次の各項で、このモデルの動作を理解するために必要な基本的概念について説明します。
Javaセキュリティ・モデルの詳細は、http://java.sun.com/developer/technicalArticles/Security/whitepaper/JS_White_Paper.pdf
を参照してください。
パーミッションとは、ある一連のリソースに対して実行が許可されている一連の操作です。実行環境にロードされるすべてのJavaクラスには、一定の基準に従って一連のパーミッションが割り当てられ、各パーミッションによって特定のリソースに対する特定のアクセス権が付与されます。たとえば、パーミッションによって、データベースへのアクセスを制限したり、ファイルの編集を禁止したりできます。
コードベースのセキュリティでは、コードが生成された状況、デジタル署名されているかどうか(また、誰が署名しているか)など、コードの特性に基づいてパーミッションが付与されます。コードベースは、コードの場所を示すURLです。次に例を示します。
file
:(ローカル・ファイル・システム上のファイル)
http://*.oracle.com
(oracle.comのホスト上のファイル)
file:${j2ee.home}/lib/oc4j-internal.jar
コードソースはこの概念を拡張し、Javaキーストアに格納されている証明書の配列を必要に応じて扱い、その場所で生成された署名付きのコードを検証します。コードソースはjava.security.CodeSource
インスタンスで表されます。このインスタンスは、java.net.URL
インスタンスと、java.security.cert.Certificate
インスタンスの配列を指定することによって構築します。
抽象Javaクラスjava.security.Permission
はパーミッションを表し、このクラスから派生した具象型には次のようなものがあります。
java.security.AllPermission
java.lang.RuntimePermission
(リソース・ターゲットのみが対象)
java.io.FilePermission
(リソースとアクションが対象)
重要: クラスAllPermission は、使用に注意を要するクラスなので、必要な場合にのみ使用してください。 |
パーミッションの詳細は、http://java.sun.com/j2se/1.5.0/docs/guide/security/spec/security-spec.doc3.html
を参照してください。
保護ドメインによって、パーミッションがコードソースと関連付けられます。その時点で有効なポリシーによって、保護ドメインが決まります。保護ドメインには1つ以上のコードソースが存在します。また、コードを実行しているエンティティ、クラスローダーの参照、およびパーミッション・オブジェクトの集合を表すパーミッション・セット(java.security.PermissionCollection
インスタンス)を記述したプリンシパル配列が存在することもあります。
セキュリティ・ポリシーは、環境の保護ドメインを定義します。つまり、指定のソースからクラスに割り当てられているパーミッションがこのポリシーで特定されます。保護ドメインによってクラスに割り当てられたパーミッションは、クラスがロードされるときに静的にバインドされるか、コードが実行されてセキュリティに関係する操作が行われるときに動的にバインドされます。保護ドメインは、1つまたは複数のポリシー・ファイルで指定されます。
次のポリシー・ファイルのサンプルは、ディレクトリ/home/sysadminに置かれ、かつjJoeによって署名されたコードに、ファイル/tmp/abcへの読取りアクセス権を付与する方法を示しています。
grant signedby jJoe codeBase "file:/home/sysadmin/" { permission java.io.FilePermission "/tmp/abc", "read"; };
この例のsignedBy
句はオプションです。省略すると、指定された場所にあるすべてのコードにパーミッションが付与されます。図1-1は、クラス、保護ドメインおよびパーミッション・セット間の関係を示しています。
ポリシー・ファイルの形式およびポリシーのカスタマイズの詳細は、http://java.sun.com/j2se/1.5.0/docs/guide/security/spec/security-spec.doc3.html#20128
を参照してください。
セキュリティ・マネージャは、Javaセキュリティ・モデルのコンポーネントであり、セキュリティ・ポリシーによってアプリケーションに付与されたパーミッションを適用します。セキュリティに関係する操作をアプリケーションが試行すると、セキュリティ・マネージャによってアプリケーションのパーミッションがチェックされ、操作を許可するかどうかが決定されます。Javaクラスjava.lang.SecurityManager
はセキュリティ・マネージャであり、操作を許可するかどうか、または指定されたパーミッションを適用するかどうかを判定する複数のチェック・メソッドを備えています。
重要: アプリケーションは、セキュリティ・マネージャの制御の有無に関係なく実行できます。ほとんどのシン・アプリケーション(Webブラウザなど)では、セキュリティ・マネージャがデフォルトで有効になります。Javaポリシーを適用する上で、セキュリティ・マネージャは必須ではありません。アプリケーションでJavaポリシーを適用するかどうかは、アプリケーションでパーミッションをどのようにチェックするかによって決まります。たとえば、メソッド |
アクセス・コントローラは、セキュリティ・マネージャが操作と決定を制御するために使用するオブジェクトです(セキュリティ・マネージャが無効になっている場合はアプリケーションが直接使用)。アクセス・コントローラの具体的な役割は次のとおりです。
現在有効なセキュリティ・ポリシーに基づいて、システム・リソースへのアクセスを許可するかどうかを決定します。
コードを権限付きとしてマークして、その後のアクセスの判定に影響するようにします。
現在のコール・コンテキストを保存できるようにして、保存したコンテキストを他の異なるコンテキストで考慮してアクセス制御を決定できるようにします。
Javaクラスjava.security.AccessController
はアクセス・コントローラを表し、渡されたパーミッションでリクエストされたアクセスを承諾するかどうかを決定するcheckPermission(aPerm)
メソッドを備えています。次のコードSnippetでは、このメソッドを使用してファイル/temp/testFileの読取りを許可しています。
FilePermission perm = new FilePermission("/temp/testFile", "read"); AccessController.checkPermission(perm);
checkPermission
は、アクセス・コントローラの特定の実装に従って評価を行います。デフォルトの実装では、コール・スタック全体、そこに含まれるクラスおよびそれらのクラスに付与されているパーミッションを調べて、リクエストを承諾するかどうかが決定されます。リクエストが承諾された場合も、リクエストが拒否されて(または渡されたパーミッションが無効で)例外がスローされた場合も、このメソッドは通知なしに戻ります。
注意: AccessController.checkPermission は、現在実行中のスレッドのコンテキスト内でセキュリティ・チェックを実行します。ただし、場合によっては、現在のコンテキストとは別のコンテキストを使用したセキュリティ・チェックがアプリケーションで必要になります。
メソッド |
セキュリティ・マネージャはアクセス制御の中心点を表し、アクセス・コントローラは特定のアクセス・アルゴリズムを実装します。
セキュリティ・マネージャとアクセス・コントローラの詳細は、http://java.sun.com/j2se/1.5.0/docs/guide/security/spec/security-spec.doc6.html
を参照してください。
Java Authentication and Authorization Service(JAAS)は、Java SDK, Standard Edition v 1.4に統合されたJavaパッケージで、Javaセキュリティ・モデルを補完します。
JAASによって追加される主な機能は次のとおりです。
コール元のアイデンティティのチェック(Javaモデルで特に不足している機能)、実行中のコードに付与されているパーミッションのチェック、およびサブジェクトベースの認可を可能にすることで、Javaセキュリティ・モデルを拡張します。
標準のPluggable Authentication Module(PAM)フレームワークが実装されます。これにより、アプリケーションがその認証サービスから切り離され、カスタム認証モジュールの実装がサポートされます。
次の各項で、このモデルの動作を理解するために必要な基本的概念について説明します。
Oracle Platform Security Services(OPSS)にはスケーラブルなJAASプロバイダが組み込まれており、ファイングレイン認証の標準メカニズムとしてJAASが使用されます。また、WebベースとEJBベースの両方のアプリケーションに対してJAAS認証がサポートされます。JAASに対するOPSSの主な拡張機能は、jazn-data.xml
ファイルによってサポートされます。このファイルでは、ファイングレイン認証の(a)軽量XMLプロバイダ、(b)LDAPプロバイダ、(c)アプリケーション、匿名ユーザーおよび匿名ロールを指定します。
JAASの主要な機能の詳細は、http://java.sun.com/javase/6/docs/technotes/guides/security/jaas/JAASRefGuide.html
を参照してください。
プリンシパルは、認証プロセスによってエンティティ(ユーザー、グループ、システム・プロセスなど)に割り当てられるアイデンティティです。プリンシパルの抽象概念は、Javaインタフェースjavax.security.auth.Principal
で表されます。具象的なプリンシパルは、このインタフェースを実装するクラスのインスタンスで表されます。アプリケーションでインスタンス化される各プリンシパルには、そのプリンシパルを識別する個別の名前が必要です。
サブジェクトは、一連のプリンシパルおよび場合によってはパスワードや暗号キーなどの資格証明を含めた、関連するセキュリティ情報のグループです。Javaクラスjavax.security.auth.Subject
はサブジェクトを表します。認証が成功すると、このクラスのインスタンスが作成され、プリンシパルが移入されます。したがって、サブジェクトは認証されたエンティティを表し、サブジェクト内のプリンシパルと資格証明を使用して、認証されたエンティティで実行できるアクションが決まります。
プリンシパルとサブジェクトの詳細は、次のサイトを参照してください。
ログイン・モジュールは、ユーザーを認証し、サブジェクトにプリンシパルを移入するコンポーネントです。ログイン・モジュールは、アプリケーション・コードを変更することなくアプリケーションにプラグインして使用できます。アプリケーションでは複数のログイン・モジュールを使用できます。
ログイン・モジュールの抽象概念は、Javaインタフェースjavax.security.auth.spi.LoginModule
で表されます。具象的なログイン・モジュールは、このインタフェースを実装するクラスのインスタンスで表されます。
ログイン・モジュールでユーザーを認証するために、JavaSEアプリケーションではまずログイン・コンテキストがインスタンス化されます。次に構成ファイルが参照され、アプリケーションに対して構成されているすべてのログイン・モジュールがロードされ、各モジュールでメソッドlogin
が起動されます。各ログイン・モジュールで、必要に応じて1つ以上のプリンシパルがサブジェクトに追加されます。サブジェクトは、認証が成功した場合にのみ使用可能となります。
ただし、JavaEEアプリケーションでは、アプリケーションでログイン・コンテキストをインスタンス化しなくても、ログイン・モジュールをコンテナで暗黙的に起動できます。
ログイン・モジュールがユーザーと通信して認証データを取得する手段としてコールバック・ハンドラがあります。このハンドラをアプリケーションでログイン・コンテキストがインスタンス化される際に指定することで、そのコンテキストで起動されるすべてのログイン・モジュールが、渡されたコールバック・ハンドラを使用するようになります。このメカニズムにより、ログイン・モジュールのロジックでユーザー操作が不要となります。
アプリケーションではログイン・モジュールのスタックを使用してユーザーを認証でき、各モジュールではスタック内の他のモジュールとは無関係に独自の計算を実行できます。アプリケーションで使用されるスタックは、アプリケーションのデプロイメント・ディスクリプタで定義されます。このファイルでログイン・モジュールが列挙される順序は重要です。これは、認証アルゴリズムで、モジュールのセキュリティ・レベルを特定するフラグ(required、sufficient、requisite、optional)などのデータに加えてこの順序が考慮されるためです。
注意: Oracle WebLogic Serverでは、標準のJAASログイン・モジュールをそのまま使用することはできません。WebLogic認証プロバイダの詳細は、第4.1.1項「Oracle WebLogicの認証プロバイダ」を参照してください。 |
ログイン・モジュール構成の詳細は、http://java.sun.com/j2se/1.5.0/docs/api/javax/security/auth/login/Configuration.htmlを参照してください。
認証プロセスが成功してサブジェクトが使用可能になると、アプリケーションでは、メソッドdoAs
またはdoAsPriviledged
をコールし、特定のコンテキストで機密性の高いアクションを実行することをそのサブジェクトに認可します。両者の違いは、doAs
が現在実行中のコンテキストを使用する一方で、doAsPriviledged
が実行中のコンテキストと必ずしも同じでない提供されたコンテキストを使用する点です。
アクションと制御コンテキストの詳細は、次のサイトを参照してください。
http://java.sun.com/j2se/1.5.0/docs/api/java/security/class-use/PrivilegedAction.html
http://java.sun.com/j2se/1.5.0/docs/api/java/security/AccessController.html
メソッドdoAs
およびdoAsPrivileged
の詳細は、次のドキュメントを参照してください。
JavaEEセキュリティ・モデルは、コンテナ管理セキュリティに基づくロールベースの宣言的なモデルです。このモデルでは、ユーザーに割り当てられているロールによってリソースが保護されます。このモデルでは、セキュリティをアプリケーション・デプロイメント・ディスクリプタでアプリケーション・ロジックとは別に指定できるため、アプリケーションをその基礎となるセキュリティ・インフラストラクチャから切り離すことができます。アプリケーションの実行場所であるコンテナは、デプロイメント・ディスクリプタでの指定に従って、アプリケーションにセキュリティを提供します。このモデルでは、デプロイメント・ディスクリプタから参照可能なセキュリティ・データ(注釈)をアプリケーション・コードに埋め込むこともできます。
次の各項で、このモデルの動作を理解するために必要な基本的概念について説明します。
コンテナは、コンテナ内で実行されるアプリケーションに、宣言的なセキュリティとプログラム的なセキュリティの2種類のセキュリティを提供します。
宣言的なセキュリティでは、アプリケーション・デプロイメント・ディスクリプタ・ファイルで表されているセキュリティが参照されます。コンテナは、実行時にこのファイルを使用して、WebモジュールURLやEJB Beanメソッドなどのアプリケーション・リソースへのアクセス制御を適用します。
EJBテクノロジとWebサーバー・セキュリティ・モデルの詳細は、次のサイトを参照してください。
http://java.sun.com/developer/technicalArticles/J2EE/jpa/
プログラム的なセキュリティでは、セキュリティ対応アプリケーションのコードで表されているセキュリティが参照されます。このセキュリティは、宣言的なセキュリティでアプリケーションのセキュリティ要件を十分に表せない場合に役立ちます。
プログラム的なセキュリティを使用するには、通常、アプリケーションでインタフェースjavax.ejb.EJBContext
またはjavax.servlet.http.HttpServRequest
を実装し、weblogic.security
APIと次のメソッドを使用してセキュリティ上の決定をカスタマイズします。
EJBContext.isCallerInRole(aRoleName)
EJBContext.getCallerPrincipal()
HttpServRequest.isUserInRole(aRoleName)
HttpServRequest.getUserPrincipal()
これらのインタフェースの詳細は、次のサイトを参照してください。
サーバーでは、Basic、フォームまたはクライアント証明書でWebアプリケーションのエンドユーザーが認証されます。この3つの方法は提供するセキュリティの範囲が異なりますが、基本的にはどの方法も、サーバーで資格証明を作成したりアクセスを拒否したりするために処理されるアカウント名やパスワードなどのデータをユーザーから取得します。サーバーによるユーザーの認証方法は、アプリケーション・デプロイメント・ディスクリプタで指定します。
サーバーでは、構成済のアイデンティティ・ストアと照合することで、提供された資格証明を検証し、それを使用してそのサーバーにあるセキュアなリソースへのアクセスのほか、別のサーバーで実行されていることもあるエンタープライズBeanメソッドのコールへのアクセスを認可します。
JavaEE認可モデルは、セキュリティ・ロールに基づいています。セキュリティ・ロールは、アプリケーション・デプロイメント・ディスクリプタまたはアプリケーション・コード(注釈を使用)で指定できる一連のユーザーです。アプリケーションでは、リソースに対する特定の操作の実行を許可されるロールを指定することで、リソース(WebモジュールURLやBeanメソッドなど)へのアクセスを制御します。
デプロイ時に、アプリケーションスコープのロールが実行環境のセキュリティ・エンティティ(ユーザー、ユーザーのグループ、プリンシパルなど)にマップされます。このマッピングは、デプロイメント・ディスクリプタとは別の構成ファイルで指定します。
実行時にプリンシパルがリソースへのアクセスをリクエストすると、リソースへのアクセスを許可されたロールがプリンシパルに関連付けられているかがコンテナによって確認され、関連付けられている場合はコンテナからアプリケーションに制御が渡されてリクエストが許可されます。
このモデルでは、他にもエンタープライズJava BeanまたはWebコンポーネントを実行する際に必ず使用するアイデンティティをアプリケーションで指定でき(run-asメソッドベースの認可)、トランスポート層のセキュリティ(SSL)がサポートされます。
サーブレットのセキュリティの詳細は、http://java.sun.com/products/servlet/whitepaper.html
を参照してください。
Java Authorization Contract for Containers(JACC)は、JavaEEコンテナと認可モジュールの間の規約を指定して、コンテナが適切な認可を提供できるようにします。具体的には、JACCによって次のタスクが実行されます。
パーミッションの集合としてロールを定義します。
ロール内のパーミッションをプリンシパルに付与します。
ロール内のパーミッションがプリンシパルに付与されているかを判定します。
アプリケーション・コードに埋め込まれたIDをアプリケーションスコープのロールにマップします。
JACCを使用すると、JavaEEセキュリティ制約をJavaパーミッションに変換することで、JavaEEセキュリティ・モデルでJavaセキュリティ・モデルを活用できます。JACCは、デフォルトでは有効になっていません。
ここでは、3つのモデルの機能を要約して、各モデルの特徴とモデル間の違いを明らかにします。
3つのモデルはいずれも、ポリシー・ストアをサポートするプラットフォームであるOPSSによって完全にサポートされます。ポリシー・ストアでは、JavaとJAASの両方のパーミッションでパーミッションを構成できるため、コード中心のモデルとユーザー中心のモデルを組み合せることができます。
JavaSE
このモデルは、事前に定義されたポリシー・ファイルにコード・セキュリティを指定できることから、コード中心のモデルと呼ばれます。Javaランタイム環境にクラスがロードされるときに、クラス・ローダーによって次の情報が自動的にクラスに関連付けられます。
クラスのロード元となった場所
クラスに署名したエンティティ(存在する場合)
デフォルト・パーミッションのセット
コードを実行するユーザーのアイデンティティはロード時には得られません。認証は、アプリケーション自体で必要に応じて実行されます。認可は、アプリケーション自体またはセキュリティ・マネージャで管理されます。
JAAS
このモデルは、セキュリティ上の決定でコードの性質と実行者の両方が考慮されるユーザー中心のモデルを取り入れることで、JavaSEのコード中心のモデルを拡張します。
認証は、ログイン・モジュールでカスタマイズできます。認可は、JavaSEモデルと同じく事前定義済のポリシーに従って管理されます。このモデルは、カスタム・パーミッションもサポートすることから、認証の制御をより細かくカスタマイズする必要があるアプリケーションに適しています。
JavaEE
このモデルでは、セキュアなリソースがURLパターン(Webモジュール内)またはメソッド名(EJBモジュール内)で識別されます。アプリケーションが実行されるコンテナでは、アプリケーション・デプロイメント・ディスクリプタでの指定またはアプリケーション・コード内の注釈に従って認証と認可が実施されます。トランスポート・レイヤーでセキュアなプロトコルHTTPSを使用できます。
このモデルはデプロイと管理が最も簡単であり、多くの場合JAASモデルとともに使用します。