Kerberosを使ったJavaのシングル・サインオン

Mayank Upadhyay
Ram Marti

要約

Java Standard Edition (J2SE)の次のリリースにおけるJavaセキュリティ・アーキテクチャの重要な拡張機能は、Kerberos Version 5を使用したシングル・サインオンを実現する機能です。シングル・サインオン・ソリューションを利用すると、ユーザーは、1回のみの認証で、複数のどのシステムに存在する情報にもアクセスできるようになります。これを実現するため、認証および承認にはJAASを、ピア・アプリケーションとの通信用のセキュアなコンテキストの確立にはJava GSS-APIを、それぞれ使用します。ここでは、シングル・サインオンの基盤となるセキュリティ・メカニズムとしてKerberos V5に注目して解説します。ただし、将来、他のセキュリティ・メカニズムも追加される可能性があります。

はじめに

分散システムの使用が増加するにつれて、ユーザーがリモートのリソースにアクセスする必要性が高まっています。従来の方法では、ユーザーは複数のシステムにサイン・オンしなければならず、しかもシステムごとに使用するユーザー名や認証技術が異なる場合もあります。一方、シングル・サインオンを利用すると、ユーザーが一度認証を行うだけで、認証された識別情報がセキュアにネットワーク内を通過し、ユーザーに代わってリソースへのアクセスが行われます。

このドキュメントでは、Kerberos V5プロトコルに基づいたシングル・サインオンを使用する方法を説明します。Kerberosに対するプリンシパルの認証、および識別情報を証明するクレデンシャルの取得には、Java認証・承認サービス(JAAS)を使用します。SunによるKerberosログイン・モジュールを実装して、ネイティブのKerberosをサポートするプラットフォーム上の既存のキャッシュからクレデンシャルを読み取る方法を示します。次に、Java Generic Security Service API (Java GSS-API)および取得済みのKerberosクレデンシャルを使用して、リモート・ピアを認証します。また、多層環境でシングル・サインオンのKerberosクレデンシャルを委譲する方法も示します。

KERBEROS V5

Kerberos V5は、サード・パーティによる信頼性の高いネットワーク認証プロトコルで、秘密キー暗号化を使用する強力な認証を提供します。Kerberos V5を使用すると、Kerberos V5の管理時を除き、ユーザーのパスワード(暗号化された状態も含む)がネットワーク内でやり取りされることがなくなります。Kerberosは、1980年代半ばにMITのProject Athenaの一環として開発されました。Kerberos V5プロトコルの完全な解説は、このドキュメントの目的ではありません。Kerberos V5プロトコルの詳細は、[1]および[2]を参照してください。

Kerberos V5は、成熟したプロトコルで、広範囲に実装されています。SolarisではSEAMとして利用可能であり、またWindows 2000やほかのプラットフォームでも利用可能です。C言語による無料のリファレンス実装が、MITにより提供されています。J2SEにおけるシングル・サインオンの基盤となる技術としてKerberos V5が選択されているのは、こうした理由によります。

Java認証・承認サービス(JAAS)

最近まで、Java 2セキュリティ・アーキテクチャが特権を決定する根拠は、コードの出所およびコード署名者に一致する公開キー証明書だけでした。しかし、複数ユーザー環境では、コードを実行するユーザーの認証済み識別情報に基づいて、特権をさらに指定するのが望ましい方法です。

JAASが提供するのは、この機能です。JAASは、認証および認証済みの識別情報に基づくアクセス制御に特化した、プラガブルなフレームワークおよびプログラミング・インタフェースです。

認証および承認

JAASフレームワークは、認証コンポーネントと承認コンポーネントの2つに分けることができます。

JAAS認証コンポーネントは、コードがアプリケーション、アプレット、Bean、サーブレットとして稼動しているかに関係なく、Javaコードを実行しているユーザーを確実かつセキュアに判定する機能を提供します。

JAAS承認コンポーネントは、コード・ソースおよびコードを実行するユーザーに基づき、Javaコードが慎重を要するタスクの実行を制限する手段を提供して、既存のJavaセキュリティ・フレームワークを補完します。

プラグインおよびスタック可能なフレームワーク

JAAS認証フレームワークは、Pluggable Authentication Module (PAM)[3]、[4]に基づいています。JAASの認証はプラガブルな方法で行われるため、システム管理者は適切な認証モジュールを追加できます。これにより、Javaアプリケーションは基盤となる認証技術に依存せずに済みます。また、アプリケーション自体を変更することなく、新規または更新された認証技術をシームレスに構成できます。

JAAS認証フレームワークは、認証モジュールのスタックもサポートします。複数のモジュールを指定し、指定順にモジュールをJAASフレームワークから呼び出すことができます。認証全体が成功するかどうかは、個別の認証モジュールの結果に依存しています。

サブジェクト

JAASでは、「サブジェクト」という語は、リソースへのアクセス要求のソースであるエンティティを表すために使用されます。サブジェクトは、ユーザーの場合もあれば、サービスの場合もあります。1つのエンティティは、多数の名前やプリンシパルを保持することが可能であるため、JAASは、サブジェクトを、エンティティあたり複数の名前を処理する特別な抽象レイヤーとして使用します。そのため、サブジェクトは一連のプリンシパルで構成されます。プリンシパル名には、制限が一切課されません。

サブジェクトは、認証済みのプリンシパルによってのみ生成されます。認証には、通常、アイデンティティを証明するためにユーザーが提供する証拠(パスワードなど)が含まれます。

さらに、サブジェクトは、「クレデンシャル」と呼ばれるセキュリティ関連の属性も保持します。クレデンシャルは、publicあるいはprivateである場合もあります。非公開暗号化キーなどのサブジェクトの機密なクレデンシャルは、サブジェクトのprivateクレデンシャル・セット内に格納されます。

Subjectクラスは、プリンシパル、およびプリンシパルに関連付けられたpublicクレデンシャルやprivateクレデンシャルを取得するメソッドを保持します。

これらのクラスを操作するには、異なるアクセス権が必要な場合があります。たとえば、サブジェクトのプリンシパル・セットを変更するには、AuthPermission("modifyPrincipals")が必要な場合があります。publicクレデンシャルやprivateクレデンシャルの変更、および現行のサブジェクトの取得にも、同様のアクセス権が必要です。

doAsおよびdoAsPrivileged

Java 2は、java.lang.SecurityManagerを介して実行時アクセス制御を実行します。SecurityManagerは、重要な操作が試行されるたびに参照されます。SecurityManagerは、このタスクをjava.security.AccessControllerに委譲します。AccessControllerは、AccessControlContextの現行のイメージを取得して、AccessControlContextが要求された操作を実行可能なアクセス権を保持していることを確認します。

JAASは、2つのメソッドdoAsおよびdoAsPrivilegedを提供します。これらのメソッドを使用すると、認証済みサブジェクトをAccessControlContextに動的に関連付けることができます。

doAsメソッドは、サブジェクトを現行スレッドのアクセス制御コンテキストに関連付けます。そのあとのアクセス制御は、実行中のコードおよびそれを実行するサブジェクトに基づいて行われます。

public static Object doAs(final Subject subject,
                          final  PrivilegedAction action)

public static Object doAs(final Subject subject,
                          final  PrivilegedExceptionAction action)
    throws  PrivilegedActionException;

どちらの形式のdoAsメソッドも、まず指定されたサブジェクトを現行スレッドのAccessControlContextに関連付けてから、アクションを実行します。これにより、サブジェクトとしてアクションを実行させる効果を実現します。最初のメソッドでは、ランタイム例外がスローされる可能性がありますが、通常の実行では、そのaction引数のrun()メソッドからのObjectが返されます。2番目のメソッドの動作も同様です。ただし、run()メソッドにより、チェックされたPrivilegedActionExceptionがスローされる可能性がある点が異なります。doAsメソッドを呼び出すには、AuthPermission("doAs")が必要です。

次のメソッドでも、特定のサブジェクトとしてコードが実行されます。

public static Object doAsPrivileged(final Subject subject,
                                    final  PrivilegedAction action,
                                    final  AccessControlContext  acc);

public static Object doAsPrivileged(final Subject subject,
                                    final PrivilegedExceptionAction action,
                                    final  AccessControlContext acc)
   throws PrivilegedActionException;

doAsPrivilegedメソッドの動作は、呼出し側がアクセス制御コンテキストを指定可能である点を除き、doAsと同様です。これにより、現行のAccessControlContextは事実上無視されるため、渡されたAccessControlContextに基づいて承認が決定されます。

AccessControlContextはスレッドごとに設定されるため、JVM内の個別のスレッドは、異なる識別情報を保持するものと見なされます。特定のAccessControlContextに関連付けられたサブジェクトは、次のメソッドを使用して取得できます。

public static Subject getSubject(final AccessControlContext acc);

LoginContext

LoginContextクラスは、サブジェクトの認証に使用する基本的なメソッドを提供します。このクラスを使用すると、アプリケーションを基盤となる認証技術から独立させることができます。ログイン・コンテキストは、構成を調べて、特定アプリケーション用に構成された認証サービスまたはログイン・モジュールを判別します。アプリケーションが特定のエントリを保持しない場合、「other」として識別されるデフォルト・エントリが指定されます。

ログイン・モジュールのスタック特性をサポートするために、ログイン・コンテキストは認証を2段階で実行します。最初のログイン段階では、構成済みの各ログイン・モジュールを呼び出して、認証を試みます。必要なログイン・モジュールがすべて成功すると、ログイン・コンテキストは第2段階に入り、各ログイン・モジュールを再度呼び出して認証プロセスを正式にコミットします。この段階で、認証されたプリンシパルおよびそのクレデンシャルを使ってサブジェクトが生成されます。いずれかの段階が失敗すると、ログイン・コンテキストは構成済みの各モジュールを呼び出して、認証全体を中止します。次に、各ログイン・モジュールは、認証に関連する状態をすべてクリーンアップします。

ログイン・コンテキストは、インスタンス化に使用可能な4つのコンストラクタを保持します。どのコンストラクタでも、構成エントリ名の引渡しが必要です。さらにサブジェクトやCallbackHandlerをコンストラクタに渡すことも可能です。

コールバック

JAASにより呼び出されるログイン・モジュールは、認証用の情報を呼出し側から収集できなければなりません。たとえば、Kerberosログイン・モジュールは、認証用のKerberosパスワードの入力をユーザーに要求します。

LoginContextを使用すると、基盤となるログイン・モジュールがユーザーとの対話に使用するコールバック・ハンドラをアプリケーションから指定できます。J2SE 1.4では、コマンド行ベースとGUIベースの2つのコールバック・ハンドラを使用できます。

LoginModule

Sunは、UnixLoginModule、NTLoginModule、JNDILoginModule、KeyStoreLoginModule、およびKrb5LoginModuleの実装を提供します。スマート・カード・ベースのJAASログイン・モジュールは、GemPlus [5]以降で使用可能です。

Kerberosログイン・モジュール

com.sun.security.auth.module.Krb5LoginModuleクラスは、SunによるKerberosバージョン5プロトコル用のログイン・モジュール実装です。認証が成功すると、Ticket Granting Ticket (TGT)がサブジェクトのprivateクレデンシャル・セットに格納され、Kerberosのプリンシパルがサブジェクトのプリンシパル・セットに格納されます。

構成可能な特定のオプションを指定することにより、Krb5LoginModuleでは、既存のクレデンシャル・キャッシュ(オペレーティング・システム内のネイティブ・キャッシュなど)を使用したTGTの取得や、秘密キーを含むキータブ・ファイルを使用したプリンシパルの暗黙的な認証も実行可能です。SolarisおよびWindows 2000プラットフォームの両方には、Krb5LoginModuleがTGTの取得に使用可能なクレデンシャル・キャッシュが含まれます。Solarisには、Krb5LoginModuleが秘密キーの取得に使用可能なシステム規模のキータブ・ファイルも含まれます。Krb5LoginModuleは、すべてのプラットフォームで、選択したチケット・キャッシュまたはキータブ・ファイルにファイル・パスを設定するオプションをサポートします。サード・パーティ製のKerberosサポートがインストールされており、Javaの統合が望まれる場合、これは有用な方法です。これらのオプションの詳細は、Krb5LoginModuleのドキュメントを参照してください。ネイティブ・キャッシュまたはキー・タブが存在しない場合、ユーザーにはKDCから取得したパスワードおよびTGTの入力が求められます。

図1は、クライアント・アプリケーション用JAASログイン構成エントリのサンプルを示します。この例では、Krb5LoginModuleはネイティブ・チケット・キャッシュを使用して、内部で使用可能なTGTを取得します。認証された識別情報は、TGTが所属するKerberosプリンシパルの識別情報になります。

SampleClient {
    com.sun.security.auth.module.Krb5LoginModule required useTicketCache=true
};
             Figure 1. Sample client  configuration entry

図2は、サーバー・アプリケーション用ログイン構成エントリのサンプルを示します。この構成では、プリンシパル「nfs/bar.example.com」の認証に、キー・タブから取得した秘密キーが使用されます。また、Kerberos KDCから取得したTGTと秘密キーの両方が、サブジェクトの非公開クレデンシャル・セットに格納されます。格納されたキーは、クライアントから送信されるサービス・チケットの検証に使用できます(Java GSS-APIセクションを参照)。

SampleServer {
     com.sun.security.auth.module.Krb5LoginModule
         required useKeyTab=true storeKey=true principal="nfs/bar.example.com"
};

             Figure 2. Sample server configuration entry

図3に示すクライアント・コード例では、LoginContextにより構成エントリ「SampleClient」が使用されます。Kerberosパスワードの入力をユーザーに求めるため、TextCallbackHandlerクラスが使用されます。ユーザーがログインすると、Kerberosプリンシパル名およびTGTを使用してサブジェクトが生成されます。これ以後、ユーザーはLoginContextから取得したサブジェクトに渡すSubject.doAsを使用してコードを実行できます。

LoginContext lc = null;

try {
        lc = new LoginContext("SampleClient", new TextCallbackHandler());
        // attempt authentication
        lc.login();
} catch (LoginException le) {
    ...
}

 // Now try to execute ClientAction as the authenticated Subject

 Subject mySubject = lc.getSubject();
 PrivilegedAction action = new ClientAction();
 Subject.doAs(mySubject, action);

            Figure 3. Sample client code

ClientActionアクションを、指定された値を保持する認証済みのKerberosクライアントPrincipalにのみ許可できます。

図4に、サーバー側のサンプル・コードを示します。これは、アプリケーションのエントリ名およびPrivilegedActionを除けば、図3のクライアント・コードに類似しています。

LoginContext lc = null;

try {
        lc = new LoginContext("SampleServer", new TextCallbackHandler());
        // attempt authentication
        lc.login();
} catch (LoginException le) {
   ...
}

// Now try to execute ServerAction as the authenticated Subject

Subject mySubject = lc.getSubject();
PrivilegedAction action = new ServerAction();
Subject.doAs(mySubject, action);

            Figure 4. Sample server code

Kerberosクラス

ほかのベンダーがJava GSS-APIで使用可能な独自のKerberosログイン・モジュール実装を提供できるようにするため、javax.security.auth.kerberosパッケージに3つの標準Kerberosクラスが導入されました。これらは、Kerberosプリンシパル用のKerberosPrincipal、長期のKerberos秘密キー用のKerberosKey、およびKerberosチケット用のKerberosTicketです。Kerberosログイン・モジュールのすべての実装で、これらのクラスを使用して、プリンシパル、キー、およびチケットをサブジェクト内に格納する必要があります。

承認

サブジェクトの認証が成功したら、認証されたサブジェクトに関連付けられたプリンシパルに基づいてアクセス制御を実行できます。JAASプリンシパルベースのアクセス制御は、Java 2のCodeSourceアクセス制御を強化します。サブジェクトに付与されるアクセス権は、システム規模のアクセス制御ポリシーを表す抽象クラスであるPolicy内で構成されます。Sunは、Policyクラスの実装をファイルベースで提供します。Policyクラスはプロバイダ・ベースであるため、他者が独自のポリシー実装を提供することが可能です。

JAVA GENERIC SECURITY SERVICE APPLICATION PROGRAM INTERFACE (Java GSS-API)

Generic Security Service API (GSS-API)

エンタープライズ・アプリケーションは、多くの場合、様々なセキュリティ要件を保持し、この実現のため、広範な基盤のテクノロジを配備します。このようなシナリオでは、あるテクノロジから別のテクノロジに簡単に移行できるように、クライアント/サーバー・アプリケーションをどのように開発すればよいでしょうか。この問題を解決するため、IETFのCommon Authentication Technologyワーキング・グループで、呼出し元を基盤のテクノロジの詳細から分離するピア・ツー・ピア認証およびセキュアな通信のための統一のアプリケーション・プログラミング・インタフェースを提供することによって、GSS-APIが設計されました。

RFC 2743 [6]にあるように、このAPIは言語非依存の形式で記述されており、認証、メッセージ機密性および整合性、保護されたメッセージの順序付け、再実行の検出およびクレデンシャルの委任などのセキュリティ・サービスに対応します。使用する基盤となるセキュリティ・テクノロジまたは「セキュリティ・メカニズム」では、本質的な一方向認証に加え、これらの機能の1つ以上をサポートするように選択できます。脚注1

IETFにより定義された標準セキュリティ・メカニズムには、Kerberos V5 [6]およびSimple Public Key Mechanism (SPKM)[8]の2つが存在します。

こうしたAPIの設計により、実装で複数のメカニズムを同時にサポートできるため、アプリケーションは実行時にいずれかのメカニズムを選択できます。メカニズムは、IANAに登録された一意のオブジェクト識別子(OID)により識別されます。たとえば、Kerberos V5メカニズムは、{iso(1) member-body(2) United States(840) mit(113554) infosys(1) gssapi(2) krb5(2)}というOIDで識別されます。

このAPIの別の重要な特徴は、これがトークン・ベースである点です。つまり、APIの呼び出しにより、不透明なオクテットが生成され、アプリケーションはそれをそのピアに転送する必要があります。これにより、APIをトランスポートから独立させることができます。

複数メカニズムGSS-API

図5. 複数メカニズムGSS-API実装

Java GSS-API

Generic Security Service用のJava APIもIETFで定義されており、RFC 2853 [10]にドキュメント化されています。Sunは、Java Community Process (JCP)[11]の下でこのAPIの標準化を目指しており、またリファレンス実装の提供を計画しています。JCPは、この外部で定義されたAPIを単に支持するだけです。IETFにより割り当てられたパッケージ名前空間「org.ietf.jgss」は、引き続きJ2SE 1.4内に保持されます。

初期出荷段階では、SunによるJava GSS-API実装は、Kerberos V5メカニズムのみをサポートします。Kerberos V5メカニズムのサポートは、Java SEのすべてのJava GSS-API実装で義務付けられています。他のメカニズムをサポートするかどうかは任意です。将来のリリースでは、Service Provider Interface (SPI)が追加され、新たなメカニズムを静的または実行時に構成できるようになります。現在でも、リファレンス実装はモジュール化されており、非公開のプロバイダSPIをサポートします。非公開のプロバイダSPIは、標準化の際、公開に変換されます。

Java GSS-APIフレームワーク自体はthinであるため、セキュリティ関連の機能はすべて、基盤となるメカニズムから取得したコンポーネントへ委譲されます。GSSManagerクラスは、インストール済みのメカニズム・プロバイダをすべて認識するため、プロバイダを呼び出してこれらのコンポーネントを取得できます。

Java SEに含まれるデフォルトのGSSManager実装は、次の方法で取得できます。

GSSManager manager = GSSManager.getInstance();

GSSManagerは新規プロバイダを構成したり、現存するすべてのメカニズムをリストしたりするために使用されます。GSSManagerは、3つの重要なインタフェース、GSSName、GSSCredential、およびGSSContextのファクトリ・クラスとしても機能します。これらのインタフェースおよびその実装をインスタンス化するメソッドについては、次に説明します。API仕様全体については、[9]および[11]を参照してください。

大半のJava GSS-API呼出しでは、GSS-APIフレームワーク内およびメカニズム・プロバイダ内の両方で発生する問題をカプセル化するGSSExceptionがスローされます。

GSSNameインタフェース

このインタフェースは、Java GSS-APIにおけるエンティティを表します。このインタフェース実装は、次の方法でインスタンス化されます。

GSSName GSSManager.createName(String name, Oid nameType)
    throws GSSException

例:

GSSName clientName = manager.createName("duke", GSSName.NT_USER_NAME);

この呼出しにより、GSSNameが返されます。これは、メカニズム非依存レベルのユーザー・プリンシパル「duke」を表します。内部的には、サポートされる各メカニズムが、ユーザーの汎用表現をよりメカニズム固有の形式にマッピングすることを前提としています。たとえば、Kerberos V5メカニズム・プロバイダは、この名前をduke@EXAMPLE.COMにマッピングできます(EXAMPLE.COMはローカルのKerberosレルム)。同様に、公開キーベースのメカニズム・プロバイダは、この名前をX.509識別名にマッピングします。

このドキュメントで、ユーザー以外の何らかのサービスとしてのプリンシパルに言及する場合、メカニズムがそれを異なる方法で解釈できるようにJava GSS-API呼出しを行うことを意味しています。

例:

GSSName serverName = manager.createName("nfs@bar.example.com",
                                         GSSName.NT_HOSTBASED_SERVICE);

Kerberos V5メカニズムは、この名前をKerberos固有の形式nfs/bar.example.com@EXAMPLE.COMにマッピングします(EXAMPLE.COMはプリンシパルのレルム)。このプリンシパルは、ホスト・マシンbar.example.comで稼動中のnfsサービスを表します。

SunによるGSSNameインタフェースの実装は、コンテナ・クラスです。コンテナ・クラスは、メカニズムの使用時にマッピングを行い、マッピングされた各要素をプリンシパル・セットに格納するよう、各プロバイダに適宜要求します。この面で、GSSNameの実装はサブジェクトに格納されたプリンシパル・セットに似ています。この実装には、サブジェクトのプリンシパル・セット内の要素と同じものを含めることもできますが、用途はJava GSS-APIのコンテキストに限定されています。

Sun Kerberos V5プロバイダにより格納される名前要素は、javax.security.auth.kerberos.KerberosPrincipalのサブクラスのインスタンスです。

GSSCredentialインタフェース

このインタフェースは、任意の1つのエンティティが所有するクレデンシャルをカプセル化します。GSSNameと同様、このインタフェースも複数メカニズム・コンテナです。

この実装は、次の方法でインスタンス化されます。

GSSCredential createCredential(GSSName name,
                               int lifetime,
                               Oid[] desiredMechs,
                               int usage)

    throws GSSException

クライアント側での呼出し例を、次に示します。

GSSCredential clientCreds =
               manager.createCredential(clientName,
                                        8*3600,
                                        desiredMechs,
                                        GSSCredential.INITIATE_ONLY);

GSSManagerはdesiredMechsにリストされたメカニズムのプロバイダを呼び出して、GSSName clientNameに所属するクレデンシャルを要求します。さらに、8時間のライフ・タイムを要求し、アウト・バウンド要求を開始可能なクレデンシャル(クライアント・クレデンシャル)でなければならないという制限を課します。返されるオブジェクトには、この条件を満たすために使用可能なクレデンシャルを保持するdesiredMechsのサブセットの要素が含まれます。Kerberos V5メカニズムにより格納される要素は、ユーザーに属するTGTを含むjavax.security.auth.kerberos.KerberosTicketのサブクラスのインスタンスです。

サーバー側でのクレデンシャル取得は、次のように実行されます。

GSSCredential serverCreds =
          manager.createCredential(serverName,
                                   GSSCredential.INDEFINITE_LIFETIME,
                                   desiredMechs,
                                   GSSCredential.ACCEPT_ONLY);

クライアントに対する動作も同様です。ただし、要求されるクレデンシャルの種類が、着信要求(サーバークレデンシャル)を受け付けられるものである点が異なります。さらに、通常サーバーは長期にわたり稼動するため、存続期間の長いクレデンシャル(ここに示したINDEFINITE_LIFETIMEなど)を要求します。格納されたKerberos V5メカニズムの要素は、サーバーの秘密キーを含むjavax.security.auth.kerberos.KerberosKeyのサブクラスのインスタンスです。

このステップでは、高い負荷がかかることがあります。さらに、通常、アプリケーションは、ライフ・タイムの間に使用する可能性のあるすべてのクレデンシャルへの参照を初期化時に取得します。

GSSContextインタフェース

GSSContextインタフェースの実装は、2つのピアにセキュリティ・サービスを提供します。

クライアント側では、次のAPI呼出しでGSSContext実装が取得されます。

GSSContext GSSManager.createContext(GSSName peer,
                                    Oid mech,
                                    GSSCredential clientCreds,
                                    int lifetime)
    throws GSSException

これにより、通信先のピアおよび通信に使用するメカニズムを認識する、初期化済みのセキュリティ・コンテキストが返されます。クライアントのクレデンシャルは、ピアの認証に必要です。

サーバー側では、次の方法でGSSContextを取得できます。

GSSContext GSSManager.createContext(GSSCredential serverCreds)
    throws GSSException

これにより、受け入れ側の初期化済みセキュリティ・コンテキストが返されます。この時点では、コンテキスト確立要求を送信するピア(クライアント)の名前、および使用する基盤となるメカニズムでさえも不明です。ただし、着信要求がクレデンシャルserverCredsにより表されるサービス・プリンシパル用でないか、クライアント側が要求する基盤となるメカニズムがserverCreds内にクレデンシャル要素を保持しない場合、要求は失敗します。

GSSContextをセキュリティ・サービスで使用する前に、2つのピア間でトークンを交換してGSSContextを確立する必要があります。コンテキスト確立メソッドへの各呼出しにより、不透明なトークンが生成され、アプリケーションは、このトークンを選択した通信チャネルを使用してピアに送信する必要があります。

クライアントは、次のAPI呼出しを使用してコンテキストを確立します。

byte[] GSSContext.initSecContext(byte[] inToken,
                                 int offset,
                                 int len)

   throws GSSException

サーバーは次の呼出しを使用します。

byte[] acceptSecContext(byte[] inToken,
                        int offset,
                        int len)

   throws GSSException

これら2つのメソッドは相補的な関係にあり、一方で生成された出力が、他方で入力として受け入れられます。クライアントがはじめてinitSecContextを呼び出すと、最初のトークンが生成されます。呼出し時に、このメソッドの引数は無視されます。最後に生成されるトークンは、使用するセキュリティ・メカニズムの詳細、および確立されたコンテキストのプロパティによって異なります。

ピアの認証に必要なGSS-APIトークンの往復回数は、メカニズムごと、また特性ごと(相互認証か一方向の認証かなど)に異なります。このため、アプリケーションの各側は、コンテキスト確立メソッドの呼出しを、プロセスが完了するまで、ループ内で継続して実行する必要があります。

Kerberos V5メカニズムの場合、コンテキスト確立時にトークンは1往復するだけです。クライアントは、最初にinitSecContext()により生成されたトークン(Kerberos AP-REQメッセージ[2]を含む)を送信します。AP-REQメッセージを生成するために、Kerberosプロバイダは、クライアントのTGTを使用してターゲット・サーバー用のサービス・チケットを取得します。サービス・チケットは、サーバーの長期秘密キーを使用して暗号化され、AP-REQメッセージの一部としてカプセル化されます。サーバーはこのトークンを受け取ると、acceptSecContext()メソッドに送信します。このメソッドにより、サービス・チケットの復号化およびクライアントの認証が行われます。相互認証が要求されなかった場合、クライアント側とサーバー側の両方のコンテキストが確立されます。サーバー側のacceptSecContext()は出力を生成しません。

ただし、相互認証が有効な場合、サーバーのacceptSecContext()はKerberos AP-REP [2]メッセージを含む出力トークンを生成します。このトークンをクライアントに送り返し、initSecContext()を使って処理を行なってから、クライアント側コンテキストを確立する必要があります。

クライアント側でGSSContextを初期化する際、どの基盤となるメカニズムを使用するかは明白です。Java GSS-APIフレームワークは、適切なメカニズム・プロバイダからのコンテキスト実装を取得できます。このため、GSSContextオブジェクトに対する呼出しはすべて、メカニズムのコンテキスト実装に委譲されます。サーバー側の場合、クライアント側からの最初のトークンが到着するまで、使用するメカニズムは決定されません。

次のクラスは、アプリケーションのクライアント側をコード化する方法を示します。これは、図3のdoAsメソッドを使用して実行されたClientActionクラスです。

class ClientAction implements PrivilegedAction {

    public Object run() {
        ...
        ...
        try {
            GSSManager manager = GSSManager.getInstance();
            GSSName clientName =
                manager.createName("duke", GSSName.NT_USER_NAME);
            GSSCredential clientCreds =
                manager.createCredential(clientName,
                                          8*3600,
                                          desiredMechs,
                                          GSSCredential.INITIATE_ONLY);
            GSSName peerName =
                manager.createName("nfs@bar.example.com",
                                    GSSName.NT_HOSTBASED_SERVICE);
            GSSContext secContext =
                manager.createContext(peerName,
                                      krb5Oid,
                                      clientCreds,
                                      GSSContext.DEFAULT_LIFETIME);
            secContext.requestMutualAuth(true);

            // The first input token is ignored
            byte[] inToken = new byte[0];

            byte[] outToken = null;

            boolean established = false;

           // Loop while the context is still not established
           while (!established) {
               outToken =
                   secContext.initSecContext(inToken, 0, inToken.length);

               // Send a token to the peer if one was generated
               if (outToken != null)
                  sendToken(outToken);

               if (!secContext.isEstablished()) {
                  inToken = readToken();
               else
                  established = true;
            }
        } catch (GSSException e) {
             ....
        }
        ...
        ...
    }
}


        Figure 6. Sample client using Java GSS-API

次に、図4のServerActionクラスを実行するサーバー側に対応するコード・セクションを示します。

class ServerAction implements PrivilegedAction {

    public Object run() {
        ...
        ...
        try {
            GSSManager manager = GSSManager.getInstance();
            GSSName serverName =
                manager.createName("nfs@bar.example.com",
                                    GSSName.NT_HOSTBASED_SERVICE);
            GSSCredential serverCreds =
             manager.createCredential(serverName,
                                       GSSCredential.INDEFINITE_LIFETIME,
                                       desiredMechs,
                                       GSSCredential.ACCEPT_ONLY);
            GSSContext secContext = manager.createContext(serverCreds);

            byte[] inToken = null;
            byte[] outToken = null;

            // Loop while the context is still not established
            while (!secContext.isEstablished()) {
                 inToken = readToken();
                 outToken =
                     secContext.acceptSecContext(inToken, 0, inToken.length);

                  // Send a token to the peer if one was generated
                  if (outToken != null)
                      sendToken(outToken);
            }
        } catch (GSSException e) {
          ...
        }
        ...
        ...
   }
}

             Figure 7. Sample server using Java GSS-API

メッセージ保護

セキュリティ・コンテキストを確立すると、それを使用してメッセージを保護できるようになります。Java GSS-APIは、メッセージの整合性および機密性の両方を提供します。これを実現する2つの呼出しを、次に示します。

byte[] GSSContext.wrap(byte[] clearText,
                       int offset,
                       int len,
                       MessageProp properties)
    throws GSSException
および
byte[] unwrap(byte[] inToken,
              int offset,
              int len,
              MessageProp properties)
    throws GSSException

wrapメソッドを使用して、クリアテキスト・メッセージをトークン内にカプセル化し、整合性を保護します。propertiesオブジェクトを介してこれを要求することにより、メッセージを暗号化することもできます(オプション)。wrapメソッドは、不透明なトークンを返し、呼出し元がそのピアに送信します。トークンがピアに渡されると、ピアのunwrapメソッドにより元のクリアテキストが返されます。unwrap側のpropertiesオブジェクトは、メッセージの整合性が保護されているだけなのか、暗号化も行われているかを示す情報を返します。これには順序付けと重複したトークンの警告が含まれます。

クレデンシャルの委譲

Java GSS-APIを使用すると、クライアントがクレデンシャルをサーバーにセキュアに委譲できるようになるため、サーバーはクライアントのためにほかのセキュリティ・コンテキストを開始できます。この機能は、多層環境でシングル・サインオンを実行する場合に有用です。

多層環境でのクレデンシャルの委譲

図8. クレデンシャルの委譲

クライアントは、initSecContext()の呼出しを最初に実行する前に、クレデンシャルの委譲を要求します。

void GSSContext.requestCredDeleg(boolean state)
    throws GSSException
その際、stateをtrueに設定します。

サーバーは、コンテキストの確立後に、委譲されたクレデンシャルを受け取ります。

GSSCredential GSSContext.getDelegCred() throws GSSException

次に、サーバーはクライアントを装って、このGSSCredentialをGSSManager.createContext()に渡すことができます。

Kerberos V5メカニズムの場合、委譲されるクレデンシャルとは、クライアントからサーバーに送信される最初のトークンの一部としてカプセル化される転送されたTGTです。このTGTを使用して、サーバーはクライアントに代わり、ほかのサービス用のサービス・チケットを取得できます。

デフォルト・クレデンシャル取得モデル

アプリケーションが、GSSManager.createCredential()メソッドを使用してメカニズム固有のクレデンシャルを保持するGSSCredentialオブジェクトを生成する方法については、すでに説明しました。次の2つのサブセクションでは、Java GSS-APIメカニズムを使用してこれらのクレデンシャルを取得する方法に焦点を当てて説明します。メカニズム自体が、ユーザーのログインを実行することはありません。Java GSS-APIを使用する前にログインを実行することおよびメカニズム・プロバイダにとって既知のキャッシュ内にクレデンシャルが格納されていることが前提となっています。GSSManager.createCredential()メソッドは、これらのクレデンシャルへの参照を取得し、GSSを中心とするコンテナであるGSSCredentialに格納して返すにすぎません。

Java 2プラットフォームでは、Java GSS-APIメカニズム・プロバイダがこれらの要素の取得に使用するクレデンシャル・キャッシュはすべて、現行のアクセス制御コンテキストのサブジェクト内のpublicおよびprivateクレデンシャル・セットでなければなりません。

このモデルには、アプリケーションの観点から、クレデンシャル管理が単純で予測しやすいという利点があります。適切なアクセス権を付与されたアプリケーションは、サブジェクト内のクレデンシャルを取り除いたり、標準Java APIを使用してクレデンシャルを更新したりできます。クレデンシャルを取り除いた場合にはJava GSS-APIメカニズムは失敗し、時間ベースのクレデンシャルを更新した場合にはメカニズムは成功します。

図3および図6のクライアント・アプリケーションがKerberos V5のメカニズムを使用する場合の、クレデンシャル取得関連のイベントの発生順序を、次に示します。

  1. アプリケーションがJAASログインを呼び出し、JAASログインが構成済みのKrb5LoginModuleを呼び出します。

  2. Krb5LoginModuleは、KDCまたは既存のチケット・キャッシュからユーザー用のTGT (KerberosTicket)を取得して、TGTをサブジェクトのprivateクレデンシャル・セットに格納します。

    注意: Krb5LoginModuleは、クレデンシャル・キャッシュ(MIT krb 5スタイルのKerberosクレデンシャル・キャッシュ(ccache)ファイル、またはWindows Local Security Authority (LSA)などのネイティブ・サービス)内で初期TGTを検索し、TGTを所有するプリンシパルのクレデンシャルを作成できます。

    また、クレデンシャル・キャッシュがproxy_impersonator構成キーを含むMIT krb 5 ccacheファイル(クレデンシャル・キャッシュ・ファイル形式を参照)である場合、Krb5LoginModuleは同じccacheファイルからエビデンス・チケットを読み取り、かわりにこのエビデンス・チケットを所有するプリンシパルの委譲されたクレデンシャルを作成します。この委譲されたクレデンシャルは、制約付き委任に使用できます。

    クレデンシャルの所有者を取得するには、取得したクレデンシャルからGSSCredenial.getName()メソッドを呼び出すか、このクレデンシャルによって作成された確立済のGSSContextオブジェクトのgetSrcName()メソッドを呼び出します。

  3. アプリケーションは、生成されたサブジェクトを取得してから、Subject.doAs/doAsPrivilegedを呼び出して、ClientActionを実行するスレッドのアクセス制御コンテキストにこのサブジェクトを配置します。

  4. ClientActionはGSSManager.createCredentialメソッドを呼び出して、desiredMechs内のKerberos V5 OIDを渡します。

  5. GSSManager.createCredentialはKerberos V5 GSS-APIプロバイダを呼び出して、セキュリティ・コンテキストを開始するためのKerberosクレデンシャルを要求します。

  6. Kerberosプロバイダは、現行のアクセス制御コンテキストからサブジェクトを取得し、ユーザーのTGTを表す有効なKerberosTicketのそのprivateクレデンシャル・セットを検索します。

  7. KerberosTicketがGSSManagerに返されます。GSSManagerはKerberosTicketをGSSCredentialコンテナ・インスタンス内に格納して、呼出し側に返します。

サーバー側では、ステップ2のKerberosログインが成功すると、Krb5LoginModuleが、KerberosTicketに加え、サーバー用のKerberosKeyをサブジェクト内に格納します。そのあと、ステップ5 - 7で取得されるKerberosKeyを使用して、クライアントから送信されるサービス・チケットの暗号解読が行われます。

デフォルト・クレデンシャル取得モデルの例外

Java GSS-API用のデフォルト・クレデンシャル取得モデルでは、クレデンシャルが現行のサブジェクト内に存在する必要があります。一般に、JAASログイン後、クレデンシャルはアプリケーションによりこの場所に配置されます。

時には、アプリケーションで、サブジェクト外のKerberosクレデンシャルを使用することが望まれる場合があります。この場合、Krb5LoginModuleが読取りを行うように構成するか、読取りを行うカスタム・ログイン・モジュールを記述して、この種のクレデンシャルを初期JAASログインの一部として読み取ることが推奨されています。ただし、アプリケーションの中には、Java GSS-APIを呼び出す前にJAASを使用できない、または現行のサブジェクトからクレデンシャルを取得しないKerberosメカニズム・プロバイダの使用を強制されるものがあります。

ほかのアプリケーション用の標準モデルを維持しつつ、このような場合に対処するため、システム・プロパティjavax.security.auth.useSubjectCredsOnlyが追加されました。これはboolean型のシステム・プロパティで、値がtrueの場合は標準クレデンシャル取得モデルが使用され、falseの場合はプロバイダに任意のキャッシュの使用が許可されます。このプロパティのデフォルト値(設定しない場合)は、trueです。

現行のサブジェクト内に有効なKerberosクレデンシャルが存在せず、このプロパティがtrueの場合、KerberosメカニズムはGSSExceptionをスローします。このプロパティをfalseに設定しても、プロバイダが現行のサブジェクト以外のキャッシュを使用しなければならないわけではなく、必要な場合には使用可能であることを意味するに過ぎません。

Kerberos V5 GSS-APIメカニズム用のSunプロバイダは、常にサブジェクトからクレデンシャルを取得します。現行のサブジェクトに有効なクレデンシャルが存在せず、このプロパティがfalseに設定されている場合、プロバイダはJAASログイン自体を呼び出すことにより、一時的なサブジェクトから新規クレデンシャルの取得を試みます。それは、ユーザーとの入力/出力にテキスト・コールバック・ハンドラを使用し、使用するモジュールおよびオプションのリストに「other」で識別されるJAAS構成エントリを使用します。脚注2

Kerberos V5 GSS-APIメカニズムのSunプロバイダでは、これらのモジュールのいずれかがKerberosログイン・モジュールになることが前提です。「other」の下にリストされたモジュールを構成して既存のキャッシュの読取りを行い、Java GSS-APIの呼出し中にユーザーが予期しない方法でパスワードの入力を求められることがないようにできます。このログインにより生成された新規サブジェクトは、要求されたクレデンシャルが取得されるとすぐに、Kerberos GSS-APIメカニズムにより破棄されます。

Webブラウザの統合

Javaシングル・サインオンを利用する必要のあるアプリケーションの重要なクラスは、アプレットです。ここでは、ブラウザJREが必要なすべてのパッケージを保持するか、ユーザーのインストールしたJ2SE 1.4のJREとともにJavaプラグインが使用されるものと仮定します。

アプレットを使用する上で1つの複雑な問題は、アプレットが、Java GSS-APIの使用前にJAASログインを実行する必要があるという点にあります。このことに関する主要な問題は、(a)アプレット開発者に求められる労力の増加、および(b)同一のユーザーがアプレットを起動するたびにログインが不必要に繰返し実行されることです。

この問題を解決するのは、起動時にブラウザ(またはJavaプラグイン)がJAASログインを一度実行するようなモデルです。この場合、どのようなJavaコードの実行時にも、アクセス制御コンテキストへの関連付けが常に可能なサブジェクトが提供されます。結果として、アプレット・コードは、Java GSS-APIの使用前にJAASログインを実行する必要はなくなり、ユーザー・ログインは一度だけ行われます。

ブラウザ(またはJavaプラグイン)にこのログイン機能が存在しない場合でも、アプレットはJAASログインの実行を回避できます。これには、アプレットでシステム・プロパティjavax.security.auth.useSubjectCredsOnlyをfalseに設定し、現行のサブジェクト以外のソースからクレデンシャルを取得可能なGSS-APIメカニズム・プロバイダを使用する必要があります。Sun Kerberos GSS-APIプロバイダとSun JREを併用する場合、メカニズムによりJAASログインが実行されて、前のセクションで説明した新規クレデンシャルが取得されることを期待できます。アプレット・デプロイヤが行う必要があるのは、適切なモジュールおよびオプションが、JREの使用するJAAS構成の「other」エントリ・リストに記載されていることの確認だけです。これにより、アプレットの開発者は、JAAS APIを直接呼び出す必要がなくなりますが、ユーザーが各アプレットを実行するたびにJAASログインが繰返し発生するのを防ぐことはできません。ただし、ログイン・モジュールを構成して既存のネイティブ・キャッシュを読み取ることにより、デプロイヤはログインをユーザーから隠すと同時に、複数のログインによるオーバーヘッドを抑えることができます。(JAAS構成エントリ「SampleClient」でこれを行う方法については、図1を参照)。

セキュリティ上の危険

シングル・サインオンによる利便性向上により、新たな危険も生まれます。悪意のあるユーザーが、だれも操作していないデスクトップにアクセスし、通常のユーザーと同様にアプレットを起動できるとしたらどうでしょうか。また、悪意のあるアプレットが、通常のユーザーと同様にサービスへのサイン・オンを実行する場合、しかも悪意のあるアプレットによるサービスへのサイン・オンが想定されていないとしたらどうでしょうか。

前者の場合、ユーザーに対し、ワークステーションをロックせずに席を立つことがないよう注意する以外に解決策はありません。後者の場合、多数の承認チェックが配備されています。

アクセス権モデルの詳細を理解するため、ブラウザが起動時にJAASログインを実行し、サブジェクトをその内部で実行するすべてのアプレットに関連付けた場合を考えましょう。

サブジェクトは、javax.security.auth.AuthPermissionクラスにより、破壊行為を行うアプレットから保護されます。コードにより、いずれかのアクセス制御コンテキストに関連付けられたサブジェクトへの参照取得が試みられる場合、常にこのアクセス権のチェックが行われます。

アプレットがサブジェクトへのアクセス権を付与されている場合でも、その内部に格納された機密のprivateクレデンシャルを実際に読み取るには、javax.security.auth.PrivateCredentialPermissionが必要になります。

クレデンシャルの所有者に代わって、クレデンシャルの読み取りおよびセキュリティ・コンテキストの確立を行う場合、Java GSS-APIメカニズム・プロバイダにより、ほかの種類のチェックも行う必要があります。Kerberos V5メカニズムをサポートするため、次の2つのアクセス権クラスがjavax.security.auth.kerberosパッケージに新たに追加されました。

ServicePermission(String servicePrinicipal, String action)
DelegationPermission(String principals)

新規GSS-APIメカニズムはJava SE用に標準化されているため、このメカニズムのプロバイダに対応した関連するアクセス権クラスを含む、より多くのパッケージが今後追加される予定です。

Kerberos GSS-APIメカニズムでは、プログラム実行時に、次のポイントでアクセス権チェックが行われます。

クレデンシャルの取得

GSSManager.createCredential()メソッドは、現行のサブジェクトなどのキャッシュからメカニズム固有のクレデンシャル要素を取得して、GSSCredentialコンテナに格納します。GSSCredentialの自由な取得をアプレットに許可することは、アプレットがGSSCredentialを使用して多くのことを行えないとしても、望ましいことではありません。そうすることは、ユーザーおよびサービス・プリンシパルの存在に関する情報をリークしてしまうことになります。このため、アプリケーションが、内部のいずれかのKerberosクレデンシャル要素を使ってGSSCredentialを取得する前に、ServicePermissionのチェックが行われます。

クライアント側では、GSSCredential取得成功は、キャッシュからTGTへのアクセスが行われたことを意味します。このため、次のServicePermissionがチェックされます。

ServicePermission("krbtgt/EXAMPLE.COM@EXAMPLE.COM", "initiate");

サービス・プリンシパルkrbtgt/EXAMPLE.COM@EXAMPLE.COMは、KerberosレルムEXAMPLE.COM内のチケット交付サービス(TGS)を表します。また、アクション「initiate」は、このサービスへのチケットがアクセス中であることを示します。クライアント側のクレデンシャル取得時に、このアクセス権チェックでTGSサービス・プリンシパルが常に使用されます。

サーバー側では、GSSCredential取得成功は、キャッシュから秘密キーへのアクセスが行われたことを意味します。このため、次のServicePermissionがチェックされます。

ServicePermission("nfs/bar.example.com@EXAMPLE.COM", "accept");

ここで、サービス・プリンシパルnfs/bar.example.comはKerberosサービス・プリンシパルを、アクション"accept"はこのサービスの秘密キーが要求されていることを、それぞれ表します。

コンテキストの確立

特定サーバー(例、LDAPサーバー)への接続用アクセス権を保持するアプレットは、別のサーバー(例、FTPサーバー)に接続してはいけません。当然、SocketPermissionの働きにより、アプレットがこの種の動作を行うことは制限されます。ただし、ネットワーク接続が許可された場合でも、ServicePermissionを使用して、識別情報による認証を制限することは可能です。

Kerberosメカニズム・プロバイダは、コンテキストの確立を開始する際に、ServicePermissionをチェックします。

ServicePermission("ftp@EXAMPLE.COM", "initiate");

これにより、承認されていないコードによる、プリンシパルftp@EXAMPLE.COMに対するKerberosサービス・チケットの取得および使用を防ぐことができます。

このアクセス権を使用して、特定のサービス・プリンシパルへの制限されたアクセスを提供することは、やはり危険です。ダウンロードされたコードには、コードの出所であるホストとの通信が許可されます。悪意のあるアプレットが、ターゲット・サービス・プリンシパルの長期秘密キーで暗号化されたKerberosTicketを含む初期GSS-API出力トークンを送り返す可能性があります。このため、オフラインの辞書攻撃にさらされる危険性があります。この理由で、信頼できないサイトからダウンロードされたコードに、「initiate」ServicePermissionを付与することは、お薦めできません。

サーバー側では、着信するセキュリティ・コンテキスト確立要求を秘密キーを使用して受け入れるためのアクセス権は、クレデンシャル取得時にチェック済みです。このため、コンテキスト確立段階では、チェックは行われません。

クレデンシャルの委譲

ユーザーに代わってサーバーとのセキュリティ・コンテキストを確立するアクセス権を保持するアプレットは、サーバーへのクレデンシャルの委譲を要求できます。ただし、すべてのサーバーが、クレデンシャルを委譲できるだけの信頼性を保持するわけではありません。このため、Kerberosプロバイダは、委譲されたクレデンシャルを取得してピアに送信する前に、次のアクセス権をチェックします。

DelegationPermission(" \"ftp@EXAMPLE.COM\" \"krbtgt/EXAMPLE.COM@EXAMPLE.COM\" ");

このアクセス権により、Kerberosサービス・プリンシパルftp@EXAMPLE.COMは、転送されたTGT (チケット交付サービスkrbtgt/EXAMPLE.COM@EXAMPLE.COMにより表される)を受信できます。脚注3

結論

このドキュメントでは、Javaでシングル・サインオンを可能にするフレームワークについて解説しました。これには、初期認証を行ってクレデンシャルを取得するJAASと、それらのクレデンシャルを使用してセキュアな回線通信を行うJava GSS-APIとの間で、クレデンシャルの共有が必要です。ここでは、基盤となるセキュリティ・システムとして、Kerberos V5に焦点を当てて説明しました。ただし、JAASのスタック・アーキテクチャおよびJava GSS-APIの複数メカニズム対応のために、任意の数の異なるメカニズムを同時に使用できます。

JAAS用のKerberosログイン・モジュールは、ネイティブ・キャッシュの読取りが可能であるため、Kerberosをサポートするプラットフォームのデスクトップにログインする場合以外、ユーザーは自らを認証する必要がありません。さらに、Java GSS-API用のKerberos V5メカニズムを使用することにより、クレデンシャルを委譲して、多層環境へのシングル・サインオンを可能にできます。

最後に、Kerberosの提供するシングル・サインオン機能が承認なしで使用されることを防ぐ、多数のアクセス権チェックを紹介しました。

謝辞

Kerberosシングル・サインオン・プロジェクトの各段階での貢献に対し、Gary Ellison、Charlie Lai、およびJeff Nisewangerに感謝します。JAAS 1.0は、Charlieにより、J2SE 1.3のオプション・パッケージとして実装されました。Kerberos Java GSS-APIメカニズムのアクセス権モデルを設計する際、Garyが尽力してくれました。JAAS 1.0の統合に関してフィードバックを送ってくれたBob Scheiflerに、またKeyStoreLoginModuleおよびCallbackHandler実装に関して尽力してくれたTim Blackmanに感謝します。また、コメントや提案をくださった、Bruce Rich、Tony Nadalin、Thomas Owusu、Yanni Zhangの諸氏にも感謝します。ドキュメントやチュートリアルの面で援助してくれたMary Dagefordeに感謝します。Sriramulu Lakkaraju、Stuart Ke、およびShital Shisodeは、プロジェクトのテストを担当してくれました。Maxine Erlundは、プロジェクト管理をサポートしてくれました。

参照情報

  1. Neuman, CliffordおよびTso, Theodore(1994年)。『Kerberos: An Authentication Service for Computer Networks』IEEE Communications、第39巻33 - 38ページ
  2. J.KohlおよびC.Neuman。『The Kerberos Network Authentication Service (V5)』、Internet Engineering Task Force、1993年9月RFC 1510
  3. V. SamarおよびC. Lai。『Making Login Services Independent from Authentication Technologies』『In Proceedings of the SunSoft Developer's Conference』1996年3月。
  4. 『X/Open Single Sign-On Service (XSSO) - Pluggable Authentication』。仮仕様702ページ、The Open Group、1997年6月。http://www.opengroup.org
  5. 『A Smart Card Login Module for Java Authentication and Authorization Service』http://www.gemplus.com/techno/smartjaas/index.html
  6. J. Linn。『Generic Security Service Application Program Interface,Version 2』、Internet Engineering Task Force、2000年1月RFC 2743
  7. J. Linn。『The Kerberos Version 5 GSS-API Mechanism』Internet Engineering Task Force、1996年6月RFC 1964
  8. C.Adams。『The Simple Public-Key GSS-API Mechanism (SPKM)』Internet Engineering Task Force、1996年10月RFC 2025
  9. J. KabatおよびM.Upadhyay。『Generic Security Service API Version 2: Java Bindings』Internet Engineering Task Force、1997年1月RFC 2853
  10. 『JSR 000072 Generic Security Services API』
  11. Java Platform, Standard Edition API仕様

脚注1 GSS-API Kerberosメカニズムは、最低限、クライアント認証を実行します。

脚注2 最初に、クライアントに対してJAAS構成エントリ「com.sun.security.jgss.initiate」の使用、サーバーに対して「com.sun.security.jgss.accept」の使用が試みられます。これらのエントリが存在しない場合、「other」のエントリが使用されます。これにより、システム管理者は、その動作をより細かく制御できるようになります。

脚注3 このアクセス権で2つのプリンシパル名を使用すると、よりきめの細かい委譲を行えます。たとえば、TGTに転送される無条件の許可とは異なる、特定のサービス用のプロキシ・チケットなどが可能になります。GSS-APIがプロキシ・チケットを許可しない場合でも、別のAPI (JSSEなど)が将来この機能をサポートする可能性があります。


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