10 Java SASL APIプログラミングおよび配備ガイド

SASL (Simple Authentication and Security Layer)は、認証およびクライアント・アプリケーションとサーバー・アプリケーション間のセキュリティ層の確立(オプション)を行うプロトコルを指定するインターネット標準(RFC 2222)です。SASLは認証データの交換方法を定義しますが、そのデータの内容は指定しません。認証データの内容およびセマンティックスを指定する特定の認証メカニズムが適合できるフレームワークです。

SASLは、Lightweight Directory Access Protocol、バージョン3 (LDAP v3)Internet Message Access Protocol、バージョン4 (IMAP v4)などのプロトコルによって、プラガブル認証を有効にするために使用されます。認証方式をプロトコルに固定するかわりに、LDAP v3およびIMAP v4はSASLを使用して認証を実行するため、様々なSASLメカニズムによる認証が可能になります。

さまざまなセキュリティ・レベルおよび配備シナリオ用にインターネット・コミュニティによって定義された、多数の標準SASLメカニズムがあります。その範囲はセキュリティなし(匿名認証など)から高セキュリティ(Kerberos認証など)にいたるまで、様々なレベルがあります。

Java SASL API

Java SASL APIは、SASLメカニズムを使用するアプリケーション用のクラスおよびインタフェースを定義します。これは、メカニズムに依存しないものとして定義されています。APIを使用するアプリケーションを、特定のSASLメカニズムの使用に固定する必要はありません。このAPIは、クライアントとサーバーの両方のアプリケーションをサポートしています。アプリケーションは、受動的な辞書攻撃の影響を受けやすいかどうか、および匿名認証を受け入れるかどうかなど、必要なセキュリティ機能に基づいて使用するメカニズムを選択できます。

Java SASL APIでは、開発者は独自のカスタムSASLメカニズムを使用することもできます。SASLメカニズムは、Java暗号化アーキテクチャ(JCA)を使用してインストールされます(Java暗号化アーキテクチャ(JCA)リファレンス・ガイドを参照)。

SASLをいつ使用するか

SASLは、プラガブルな認証とセキュリティ層をネットワーク・アプリケーションに提供します。Java SEには、Java Secure Socket Extension (JSSE)など、同様の機能を提供するその他の機能があります(Java Secure Socket Extension (JSSE)リファレンス・ガイドおよびJava Generic Security Serviceを参照)。JSSEは、SSL、TLSおよびDTLSプロトコルのJava言語バージョンに、フレームワークと実装を提供します。Java GSSは、Generic Security Service Application Programming Interface (GSS-API)用のJava言語バインディングです。Java SEでは、このAPIの下で現在サポートされているメカニズムは、Kerberos v5のみです。

プロトコルをゼロから定義および構築する場合を除き、どのAPIを使用するかを決定する場合の最大要因は、多くの場合プロトコル定義です。JSSEおよびJava GSSと比較すると、SASLは相対的に軽量であり、一部のプロトコルの中で一般的です。一般的かつ軽量な(インフラストラクチャ・サポートの点で) SASLメカニズムがいくつか定義されているという利点もあります。一方、主要なJSSEおよびJava GSSメカニズムは相対的に重量のあるメカニズムを持ち、より精巧なインフラストラクチャ(それぞれ公開キーインフラストラクチャおよびKerberos)を必要とします。

SASL、JSSEおよびJava GSSは、しばしば併用されます。たとえば、一般的なパターンでは、アプリケーションはセキュアなチャネルを確立するためにJSSEを使用し、クライアントのユーザー名/パスワードベースの認証にはSASLを使用します。GSS-APIメカニズムの上位層となるSASLメカニズムもあります。一般的な例は、LDAPで使用されるSASL GSS-API/Kerberos v5メカニズムです。

プロトコルをゼロから定義および構築する場合を除き、どのAPIを使用するかを決定する場合の最大要因は、多くの場合プロトコル定義です。たとえば、LDAPおよびIMAPはSASLを使用するように定義されているので、これらのプロトコルに関係するソフトウェアはJava SASL APIを使用するようにしてください。Kerberosアプリケーションおよびサービスを構築する場合、使用するAPIはJava GSSです。プロトコルとしてSSL/TLSを使用するアプリケーションおよびサービスを構築する場合、使用するAPIはJSSEです。

Java SASL APIの概要

SASLはチャレンジ応答プロトコルです。サーバーはクライアントにチャレンジを発行し、クライアントはチャレンジに基づいて応答を送信します。この交換は、サーバーが充足してチャレンジを発行しなくなるまで続きます。これらのチャレンジおよび応答は、任意の長さのバイナリ・トークンです。カプセル化を行うプロトコル(LDAPやIMAPなど)は、これらのトークンのエンコードおよび交換方法を指定します。たとえば、LDAPは、SASLトークンがLDAPバインド要求および応答にどのようにカプセル化されるかを指定します。

Java SASL APIは、この相互作用と使用方法のスタイルに従ってモデル化されています。インタフェースSaslClientおよびSaslServerがあり、これらはそれぞれクライアント側およびサーバー側のメカニズムを表します。アプリケーションはチャレンジと応答を表すバイト配列によって、メカニズムと相互に作用します。サーバー側のメカニズムは、充足されるまでチャレンジの発行と応答の処理を繰り返します。一方、クライアント側のメカニズムは、サーバーが充足されるまでチャレンジの評価と応答の発行を繰り返します。メカニズムを使用しているアプリケーションが、それぞれの反復を制御します。つまり、それは、チャレンジまたは応答をプロトコル・パケットから抽出してメカニズムに渡し、メカニズムから返された応答またはチャレンジをプロトコル・パケットに入れて、ピアに送信します。

メカニズムの作成

SASLメカニズムを使用するクライアント・コードおよびサーバー・コードは、特定のメカニズムを使用するように固定はされていません。SASLを使用する多くのプロトコルでは、サーバーは、サポートするSASLメカニズムのリストを(静的または動的に)通知します。クライアントは、セキュリティ要件に基づいて、これらの1つを選択します。

Saslクラスが、SaslClientおよびSaslServerのインスタンスの作成に使用されます。次に、使用可能なSASLメカニズムのリストを使用して、アプリケーションがどのようにSASLクライアント・メカニズムを作成するかの例を示します。

    String[] mechanisms = new String[]{"DIGEST-MD5", "PLAIN"}; 
    SaslClient sc = Sasl.createSaslClient(
        mechanisms, authzid, protocol, serverName, props, callbackHandler);

プラットフォームによってサポートされるメカニズムの可用性およびパラメータで提供されるその他の構成情報に基づいて、Java SASLフレームワークは一覧されているメカニズムの1つを選択し、SaslClientのインスタンスを返します。

選択されたメカニズムの名前は、通常、アプリケーション・プロトコルによってサーバーに転送されます。メカニズム名を受信すると、サーバーは、クライアントから送信された応答を処理するために、対応するSaslServerオブジェクトを作成します。次に、サーバーがSaslServerのインスタンスを作成する方法の例を示します。

    SaslServer ss = Sasl.createSaslServer(
        mechanism, protocol, myName, props, callbackHandler);

メカニズムに入力を渡す

Java SASL APIは汎用フレームワークなので、多数の異なるタイプのメカニズムに対応できる必要があります。各メカニズムは入力によって初期化される必要があり、先に進むために入力を必要とする場合があります。このAPIは、アプリケーションがメカニズムに入力を渡すための、次の3つの手段を提供します。

  1. 共通入力パラメータ: アプリケーションはあらかじめ定義されたパラメータを使用して、SASL仕様によって定義された、メカニズムによって共通に必要とされる情報を提供します。SaslClientのメカニズムの場合、入力パラメータは承認ID、プロトコルIDおよびサーバー名です。SaslServerのメカニズムの場合、共通入力パラメータは、プロトコルIDおよび(独自の完全修飾)サーバー名です。

  2. プロパティ・パラメータ: アプリケーションは、プロパティ値(文字列以外の場合もある)へのプロパティ名のマッピングであるプロパティ・パラメータを使用して、構成情報を提供します。Java SASL APIは、Sasl.QOP (保護の品質)、Sasl.STRENGTH (暗号の強度)、Sasl.MAX_BUFFER (最大バッファ・サイズ)など、いくつかの標準プロパティを定義しています。パラメータは、特定のメカニズムに固有の非標準のプロパティを渡す場合にも使用できます。

  3. コールバック: アプリケーションは、CallbackHandlerパラメータを使用して、あらかじめ決められないか、またはメカニズム間で共通しない可能性がある入力を渡します。メカニズムが入力データを必要とする場合、アプリケーションによって渡されたコールバック・ハンドラを使用してデータを収集します。アプリケーションのエンド・ユーザーから収集する場合もあります。たとえば、メカニズムは、アプリケーションのエンド・ユーザーに名前とパスワードを指定するように要求する場合があります。

    メカニズムは、javax.security.auth.callbackパッケージで定義されたコールバックを使用できます。これらは、認証を実行するアプリケーションを構築するのに便利なジェネリック・コールバックです。メカニズムは、レルムおよび認証情報を収集するためのコールバックなどの、SASL固有のコールバック、または(標準化されていない)メカニズム固有のコールバックを必要とする場合もあります。アプリケーションは様々なメカニズムに対応できるようにする必要があります。したがって、そのコールバック・ハンドラは、メカニズムが要求する可能性があるすべてのコールバックに対応できることが必要です。これは、任意のメカニズムに対しては一般的には不可能ですが、通常は配備および使用されているメカニズムは数が限定されているため、実現可能です。

メカニズムの使用

アプリケーションがメカニズムを作成すると、アプリケーションはメカニズムを使用してSASLトークンを取得し、ピアと交換します。通常、クライアントはアプリケーション・プロトコルによって、どのメカニズムを使用するかをサーバーに指示します。一部のプロトコルでは、クライアントは初期応答を持つメカニズム用に、要求にオプションの初期応答を付加できます。この機能は、認証に必要なメッセージ交換の数を減らすために使用できます。次に、クライアントが認証にSaslClientをどのように使用するかの例を示します。

    // Get optional initial response
    byte[] response = 
        (sc.hasInitialResponse() ? sc.evaluateChallenge(new byte[]) : null);

    String mechanism = sc.getMechanismName();

    // Send selected mechanism name and optional initial response to server
    send(mechanism, response);

    // Read response
    msg = receive();
    while (!sc.isComplete() && (msg.status == CONTINUE || msg.status == SUCCESS)) {
        // Evaluate server challenge
        response = sc.evaluateChallenge(msg.contents);

        if (msg.status == SUCCESS) {
            // done; server doesn't expect any more SASL data
             if (response != null) {
                throw new IOException(
                    "Protocol error: attempting to send response after completion");
            } 
            break;
        } else {
            send(mechanism, response);
            msg = receive();
        }
    }  

クライアント・アプリケーションはメカニズム(sc)を使用して認証の各ステップを繰り返し、サーバーから取得したチャレンジを評価してサーバーに応答を返信します。クライアント・アプリケーションはメカニズムまたはアプリケーション・レベルのプロトコルが認証が完了したことを示すまで、またはメカニズムがチャレンジを評価できない場合に、このサイクルを続行します。メカニズムがチャレンジを評価できない場合、エラーを示す例外をスローし、認証を終了します。完了状態に関してメカニズムとプロトコルの間で不一致がある場合は、認証交換に障害があることを示す可能性があるため、エラーとして処理します。

次に、サーバーがSaslServerをどのように使用するかの例を示します。

    // Read request that contains mechanism name and optional initial response
    msg.receive();

    // Obtain a SaslServer to perform authentication
    SaslServer ss = Sasl.createSaslServer(msg.mechanism, 
        protocol, myName, props, callbackHandler);

    // Perform authentication steps until done
    while (!ss.isComplete()) {
        try {
            // Process response
            byte[] challenge = sc.evaluateResponse(msg.contents);

            if (ss.isComplete()) {
                send(mechanism, challenge, SUCCESS);
            } else {
                send(mechanism, challenge, CONTINUE);
                msg.receive();
            } 
        } catch (SaslException e) {
            send(ERROR);
            sc.dispose();
            break;
        }
    }

サーバー・アプリケーションはクライアントの応答をメカニズム(ss)に渡して処理することによって、認証の各ステップを繰り返します。応答が不正な場合、サーバーがエラーを報告して認証を終了できるように、メカニズムはSaslExceptionをスローしてエラーを示します。応答が正しい場合、メカニズムはクライアントに送信されるチャレンジ・データを返し、認証が完了したかどうかを示します。チャレンジ・データは「成功」を示すデータを伴うことができます。これは、たとえば、ネゴシエーションされた状態をクライアントに完結させるために使用される場合があります。

ネゴシエーション済みのセキュリティ層の使用

認証のみをサポートするSASLメカニズムだけでなく、認証後にネゴシエーション済みのセキュリティ層の使用をサポートするSASLメカニズムもあります。セキュリティ層の機能はアプリケーションがSSL/TLSなどのほかの手段を使用してピアと安全に通信する場合は、使用されない場合がよくあります。

セキュリティ層がネゴシエーション済みの場合、ピアとの後続の通信はすべてセキュリティ層を使用して発生します。セキュリティ層がネゴシエーション済かどうかを判別するには、ネゴシエーション済のSasl.QOPをメカニズムから取得します。次に、セキュリティ層がネゴシエーション済みかどうかを判別する方法の例を示します。


String qop = (String) sc.getNegotiatedProperty(Sasl.QOP);
boolean hasSecurityLayer = (qop != null && 
    (qop.equals("auth-int") || qop.equals("auth-conf")));

Sasl.QOPプロパティが整合性または機密性、あるはその両方がネゴシエーション済みであることを示している場合、セキュリティ層はネゴシエーション済みです。

ネゴシエーション済の層を使用してピアと通信するには、アプリケーションは最初にwrapメソッドを使用し、ピアに送信されるデータをエンコードして、ラップされたバッファを生成します。次に、ラップされたバッファ内のオクテットの数を表す長さフィールドとそれに続いてラップされたバッファの内容をピアに転送します。オクテットのストリームを受信するピアは長さフィールドを除くバッファをunwrapに渡し、ピアによって送信された復号化されたバイトを取得します。このプロトコルの詳細はRFC 2222で説明されています。例10-1では、クライアント・アプリケーションでセキュリティ層を使用してアプリケーション・データがどのように送受信されるかを示します。

例10-1 SASLクライアントのデータ送受信のサンプル・コード


// Send outgoing application data to peer
byte[] outgoing = ...;
byte[] netOut = sc.wrap(outgoing, 0, outgoing.length);

send(netOut.length, netOut);   // send to peer

// Receive incoming application data from peer
byte[] netIn = receive();      // read length and ensuing bytes from peer

byte[] incoming = sc.unwrap(netIn, 0, netIn.length);

SASLメカニズムをインストールおよび選択する方法

SASLメカニズムの実装は、SASLセキュリティ・プロバイダによって提供されます。各プロバイダは、1つ以上のSASLメカニズムをサポートでき、JCAを使用して登録されます。

デフォルトでは、SunSASLプロバイダがJCAプロバイダとして自動的に登録されます。このプロバイダを削除するか、JCAプロバイダとしての優先順位を変更するには、次の行を変更します。
security.provider.7=SunSASL

Javaセキュリティ・プロパティ・ファイル(java-home/conf/security/java.security)内。

SASLプロバイダを追加または削除するには、セキュリティ・プロパティ・ファイルで対応する行を追加または削除します。たとえば、SASLプロバイダを追加し、そのメカニズムが、SunSASLプロバイダによって実装されている同じメカニズムよりも優先して選択されるようにする場合は、セキュリティ・プロパティ・ファイルに、より小さい番号で行を追加します。

security.provider.7=com.example.MyProvider
security.provider.8=SunSASL

この場合、java.security.Securityクラスを使用して、プログラムで独自のプロバイダを追加することもできます。たとえば、次のサンプル・コードは、使用可能なSASLセキュリティ・プロバイダのリストにcom.example.MyProviderを登録します。

Security.addProvider(new com.example.MyProvider());

セキュリティ・プロパティ・ファイルにプロバイダを追加する方法、およびプログラムで独自のプロバイダを追加する方法の詳細は、プロバイダの実装および統合までのステップステップ8: テストの準備を参照してください。

アプリケーションが1つ以上のメカニズム名を指定してSASLメカニズムを要求すると、SASLフレームワークは、登録済みプロバイダのリストを順に検索して、そのメカニズムをサポートする登録済みのSASLプロバイダを探します。次に、プロバイダは、要求されたメカニズムがSasl内の選択ポリシー・プロパティに一致するかどうかを判別し、一致する場合は、メカニズムの実装を返します。

選択ポリシー・プロパティは特定の攻撃の受けやすさなど、メカニズムのセキュリティ面を指定します。これらは、その実装というよりもメカニズム(定義)の特性であるため、すべてのプロバイダは特定のメカニズムについて同じ結果になるはずです。たとえば、PLAINメカニズムは、どのように実装されるかにかかわらず、平文攻撃を受けやすくなります。選択ポリシー・プロパティが指定されない場合、メカニズムの選択に制限はありません。これらのプロパティを使用して、アプリケーションは、実行環境に配備される可能性があるメカニズムについて、適していないものを使用しないようにすることができます。たとえば、平文攻撃を受けやすいメカニズムの使用を許可しない場合、アプリケーションは次のサンプル・コードを使用する場合があります。

    Map<String, String> props = new HashMap<>();
    props.put(Sasl.POLICY_NOPLAINTEXT, "true");
    SaslClient sc = Sasl.createSaslClient(
        mechanisms, authzid, protocol, serverName, props, callbackHandler);

SunSASLプロバイダ

SunSASLプロバイダは、次のクライアント・メカニズムおよびサーバー・メカニズムをサポートします。

  • クライアント・メカニズム
    • PLAIN (RFC 2595)。このメカニズムは、クリアテキスト・ユーザー名/パスワード認証をサポートしています。
    • CRAM-MD5 (RFC 2195)。このメカニズムは、ハッシュ化されたユーザー名/パスワード認証方式をサポートしています。
    • DIGEST-MD5 (RFC 2831)。HTTP Digest AuthenticationをSASLメカニズムとして使用する方法を定義します。
    • EXTERNAL (RFC 2222)。このメカニズムは、TLSやIPsecなどの外部チャネルから認証情報を取得します。
    • NTLM。このメカニズムは、NTLM認証をサポートしています。
  • サーバー・メカニズム
    • CRAM-MD5
    • DIGEST-MD5
    • NTLM

SunSASLプロバイダのクライアント・メカニズム

SunSASLプロバイダでは、LDAP、IMAPおよびSMTPなどの一般的なプロトコルで使用される複数のSASLクライアント・メカニズムがサポートされています。

次の表は、クライアント・メカニズムとそれらに必要な入力の概要です。

表10-1 SunSASLプロバイダのクライアント・メカニズム

クライアント・メカニズム名 パラメータ/入力 コールバック 構成プロパティ 選択ポリシー
CRAM-MD5 承認ID (デフォルトのユーザー名として)

PasswordCallback

NameCallback

なし

Sasl.POLICY_NOANONYMOUS

Sasl.POLICY_NOPLAINTEXT

DIGEST-MD5

承認ID

プロトコルID

サーバー名

NameCallback

PasswordCallback

RealmCallback

RealmChoiceCallback

Sasl.QOP

Sasl.STRENGTH

Sasl.MAX_BUFFER

Sasl.SERVER_AUTH

javax.security.sasl.sendmaxbuffer

com.sun.security.sasl.digest.cipher

Sasl.POLICY_NOANONYMOUS

Sasl.POLICY_NOPLAINTEXT

EXTERNAL

承認ID

外部チャネル

なし なし 

Sasl.POLICY_NOPLAINTEXT

Sasl.POLICY_NOACTIVE

Sasl.POLICY_NODICTIONARY

NTLM

authzId (デフォルトのユーザー名として)

サーバー名(デフォルト・ドメインとして)

RealmCallback

NameCallback

PasswordCallback

Sasl.QOP

com.sun.security.sasl.ntlm.version

com.sun.security.sasl.ntlm.random

com.sun.security.sasl.ntlm.hostname

Sasl.POLICY_NOANONYMOUS

Sasl.POLICY_NOPLAINTEXT

PLAIN 承認ID

NameCallback

PasswordCallback

なし

Sasl.POLICY_NOANONYMOUS

SunSASLプロバイダのこれらのメカニズムを使用するアプリケーションは、必要なパラメータ、コールバック、およびプロパティを提供する必要があります。プロパティには適切なデフォルト値が設定されているため、アプリケーションがデフォルト値をオーバーライドする場合にのみ設定する必要があります。ほとんどのパラメータ、コールバック、およびプロパティはAPIドキュメントで説明されています。次のセクションでは、メカニズム固有の動作、およびAPIドキュメントで説明されていないパラメータについて説明します。

Cram-MD5

Cram-MD5クライアント・メカニズムは、承認IDパラメータが指定された場合、それをNameCallbackのデフォルト・ユーザー名として使用して、アプリケーション/エンドユーザーに認証IDを求めます。それ以外の場合、承認IDはCram-MD5メカニズムによって使用されません。認証IDのみがサーバーと交換されます。

Digest-MD5

Digest-MD5メカニズムは、ダイジェスト認証およびオプションでセキュリティ層を確立する場合に使用されます。セキュリティ層とともに使用するTriple DES、DES、およびRC4 (128、56、および40ビット)の暗号を指定します。Digest-MD5メカニズムは、プラットフォームで使用可能な暗号のみをサポートできます。たとえば、プラットフォームがRC4暗号をサポートしない場合、Digest-MD5メカニズムはその暗号を使用しません。

Sasl.STRENGTHプロパティは、highmediumおよびlow設定をサポートしており、デフォルトはhigh,medium,lowです。暗号は、次のように強度設定にマッピングされています。

表10-2 暗号強度

強さ 暗号 暗号ID
high トリプルDES

RC4 128ビット

3des rc4
medium DES

RC4 56ビット

des rc4-56
low RC4 40ビット rc4-40

特定の強度に複数の選択肢がある場合、選択される暗号は、基盤となるプラットフォームでの暗号の可用性によって決まります。使用する暗号を明示的に指定するには、com.sun.security.sasl.digest.cipherプロパティを、対応する暗号IDに設定します。このプロパティ設定は、Sasl.STRENGTHおよび基盤となるプラットフォームで利用可能な暗号と互換性を持たせてください。たとえば、lowに設定されているSasl.STRENGTH3desに設定されているcom.sun.security.sasl.digest.cipherには、互換性がありません。com.sun.security.sasl.digest.cipherプロパティには、デフォルトはありません。

javax.security.sasl.sendmaxbufferプロパティは、最大送信バッファ・サイズ(の文字列表現)をバイト単位で指定します。デフォルトは、65536です。実際の最大バイト数は、この数の最小値およびピアの最大受信バッファ・サイズになります。

NTLM

ノート:

この項は、NTLMクライアント・メカニズムおよびNTLMサーバー・メカニズムの両方に適用されます。

NT LAN Manager (NTLM)はMicrosoftが提供するセキュリティ・プロトコルで、Microsoftの各種サービス(IIS WebサーバーやExchangeメール・サーバーなど)へのアクセスに使用されます。SASLメカニズムとして、Microsoft Exchange Serverへのアクセスに使用できます。また、NTLMスキームでのHTTP認証にも役立ちます。

NTLMメカニズムは、NTLM認証に使用されます。セキュリティ層は提供しません。これは、javax.security.sasl.qop環境プロパティをauthにのみ設定できることを意味します。

LMCompatibilityLevelレジストリ値がサーバー上で高い値に設定されている場合、一部の低い値のリクエストはサポートされません。ただし、サーバーからクライアントに、より高いバージョンを使用するように通知するプロトコルはないため、ユーザーはクライアント側で適切なバージョンを手動で選択する必要があります。

デバッグを有効にするには、システム・プロパティntlm.debugを任意の値に設定します

メカニズムの作成時またはコールバックを介して次の情報を指定します。

表10-3 NTLMで必要な情報

情報 必須またはオプション 説明
名前 String 必須 デフォルト値としてauthzid入力引数を使用してNameCallbackによって提供されます
パスワード char[] 必須 PasswordCallbackによって提供されます

パスワードにASCII以外の文字が含まれている場合、元のLMバージョンが失敗する可能性があります。この場合、バージョンとしてLMを選択しないでください。

ドメイン String オプション

デフォルト値としてserverName入力引数を使用してRealmCallbackによって提供されます。

クライアント側で指定されたドメインは、タイプ1のメッセージを作成するために使用されます。ネゴシエーション済のプロパティcom.sun.security.sasl.ntlm.domainはサーバーのタイプ2メッセージによって決定されます。

NTLMバージョン String オプション

使用する特定のバージョンを指定します。com.sun.security.sasl.ntlm.versionプロパティによって提供されます。次の値のうち1つを取ることができます。

  • LM/NTLM: 元のNTLM v1
  • LM: 元のNTLM v1、LMのみ
  • NTLM: 元のNTLM v1、NTLMのみ
  • NTLM2: クライアント・チャレンジを使用するNTLM v1
  • LMv2/NTLMv2: NTLM v2
  • LMv2: NTLM v2、LMのみ
  • NTLMv2: NTLM v2、NTLMのみ

指定しない場合、システム・プロパティntlm.versionが使用されます。まだが提供されない場合、値LMv2/NTLMv2が使用され、サーバー側では、すべての値が受け入れられます。

ノート: これらのタイプは、クライアント側でのみ異なります。サーバー側では、LM (またはLMv2)やNTLM (またはNTLMv2)のいずれか1つのみが検証されると、認証が成功するため、最初の3種類は実質的に同じです。これは、最後の3種類の場合も同様です。

ホスト名 String オプション サーバーに送信されるcom.sun.security.sasl.ntlm.hostnameプロパティによって提供されます。指定しない場合、システムは自動的にホスト名を導出します。このプロパティは、クライアント側でのみ使用されます。
ランダム・ソース java.util.Random オプション nonceバイトを導出するためのランダム・ソースとして使用されます。com.sun.security.sasl.ntlm.randomプロパティを介して提供されます。提供されない場合、内部java.util.Randomオブジェクトが使用されます。

認証後、クライアントは、サーバーによって提供されるcom.sun.security.sasl.html.domainという名前のネゴシエーション済のプロパティを受け取り、サーバーは、com.sun.security.sasl.ntlm.hostnameという名前(クライアントがこのサーバーへのアクセスに使用するホスト名)のネゴシエーション済のプロパティを受け取ります。

SunSASLプロバイダのサーバー・メカニズム

SunSASLプロバイダでは、LDAP、IMAPおよびSMTPなどの一般的なプロトコルで使用される複数のSASLサーバー・メカニズムがサポートされています。

次の表は、サーバー・メカニズムとそれらに必要な入力の概要です。

表10-4 サーバー・メカニズム

サーバー・メカニズム名 パラメータ/入力 コールバック 構成プロパティ 選択ポリシー
CRAM-MD5 サーバー名

AuthorizeCallback

NameCallback

PasswordCallback

なし

Sasl.POLICY_NOANONYMOUS

Sasl.POLICY_NOPLAINTEXT

DIGEST-MD5 プロトコルID

サーバー名

AuthorizeCallback

NameCallback

PasswordCallback

RealmCallback

Sasl.QOP

Sasl.STRENGTH

Sasl.MAX_BUFFER

javax.security.sasl.sendmaxbuffer

com.sun.security.sasl.digest.realm

com.sun.security.sasl.digest.utf8

Sasl.POLICY_NOANONYMOUS

Sasl.POLICY_NOPLAINTEXT

NTLM serverName (ドメインとして、プロパティでオーバーライド可能)

RealmCallback、リクエスト・ユーザーのドメインを提供

NameCallback、リクエスト・ユーザーの名前を提供

PasswordCallback

Sasl.QOP

com.sun.security.sasl.ntlm.random

com.sun.security.sasl.ntlm.version

com.sun.security.sasl.ntlm.domain

Sasl.POLICY_NOANONYMOUS

Sasl.POLICY_NOPLAINTEXT

SunSASLプロバイダのこれらのメカニズムを使用するアプリケーションは、必要なパラメータ、コールバック、およびプロパティを提供する必要があります。プロパティには適切なデフォルト値が設定されているため、アプリケーションがデフォルト値をオーバーライドする場合にのみ設定する必要があります。

サーバー・メカニズムのすべてのユーザーには、AuthorizeCallbackを処理するコールバック・ハンドラが必要です。これは、要求された承認IDに代わって認証済みのユーザーが操作できるかどうかを判別するため、および承認されたユーザーの正規化された名前を取得するために(正規化が適用可能な場合)、メカニズムによって使用されます。

ほとんどのパラメータ、コールバック、およびプロパティはAPIドキュメントで説明されています。次のセクションでは、メカニズム固有の動作、およびAPIドキュメントで説明されていないパラメータについて説明します。

Cram-MD5

Cram-MD5サーバー・メカニズムはNameCallbackおよびPasswordCallbackを使用して、SASLクライアントの応答の検証に必要なパスワードを取得します。コールバック・ハンドラは、パスワードを取得するためのキーとしてNameCallback.getDefaultName()を使用します。

Digest-MD5

Digest-MD5サーバー・メカニズムはRealmCallbackNameCallbackおよびPasswordCallbackを使用して、SASLクライアントの応答の検証に必要なパスワードを取得します。コールバック・ハンドラは、パスワードを取得するためのキーとしてRealmCallback.getDefaultText()およびNameCallback.getDefaultName()を使用します。

javax.security.sasl.sendmaxbufferプロパティは、最大送信バッファ・サイズ(の文字列表現)をバイト単位で指定します。デフォルトは、65536です。実際の最大バイト数は、この数の最小値およびピアの最大受信バッファ・サイズになります。

com.sun.security.sasl.digest.realmプロパティは、サーバーがサポートするレルムの名前を空白で区切ったリストを指定するために使用されます。このリストは、チャレンジの一部としてクライアントに送信されます。このプロパティが設定されていない場合、デフォルトのレルムはサーバーの名前です(パラメータとして指定)。

com.sun.security.sasl.digest.utf8プロパティは、使用する文字エンコーディングを指定するために使用されます。値trueはUTF-8エンコーディングを使用することを意味します。値falseはISO Latin 1 (ISO-8859-1)を使用することを意味します。デフォルト値はtrueです。

JdkSASLプロバイダ

JdkSASLプロバイダでは、次のクライアント・メカニズムおよびサーバー・メカニズムがサポートされています。

  • クライアント・メカニズム
    • GSSAPI (RFC 2222)。このメカニズムは、認証情報を取得するためにGSSAPIを使用します。Kerberos v5認証をサポートしています。
  • サーバー・メカニズム
    • GSSAPI (Kerberos v5)

JdkSASLプロバイダのクライアント・メカニズム

JdkSASLプロバイダでは、LDAP、IMAPおよびSMTPなどの一般的なプロトコルで使用されるGSSAPIクライアント・メカニズムがサポートされています。

次の表は、GSSAPIクライアント・メカニズムとそれらに必要な入力の概要です。

表10-5 JdkSASLプロバイダのクライアント・メカニズム

クライアント・メカニズム名 パラメータ/入力 コールバック 構成プロパティ 選択ポリシー
GSSAPI JAAS Subject

承認ID

プロトコルID

サーバー名

なし

Sasl.QOP

Sasl.MAX_BUFFER

Sasl.SERVER_AUTH

javax.security.sasl.sendmaxbuffer

com.sun.security.jgss.inquiretype.type_name

Sasl.POLICY_NOACTIVE

Sasl.POLICY_NOANONYMOUS

Sasl.POLICY_NOPLAINTEXT

JdkSASLプロバイダのGSSAPIメカニズムを使用するアプリケーションは、必要なパラメータ、コールバックおよびプロパティを提供する必要があります。プロパティには適切なデフォルト値が設定されているため、アプリケーションがデフォルト値をオーバーライドする場合にのみ設定する必要があります。ほとんどのパラメータ、コールバック、およびプロパティはAPIドキュメントで説明されています。次の項では、GSSAPIのその他の動作、およびAPIドキュメントで説明されていないパラメータについて説明します。

GSSAPI

ノート:

GSSAPIサーバー・メカニズムには、Kerberos資格およびjavax.security.sasl.sendmaxbufferプロパティに関して、GSSAPIクライアント・メカニズムと同じ要件があります。

GSSAPIメカニズムは、Kerberos v5認証およびオプションでセキュリティ層の確立に使用されます。メカニズムは呼出し側スレッドのSubjectがクライアントのKerberos資格を含むこと、またはKerberosに暗黙的にログインすることによって資格が取得されることを想定しています。クライアントのKerberos資格を取得するには、Java Authentication and Authorization Service (JAAS)を使用し、Kerberosログイン・モジュールを使用してログインします。詳細および例は、「JAASおよびJava GSS-APIチュートリアルの紹介」を参照してください。JAAS認証を使用してKerberos資格を取得した後で、SASL GSSAPIメカニズムを使用するコードをdoAsまたはdoAsPrivileged内に配置します。

LoginContext lc = new LoginContext("JaasSample", new TextCallbackHandler());
lc.login();
lc.getSubject().doAs(new SaslAction());

class SaslAction implements java.security.PrivilegedAction<Void> {
   public Void run() {
       // ...
       String[] mechanisms = new String[]{"GSSAPI"};
       SaslClient sc = Sasl.createSaslClient(
           mechanisms, authzid, protocol, serverName, props, callbackHandler);
       // ...
   }
}

JAASプログラミングを明示的に行わずにKerberos資格を取得するには、「Java GSS-APIを使用した、JAASプログラミングなしのセキュアなメッセージ交換」を参照してください。この方法を使用する場合は、コードをdoAsまたはdoAsPrivileged内にラップする必要はありません

javax.security.sasl.sendmaxbufferプロパティは、最大送信バッファ・サイズ(の文字列表現)をバイト単位で指定します。デフォルトは、65536です。実際の最大バイト数は、この数の最小値およびピアの最大受信バッファ・サイズになります。

com.sun.security.jgss.inquiretype.type_nameネゴシエーション済プロパティには、ExtendedGSSContext.inquireSecContext(InquireType)メソッドにより戻された値が含まれます。ここで、type_nameInquireType列挙パラメータの文字列形式です(小文字)。

JdkSASLプロバイダのサーバー・メカニズム

JdkSASLプロバイダでは、LDAP、IMAPおよびSMTPなどの一般的なプロトコルで使用されるGSSAPIメカニズムがサポートされています。

次の表は、GSSAPIサーバー・メカニズムとそれらに必要な入力の概要です。

表10-6 サーバー・メカニズム

サーバー・メカニズム名 パラメータ/入力 コールバック 構成プロパティ 選択ポリシー
GSSAPI

サブジェクト

プロトコルID

サーバー名

AuthorizeCallback

Sasl.QOP

Sasl.MAX_BUFFER

javax.security.sasl.sendmaxbuffer

Sasl.POLICY_NOACTIVE

Sasl.POLICY_NOANONYMOUS

Sasl.POLICY_NOPLAINTEXT

JdkSASLプロバイダのGSSAPIメカニズムを使用するアプリケーションは、必要なパラメータ、コールバックおよびプロパティを提供する必要があります。プロパティには適切なデフォルト値が設定されているため、アプリケーションがデフォルト値をオーバーライドする場合にのみ設定する必要があります。

サーバー・メカニズムのすべてのユーザーには、AuthorizeCallbackを処理するコールバック・ハンドラが必要です。これは、要求された承認IDに代わって認証済のユーザーが操作できるかどうかを判別するため、および承認されたユーザーの正規化された名前を取得するために(正規化が適用可能な場合)、メカニズムによって使用されます。

ほとんどのパラメータ、コールバック、およびプロパティはAPIドキュメントで説明されています。

デバッグおよびモニタリング

SunSASLプロバイダとJdkSASLプロバイダは、ロギングAPIを使用して、実装のログを出力します。この出力は、ロギング構成ファイルおよびプログラム上のAPI (java.util.logging)を使用して制御できます。SunSASLプロバイダによって使用されるロガー名は、javax.security.saslです。次に、SunSASLプロバイダのFINESTロギング・レベルを有効にするサンプル・ロギング構成ファイルを示します。

javax.security.sasl.level=FINEST
handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level=FINEST

表10-7に、メカニズムおよびそれらが生成するロギング出力を示します:

表10-7 ロギング出力

メカニズム ロギング・レベル ログ記録される情報
CRAM-MD5 FINE 構成プロパティ。チャレンジおよび応答メッセージ
DIGEST-MD5 INFO エンコーディングの問題のために破棄されたメッセージ(不一致のMAC、不正なパディングなど)
DIGEST-MD5 FINE 構成プロパティ。チャレンジおよび応答メッセージ
DIGEST-MD5 FINER チャレンジおよび応答メッセージに関するより詳細な情報
DIGEST-MD5 FINEST セキュリティ層で交換されるバッファ
GSSAPI FINE 構成プロパティ。チャレンジおよび応答メッセージ
GSSAPI FINER チャレンジおよび応答メッセージに関するより詳細な情報
GSSAPI FINEST セキュリティ層で交換されるバッファ

SASLセキュリティ・プロバイダの実装

SASLセキュリティ・プロバイダの実装には、次の3つの基本的なステップがあります。
  1. SaslClientまたはSaslServerインタフェースを実装するクラスを記述します。

    これには、SASLメカニズムの実装を提供することが含まれます。クライアント・メカニズムを実装するには、SaslClientインタフェースで宣言されたメソッドを実装する必要があります。同様に、サーバー・メカニズムの場合は、SaslServerインタフェースで宣言されたメソッドを実装する必要があります。この説明では、クラスcom.example.SampleMechClientによって実装されるクライアント・メカニズム「SAMPLE-MECH」の実装を開発するものとします。メカニズムが必要とする入力、およびそれらを実装が収集する方法を決定する必要があります。たとえば、メカニズムがユーザー名/パスワードベースの場合、実装ではその情報をコールバック・ハンドラ・パラメータ経由で収集する必要性が高くなります。

  2. クラスのインスタンスを作成するファクトリ・クラス(SaslClientFactoryまたはSaslServerFactoryを実装)を記述します。

    これには、com.example.SampleMechClientのインスタンスを作成するファクトリ・クラスの提供が含まれます。ファクトリはSasl.POLICY_*プロパティによって記述されるように、サポートするメカニズムの特性を決定する必要があります。そうすることにより、互換性のあるポリシー・プロパティを使用してAPIユーザーが要求したときに、メカニズムのインスタンスを返すことができます。ファクトリは、また、メカニズムを作成する前にパラメータの妥当性をチェックする場合もあります。この説明では、ファクトリ・クラスの名前をcom.example.MySampleClientFactoryとします。サンプル・ファクトリは1つのメカニズムのみを処理しますが、1つのファクトリは任意の数のメカニズムを処理できます。

  3. ファクトリを登録するJCAプロバイダを記述します。

    これには、JCAプロバイダの作成が含まれます。JCAプロバイダを作成するステップは、プロバイダの実装および統合までのステップに詳細に説明されています。SASLクライアント・ファクトリは、SaslClientFactory.mechNameという形式のプロパティ名を使用して登録されますが、SASLサーバー・ファクトリは、SaslServerFactory.mechNameという形式のプロパティ名を使用して登録されます。

    mechNameは、SASLメカニズムの名前です。これは、SaslClient.getMechanismName()およびSaslServer.getMechanismName()によって返された名前です。この例で、プロバイダが「SAMPLE-MECH」メカニズムを登録する方法を次に示します。

        put("SaslClientFactory.SAMPLE-MECH", "com.example.MySampleClientFactory");
    

    1つのSASLプロバイダが、多数のメカニズムを処理する場合があります。そのため、関連するファクトリを登録するputの呼出しが多数ある場合があります。完了したSASLプロバイダは、SASLメカニズムをインストールおよび選択する方法で説明されている手順を使用して、アプリケーションで使用可能にすることができます。