そのすべてのJAAS

アプリケーションのログイン認証メカニズムを作成する必要があったことはありますか?新しい実装はそれぞれ、前の実装と同じではありませんが、近い可能性があります。たとえば、ある実装ではOracleデータベースを使用し、別の実装ではNT認証を使用し、別の実装ではLDAP(ライトウェイトアクセスディレクトリプロトコル)ディレクトリを使用する場合があります。アプリケーションレベルのコードを変更せずに、これらすべてのセキュリティメカニズムをサポートするのは素晴らしいことではないでしょうか。

現在、Javaの世界では、Java Authentication and Authorization Service(JAAS)を使用できます。この比較的新しいAPIは、J2SE(Java 2 Platform、Standard Edition)1.3の拡張であり、J2SE 1.4のコアAPIであり、J2EE(Java 2 Platform、Enterprise Edition)1.3仕様の一部でもあります。この記事では、JAASの基本事項を説明し、JAASを実際のアプリケーションに効果的に適用する方法を示します。この記事のアプリケーションは、ユーザーのログイン情報を格納するためにRDBMS(リレーショナルデータベース管理システム)を使用する既存のJavaWebベースのシステムにJAASを統合した独自の経験に基づいています。 JAASを使用して、より堅牢で柔軟性があり、一貫性のあるログインおよび認証メカニズムを設計しました。

以下のリソースから実用的な例の完全なセットをダウンロードできます(Javaソース、JSP(JavaServer Pages)、JAAS構成、データベースおよびビルドスクリプトが含まれます)。これらの例は、JDBC(Java Database Connectivity)を備えたResinサーバーとMySQLデータベースを使用してテストしました。

Java認証と承認:全体像

JAAS以前は、Javaのセキュリティモデルは、分散型のネットワークアプリケーション用のプラットフォームに依存しない言語としての起源によって主に形作られていました。初期のJavaは、ブラウザベースのアプレットなどのモバイルコードとして登場することが多かったため、初期のセキュリティモデルは、コードの作成作成者に基づいてユーザーを保護することに重点を置いていました。SecurityManager s、サンドボックスの概念、コード署名、ポリシーファイルなどの初期のJavaセキュリティメカニズムはすべて、システムからユーザーを保護することを目的としていました。

JAASの発明は、ログインとアクセス制御を必要とする従来のクライアントおよびサーバーアプリケーションの実装に使用される汎用プログラミング言語へのJavaの進化を反映しています。 JAASは、プログラムの実行者または実行者に基づいてアクセスを許可または拒否することにより、システムをユーザーから保護します JAASは認証と承認の両方を実行できますが、この記事では、主に認証に焦点を当てます。

JAASは、アプリケーションと異なる基盤となる認証および承認メカニズムの間に抽象化レイヤーを配置することにより、Javaセキュリティ開発を簡素化できます。プラットフォームやアルゴリズムからのこの独立性により、アプリケーションレベルのコードを変更することなく、さまざまなセキュリティメカニズムを使用できます。ほとんどのJavaセキュリティAPIと同様に、JAASは、プラグイン可能なサービスプロバイダーインターフェイス(SPI)の拡張可能なフレームワーク(特定の実装が開発される抽象クラスとインターフェイスのセット)を通じて、この実装に依存しないことを実現します。

以下の図1は、JAASがこのプラグ可能性を実現する方法の概要を示しています。アプリケーション層コードは主にを扱いLoginContextます。その下にLoginContextLoginModule、適切なセキュリティインフラストラクチャを使用して実際の認証を処理する、動的に構成された1つ以上ののセットがあります。

JAASはLoginModuleJndiLoginModule;などのいくつかのリファレンス実装を提供します。ここでを使用して行うように、独自に開発することもできますRdbmsLoginModule。また、簡単な構成ファイルを使用して、実装を選択してアプリケーションをすばやくセットアップする方法についても説明します。

プラグ可能であることに加えて、JAASはスタック可能です。単一のログインのコンテキストでは、セキュリティモジュールのセットを互いに積み重ねることができ、それぞれが順番に呼び出され、それぞれが異なるセキュリティインフラストラクチャと相互作用します。

JAASの側面は、いくつかの使い慣れたセキュリティアーキテクチャパターンと既存のフレームワークに基づいてモデル化されています。たとえば、スタック可能な機能は、Unix Pluggable Authentication Module(PAM)フレームワークに意図的に似ています。トランザクションの観点から、JAASは2フェーズコミット(2PC)プロトコルと同様の動作を採用しています。Policyファイルやを含むJAASのセキュリティ構成の概念はPermissions、J2SE1.2セキュリティパッケージに由来します。JAASSubjectは、名前の由来となったX.509証明書など、他の確立されたセキュリティフレームワークからもアイデアを借りています(詳細についてはSubject後で説明します)。

注: JAASは、いくつかの新しいJavaセキュリティAPIの1つにすぎません。Javaセキュリティの詳細については、以下のサイドバー「Javaセキュリティパズル」および「参考文献」を参照してください。

クライアント側とサーバー側のJAAS

JAASは、クライアントとサーバーの両方に適用できます。すぐに説明するように、クライアント側での使用は簡単です。サーバー側では、物事は少し複雑になります。現在、アプリケーションサーバー市場のJAASは少し一貫性がありません。 J2EEアプリサーバーは、使用するサーバーに応じて、JAASの使用方法が少し異なります。たとえば、JBossSXは、独自のアーキテクチャを使用して、JAASを全体的なセキュリティフレームワークにうまく統合します(これについては、Scott Starkの優れたJavaWorld記事「IntegrateSecurityInfrastructures withJBossSX」(2001年8月)で詳しく説明されています)。ただし、WebLogic 6.xはJAASをサポートしていますが、詳細は異なります。

したがって、サーバー側とクライアント側の両方の観点からJAASを理解できるように、この記事では両方の例を示します。また、サーバーを簡素化するために、Resinアプリケーションサーバーを使用して、よりクリーンな状態から始めることができます(Resinには独自のプラグ可能な認証スキームがありますが、標準ではないため、JAASを使用すると移植性が向上します後でオプション)。

コアJAAS

JAASの使用を開始するには、まずJAASがインストールされていることを確認する必要があります。 J2SE1.4にはすでにJAASが含まれています。 J2SE1.3はそうではありません。 J2SE 1.3を引き続き使用する場合は、SunMicrosystemsからJAASをダウンロードしてください。 JAASをダウンロードして特定のディレクトリにインストールするとlib、という名前の1つのファイルを含むというサブディレクトリが表示されますjaas.jar。このファイルをクラスパスに追加するか、JRE(Javaランタイム環境)拡張ディレクトリ(で\lib\extJREの場所)にコピーする必要があります。これで、JAASの準備が整いました。注:アプリケーションサーバーを使用している場合は、すでにJAASが含まれている可能性があります。詳細については、サーバーのドキュメントを確認してください。

これらのアプローチのいずれかを使用して、JavaセキュリティプロパティファイルでJAAS関連のシステムプロパティ設定の一部(および他の多くのJavaセキュリティ設定)を変更できることに注意してください。このファイルjava.securityは、/lib/securityディレクトリにあり、標準のJavaプロパティファイル形式で記述されています。

アプリケーションからJAAS認証を使用するには、通常、次の手順が必要です。

  1. 作成する LoginContext
  2. オプションで、認証データを収集または処理するためCallbackHandlerに、LoginContextにを渡します
  3. LoginContextlogin()メソッドを呼び出して認証を実行します
  4. 返されたものを使用して特権アクションを実行Subjectします(ログインが成功した場合)

最小限の例を次に示します。

LoginContext lc = new LoginContext( "MyExample"); {lc.login();を試してください。} catch(LoginException){//認証に失敗しました。} //認証が成功しました、これで続行できます。//必要に応じて、返されたサブジェクトを使用できます。サブジェクトsub = lc.getSubject(); Subject.doAs(sub、new MyPrivilegedAction());

カバーの下で、他のいくつかのことが起こります:

  1. 初期化中に、LoginContext"MyExample"JAAS構成ファイル(構成済み)で構成エントリを検索して、LoginModuleロードするものを決定します(図2を参照)。
  2. ログイン中に、LoginContextそれぞれLoginModulelogin()メソッドを呼び出します
  3. login()メソッドは、認証を実行するか、CallbackHandler
  4. CallbackHandler用途一つ以上はCallback、ユーザーとの対話や入力を収集しますよ
  5. A new Subject instance is populated with authentication details such as Principals and credentials

We'll explain further details below, but to begin, let's look at the key JAAS classes and interfaces involved in the process. These are typically divided into the following three groups:

Table 1. JAAS classes and interfaces

Common Subject, Principal, credential (credential is not any specific class, but can be any object)
Authentication LoginContext, LoginModule, CallbackHandler, Callback
Authorization Policy, AuthPermission, PrivateCredentialPermission

Most of these classes and interfaces are in the javax.security.auth package's subpackages, with some prebuilt implementations in the com.sun.security.auth package, included only in J2SE 1.4.

Note: Because we focus on authentication in this article, we don't delve into the authorization classes.

Common: Subjects, Principals, and Credentials

The Subject class represents an authenticated entity: an end-user or administrator, or a Web service, device, or another process. The class contains three sets of security information types:

  • Identities: In the form of one or more Principals
  • Public credentials: Such as name or public keys
  • Private credentials: Like passwords or private keys

Principals represent Subject identities. They implement the java.security.Principal interface (which predates JAAS) and java.io.Serializable. A Subject's most important method is getName(), which returns an identity's string name. Since a Subject instance contains an array of Principals, it can thus have multiple names. Because a social security number, login ID, email address, and so on, can all represent one user, multiple identities prove common in the real world.

The last element here, credential, is not a class or an interface, but can be any object. Credentials can include any authentication artifact, such as a ticket, key, or password, that specific security systems might require. The Subject class maintains unique Sets of private and public credentials, which can be retrieved with methods such as getPrivateCredentials() and getPublicCrendentials(). These methods are more often used by security subsystems than at the application layer.

Authentication: LoginContext

Your application layer uses LoginContext as its primary class for authenticating Subjects. LoginContext also represents where JAAS's dynamic pluggability comes into play, because when you construct a LoginContext, you specify a named configuration to load. The LoginContext typically loads the configuration information from a text file, which in turn tells the LoginContext which LoginModules to use during login.

The three commonly used methods in LoginContext are:

Table 2. LoginContext methods

login() Performs login, a relatively complex step that invokes all LoginModules specified for this configuration. If it succeeds, it creates an authenticated Subject. If it fails, it throws a LoginException.
getSubject() Returns the authenticated Subject.
logout() Logs out the authenticated Subject and removes its Principals and credentials.

We will show how to use these methods later.

Authentication: LoginModule

LoginModule is the interface to specific authentication mechanisms. J2SE 1.4 ships with a set of ready-to-use LoginModules, including:

Table 3. LoginModules in J2SE 1.4

JndiLoginModule Verifies against a directory service configured under JNDI (Java Naming and Directory Interface)
Krb5LoginModule Authenticates using Kerberos protocols
NTLoginModule Uses the current user's NT security information to authenticate
UnixLoginModule Uses the current user's Unix security information to authenticate

Along with these modules comes a set of corresponding concrete Principal implementations in the com.sun.security.auth package, such as NTDomainPrincipal and UnixPrincipal.

The LoginModule interface has five methods:

Table 4. LoginModule methods

initialize() Called after the LoginModule is constructed.
login() Performs the authentication.
commit() Called by the LoginContext after it has accepted the results from all LoginModules defined for this application. We assign Principals and credentials to the Subject here.
abort() Called when any LoginModule for this application fails (even though earlier ones in sequence may have succeeded—thus akin to a 2PC model). No Principals or credentials are assigned to the Subject.
logout() Removes the Principals and credentials associated with the Subject.

The application layer calls none of these methods directly—the LoginContext invokes them as needed. Our example below will elaborate on these methods' implementations.

Authentication: CallbackHandlers and Callbacks

CallbackHandlersおよびCallbacksをLoginModule使用すると、実際の対話メカニズムから独立したまま、ユーザーまたはシステムから必要な認証情報を収集できます。この機能を設計で活用します。RdbmsLoginModuleユーザー資格情報(ユーザー名/パスワード)の取得方法に依存しないため、(コマンドラインまたはJSPから)説明するさまざまなアプリケーション環境で使用できます。 。