前のチュートリアル チュートリアルの紹介および目次 次のチュートリアル

JAAS Login ユーティリティーおよび Java GSS-API を使用したセキュアなメッセージ交換



このチュートリアルでは、2 つのサンプルアプリケーションを使って、Java GSS-API の使用方法を説明します。この API は、アプリケーション間のセキュアなメッセージ交換を可能にします。このチュートリアルで使用するサンプルのクライアントアプリケーションおよびサーバーアプリケーションは次の 2 つです。


注: このチュートリアルでは、「Java GSS-API を使用した、JAAS プログラミングなしのセキュアなメッセージ交換」チュートリアルと同じクライアントおよびサーバーのアプリケーションを使用します。そのチュートリアルでは、JAAS (Java 認証・承認サービス) プログラミングは不要です。その代わり、基盤となるメカニズムによってクレデンシャルの取得方法が決定されます。
このチュートリアルでは、ポリシーファイルとより複雑なログイン構成ファイルを使用します。プログラムの実行にはセキュリティーマネージャーを使用するので、セキュリティー保護の必要な操作を行うには、必要なアクセス権が明示的に付与されていなければなりません。このチュートリアルは、JAAS 承認によりユーザー中心のアクセス制御を追加する方法を示します。このため制御は、実行中のコードの種類と、コードを実行するユーザーに基づいて適用されます。

内容:




作業を開始する前に: 関連チュートリアルの紹介

この Java GSS-API チュートリアルは、JAAS 認証の最初のステップです。前のチュートリアルでは、JAAS を使用してユーザーの認証や承認を行う方法や、JAAS に必要なポリシーファイルとログイン構成ファイル (使用する基盤となる認証技術を指定する) の内容およびサンプルを示しました。JAAS 入門用のチュートリアルである「JAAS 認証」および「JAAS 承認」では、アプリケーションは、JAAS メソッドを直接呼び出しました。「JAAS Login ユーティリティーの使用」チュートリアルでは、アプリケーションをこの操作から開放するユーティリティープログラムの使用方法を示しました。このチュートリアルのクライアントおよびサーバーアプリケーションでも同じユーティリティープログラムを使用しますので、あらかじめ Login ユーティリティーのチュートリアルの内容を確認してからこのチュートリアルに進むことをお勧めします。

この一連のチュートリアルでは、Kerberos を認証およびアプリケーションのセキュアな通信をサポートする基幹技術として使用しています。「Kerberos 要件」を参照してください。

クライアントおよびサーバーアプリケーションの概要

このチュートリアルで使用するアプリケーションの名前は、SampleClient および SampleServer です。

各アプリケーションは、このチュートリアルで提供する Login ユーティリティーを実行して呼び出します。引数には、アプリケーションの名前 (SampleClient または SampleServer) とアプリケーションが必要とする引数を指定します。Login ユーティリティーは、JAAS LoginContext を使って、Kerberos を使用するユーザーを認証します。最後に、Login ユーティリティーはアプリケーションクラス (ここでは SampleClient または SampleServer) の main メソッドを呼び出して、アプリケーションに引数を渡します。

次に、SampleClient および SampleServer アプリケーションの実行方法のサマリーを示します。

  1. 引数に「SampleServer」、続いて SampleServer プログラム用の引数を指定して Login ユーティリティーを実行することにより、SampleServer アプリケーションを実行します。Login ユーティリティーにより、SampleServer を実行するプリンシパルのパスワード入力が求められます。(「Kerberos ユーザー名およびサービスプリンシパル名」を参照)。認証完了後に、SampleServer が実行されます。
    1. 引数に注目し、クライアントからの接続を待機するポート番号を確認します。
    2. 指定されたポート上でクライアント接続を待機する ServerSocket を作成します。
    3. 接続を待機します。
  2. 引数に「SampleClient」、続いて SampleClient プログラム用の引数を指定して Login ユーティリティーを実行することにより、SampleClient アプリケーションを実行します (通常別のマシンを使用)。Login ユーティリティーにより、Kerberos 名およびパスワードの入力が求められます。認証完了後に、SampleClient が実行されます。次のとおりです。
    1. 引数に注目し、(1) SampleServer を表す Kerberos プリンシパルの名前 (「Kerberos ユーザー名およびサービスプリンシパル名」を参照)、(2) SampleServer を実行中のホスト (マシン) の名前、(3) SampleServer がクライアント接続を待機するポート番号を確認します。
    2. 引数として渡されたホストおよびポートを使用して、SampleServer へのソケット接続を試みます。
  3. ソケット接続が SampleServer により受け入れられます。両方のアプリケーションが、ソケット入力および出力ストリームからの DataInputStream および DataOutputStream を初期化して、将来のデータ交換に使用します。
  4. SampleClient および SampleServer は、それぞれ GSSContext をインスタンス化し、以後のセキュアなデータ交換を可能にする共有コンテキストを確立します。
  5. これで、SampleClient および SampleServer は、メッセージをセキュアに交換できます。
  6. SampleClient および SampleServer は、メッセージ交換の完了後に、クリーンアップ操作を実行します。

注: このチュートリアルで使用するコードについては、「Java GSS-API を使用した、JAAS プログラミングなしのセキュアなメッセージ交換」チュートリアルの「SampleClient および SampleServer コード」のセクションで詳しく解説します。

Kerberos ユーザー名およびサービスプリンシパル名

このチュートリアルでは、ベースとなる認証およびセキュアな通信技術として Kerberos V5 が使用されているため、ユーザーまたはサービスが要求される場合、常に Kerberos スタイルのプリンシパル名が使用されます。

たとえば、SampleClient を実行する場合、ユーザー名の指定が求められます。Kerberos スタイルのユーザー名は、Kerberos 認証用だけに割り当てられたユーザー名です。このユーザー名は、ベースユーザー名 (例、「mjones」)、「@」、およびレルムの順序で構成されます (例、「mjones@KRBNT-OPERATIONS.EXAMPLE.COM」)。

通常、SampleServer などのサーバープログラムは、「サービス」を提供し、特定の「サービスプリンシパル」に代わって実行されるプログラムと見なされます。SampleServer のサービスプリンシパル名が必要とされるのは、次の場合です。

このドキュメントおよび付属のログイン構成ファイルやポリシーファイルを通じて、

service_principal@your_realm
という形式で記述された部分は、自分の環境で使用する実際の名前で置き換えてください。サービスプリンシパル名として、任意の Kerberos プリンシパルを実際に使用できます。このため、このチュートリアルを実行してみる場合、クライアントユーザー名とサービスプリンシパル名の両方に自分のユーザー名を使用できます。

通常、本番稼動環境では、システム管理者は、サーバーを特定のプリンシパルのみで実行し、特定の名前を割り当てて使用します。たいてい、割り当てる Kerberos 形式のサービスプリンシパル名は、次のようになります。

service_name/machine_name@realm; 

たとえば、「KRBNT-OPERATIONS.EXAMPLE.COM」というレルム内の「raven」という名前のマシンで nfs サービスを実行する場合、サービスプリンシパル名は次のようになります

nfs/raven@KRBNT-OPERATIONS.EXAMPLE.COM

ただし、このようなマルチコンポーネント名は必須ではありません。ユーザープリンシパル名のような、シングルコンポーネント名も使用できます。たとえば、インストールによって、レルム内のすべての ftp サーバーで同じ ftp サービスプリンシパル ftp@realm を使用する場合と、ftp サーバーごとに異なる ftp プリンシパルを使用する (たとえば、マシン host1host2 の ftp プリンシパルがそれぞれ ftp/host1@realmftp/host2@realm となる) 場合があります。

プリンシパル名にレルムを指定する必要がある場合

ユーザーまたはサービスプリンシパル名のレルムがデフォルトレルムの場合は (「Kerberos 要件」を参照)、Kerberos にログインする際、ユーザー名を求めるプロンプトが表示された時点で、必ずしもレルムを指定する必要はありません。このため、たとえばユーザー名が「mjones@KRBNT-OPERATIONS.EXAMPLE.COM」で、SampleClient を実行する場合、ユーザー名が要求されたら、レルムを省略して「mjones」とだけ入力できます。名前は Kerberos プリンシパル名のコンテキストで解釈され、必要に応じてデフォルトのレルムが付けられます。

GSSManager の createName メソッドにより、プリンシパル名が GSSName に変換される場合にも、レルムの指定を省略できます。たとえば、SampleClient の実行時に、引数の 1 つにサーバーサービスプリンシパル名を指定します。この場合、SampleClient が名前を createName メソッドなどに渡し、このメソッドが必要に応じてデフォルトのレルムを追加するため、名前を指定する際にレルムを省略できます。

プリンシパル名をログイン構成ファイルおよびポリシーファイルで使用する場合は、常にレルムを含めて名前を指定することをお勧めします。理由は、これらのファイルのパーサーの動作が実装に依存しないため、プリンシパル名の使用前にデフォルトのレルムが追加される場合と、追加されない場合があるためです。名前にレルムが指定されていない場合、以降のアクションは失敗します。

ログイン構成ファイル

JAAS を使用する場合は常に、使用する認証テクノロジをログイン構成ファイルに指定する必要があります。ログイン構成ファイルの詳細は、「JAAS ログイン構成ファイル」を参照してください。ログイン構成ファイルに、クライアント側が使用するエントリとサーバー側が使用するエントリの 2 つが含まれる場合、SampleClientSampleServer の両方で同じログイン構成ファイルを使用できます。

このチュートリアルで使用するログイン構成ファイル csLogin.conf を、次に示します。

SampleClient {
  com.sun.security.auth.module.Krb5LoginModule required;
};

SampleServer {
  com.sun.security.auth.module.Krb5LoginModule required storeKey=true 
    principal="service_principal@your_realm";
};

各エントリの名前は、2 つのトップレベルアプリケーション SampleClient および SampleServer のクラス名にそれぞれ一致します。これは、アプリケーション用の JAAS 操作を実行する Login ユーティリティーに渡される名前でもあることに留意してください。Login ユーティリティーがログイン構成ファイル内で検索するエントリ名は、渡されたエントリ名と同じになります。

両方のエントリでは、ユーザー認証の成功のため、Sun の Kerberos V5 ログインモジュールを使用する必要があることが指定されています。Krb5LoginModule が成功するのは、指定されたエンティティーでの Kerberos KDC へのログインが成功した場合だけです。SampleClient の場合、ユーザーは名前とパスワードの入力を求められます。SampleServer の場合、ログイン構成ファイルに名前 (指定されたプリンシパル、詳細は後述) が指定されているため、SampleServer を実行するユーザーにはその名前で指定されたエンティティーのパスワードの入力だけが求められます。認証が成功するには、正確なパスワードを指定する必要があります。

SampleServer のエントリ storeKey=true は、ログイン時に指定されたパスワードから秘密鍵を計算すること、およびログインにより作成されたサブジェクトの private クレデンシャルに秘密鍵を格納することを意味します。この鍵は、SampleClientSampleServer との間でセキュリティーコンテキストを確立する際、相互認証に利用されます。

Krb5LoginModule には principal オプションを指定できます。このオプションを使用すると、指定されたプリンシパル (エンティティー/ユーザー) だけが決められたプログラムにログインするよう指定できます。ここでは、SampleClient エントリにプリンシパルが指定されていない (必要に応じて指定可能) ため、ユーザーはユーザー名およびパスワードの入力を求められます。有効なユーザー名およびパスワードを保持するユーザーならだれでも SampleClient を実行できます。一方、SampleServer には特定のプリンシパルが指定されています。通常、システム管理者は、サーバーを特定のプリンシパルとして実行することを好みます。この場合、SampleServer を実行するユーザーは、プリンシパルのパスワードの入力を求められます。認証が成功するには、適正なパスワードを指定する必要があります。

「service_principal@your_realm」を、SampleServer を表すサービスプリンシパルの名前で置き換える必要があります。(「Kerberos ユーザー名およびサービスプリンシパル名」を参照)。

Krb5LoginModule に引き渡し可能なすべてのオプションの詳細は、Krb5LoginModule ドキュメントを参照してください。

ポリシーファイル

SampleClient の実行時に使用されるポリシーファイルは client.policySampleServer の実行時に使用されるポリシーファイルは server.policy です。各ファイルの内容を、以降で説明します。

クライアントのポリシーファイル

Login ユーティリティークラスに必要なアクセス権

Login.java (Login および MyAction) 内のクラスでは、多数のアクセス権が必要です。Login の使用に関する前のチュートリアルで推奨したように、Login.class および MyAction.class ファイルを含む JAR ファイル Login.jar を作成し、ポリシーファイル client.policyLogin.jar AllPermission を付与します。

grant codebase "file:./Login.jar" {
   permission java.security.AllPermission;
};

SampleClient に必要なアクセス権

SampleClient コードは、アクセス権の必要な 2 つのタイプの操作を実行します。次のとおりです。

ソケット接続を開くのに必要なアクセス権を、次に示します。

permission java.net.SocketPermission "*", "connect";

"*" は、SampleServer を実行するマシンのホスト名または IP アドレスで置き換えることができます。

セキュリティーコンテキストの確立を開始するために必要なアクセス権は、基盤となるメカニズムによって異なります。このチュートリアルでは、基盤となるメカニズムとして Kerberos を使用します。このため、アクセス権 javax.security.auth.kerberos.ServicePermission が 2 つ必要になります。ServicePermission には、サービスプリンシパル名およびアクション (またはアクションのリスト) が必要です。セキュリティーコンテキストの確立を開始するには、アクション「initiate」を指定して 2 つの ServicePermission を使用する必要があります。ServicePermission の名前により、次が指定されます。

SampleClient を実行する、認証済みの特定ユーザーにアクセス権を付与します。このために、SampleClient のコード位置 (SampleClient.jar 内)、およびユーザー名とユーザー (SampleClient を実行するユーザー) のレルムを示すプリンシパル指示部の両方を指定します。プリンシパル指示部を含むポリシーファイル grant 文の詳細は、このシリーズの 2 番目のチュートリアルの「プリンシパルベースのポリシーファイル文の作成方法」を参照してください。

grant 文の基本的な書式を、次に示します。

  grant CodeBase "file:./SampleClient.jar", 
    Principal javax.security.auth.kerberos.KerberosPrincipal 
        "your_user_name@your_realm" {

    permission java.net.SocketPermission "*", "connect";

    permission javax.security.auth.kerberos.ServicePermission
        "krbtgt/your_realm@your_realm", 
        "initiate";

    permission javax.security.auth.kerberos.ServicePermission
        "service_principal@your_realm", 
        "initiate";
};

your_user_name@your_realm」には、使用する Kerberos ユーザー名、「@」、およびレルムを指定する必要があります。たとえば、ユーザー名が「mjones」、レルムが「KRBNT-OPERATIONS.EXAMPLE.COM」の場合、"mjones@KRBNT-OPERATIONS.EXAMPLE.COM" (引用符も付ける) を指定します。

また、「service_principal@your_realm」を、「krbtgt/your_realm@your_realm」内のレルムおよびサーバーを表すサービスプリンシパルの名前で置き換える必要もあります。前者が「krbtgt/KRBNT-OPERATIONS.EXAMPLE.COM@KRBNT-OPERATIONS.EXAMPLE.COM」、後者が「sample/raven.example.com@KRBNT-OPERATIONS.EXAMPLE.COM」、ユーザー名が前の段落で指定したのと同じである場合を考えます。この場合、grant 文は次のようになります

grant CodeBase "file:./SampleClient.jar", 
    Principal javax.security.auth.kerberos.KerberosPrincipal 
        "mjones@KRBNT-OPERATIONS.EXAMPLE.COM" {

    permission java.net.SocketPermission "*", "connect";

    permission javax.security.auth.kerberos.ServicePermission
        "krbtgt/KRBNT-OPERATIONS.EXAMPLE.COM@KRBNT-OPERATIONS.EXAMPLE.COM", 
        "initiate";

    permission javax.security.auth.kerberos.ServicePermission
        "sample/raven.example.com@KRBNT-OPERATIONS.EXAMPLE.COM", 
        "initiate";
};

サーバーのポリシーファイル

Login ユーティリティークラスに必要なアクセス権

サーバーポリシーファイル内の Login クラス用 grant 文は、クライアントポリシーファイル内の grant 文とまったく同じです (「Login ユーティリティークラスに必要なアクセス権」を参照)。

grant codebase "file:./Login.jar" {
   permission java.security.AllPermission;
};

SampleServer に必要なアクセス権

SampleServer コードは、アクセス権の必要な 2 つのタイプの操作を実行します。次のとおりです。

ソケット接続の受け入れに必要なアクセス権を、次に示します。

permission java.net.SocketPermission "*", "accept";

"*" は、SampleClient を実行するマシンのホスト名または IP アドレスで置き換えることができます。

セキュリティーコンテキストの確立を受け入れるのに必要なアクセス権を、次に示します。

permission javax.security.auth.kerberos.ServicePermission
    "service_principal@your_realm", 
    "accept";
ここで、"service_principal@your_realm" は、SampleServer を表すサービスプリンシパルの Kerberos 名です。

SampleServer を実行する特定の認証済みユーザー (SampleServer を表すと見なされるサービスプリンシパル) にアクセス権を付与するため、SampleServer のコード位置 (SampleServer.jar 内) およびサービスプリンシパルを表すプリンシパル指示部の両方を指定します。この名前が、「sample/raven.example.com@KRBNT-OPERATIONS.EXAMPLE.COM」である場合を考えましょう。この場合、grant 文は次のようになります

  grant CodeBase "file:./SampleServer.jar" 
    Principal javax.security.auth.kerberos.KerberosPrincipal 
        "sample/raven.example.com@KRBNT-OPERATIONS.EXAMPLE.COM" {

    permission java.net.SocketPermission "*", "accept";

    permission javax.security.auth.kerberos.ServicePermission
        "sample/raven.example.com@KRBNT-OPERATIONS.EXAMPLE.COM", "accept";
};

SampleClient および SampleServer プログラムの実行

SampleClient および SampleServer プログラムを実行するには、次の操作を行います。

SampleServer の実行準備

SampleServer の実行準備では、次の操作を行います。

  1. 次のファイルを、SampleServer を実行するマシンからアクセス可能なディレクトリにコピーします。
  2. csLogin.conf の「service_principal@your_realm」を、SampleServer を表すサービスプリンシパルの名前で置き換えます。
  3. 表示される両方の場所で、server.policy の「service_principal@your_realm」を、SampleServer を表すサービスプリンシパルの Kerberos 名で置き換えてください。これは、ログイン構成ファイルで使用する名前と同じ名前です。
  4. Login.javaSampleServer.java をコンパイルします。
    javac Login.java SampleServer.java
    

    Login.java には 2 つのクラスが含まれるため、Login.java をコンパイルすると Login.class および MyAction.class が生成されます。

  5. Login.class and MyAction.class を含む Login.jar という名前の JAR ファイルを作成します。
    jar -cvf Login.jar Login.class MyAction.class
    
  6. SampleServer.class を含む SampleServer.jar という名前の JAR ファイルを作成します。
    jar -cvf SampleServer.jar SampleServer.class
    

SampleClient の実行準備

SampleClient の実行準備では、次の操作を行います。

  1. 次のファイルを、SampleClient を実行するマシンからアクセス可能なディレクトリにコピーします。
  2. client.policy の各部を置き換えます。
  3. Login.javaSampleClient.java をコンパイルします。
    javac Login.java SampleClient.java
    
  4. Login.class and MyAction.class を含む Login.jar という名前の JAR ファイルを作成します。
    jar -cvf Login.jar Login.class MyAction.class
    
  5. SampleClient.class を含む SampleClient.jar という名前の JAR ファイルを作成します。
    jar -cvf SampleClient.jar SampleClient.class
    

SampleServer の実行

SampleClient を実行する前に、必ず SampleServer を実行してください。SampleClientSampleServer へのソケット接続を試みるため、SampleServer が稼動していないとソケット接続が受け付けられず、失敗します。

SampleServer を実行する場合、SampleServer を稼動する予定のマシンで実行してください。このマシン名 (ホスト名) は、SampleClient の引数として指定します。サービスプリンシパル名は、ログイン構成ファイルやポリシーファイルなど、いくつかの場所に表示されます。

SampleServer の実行用に準備したディレクトリに移動します。次を指定して、Login クラスを実行します。

Login の引数として、アプリケーションの名前 (ここでは「SampleServer」) を渡します。次に、アプリケーションに必要なすべての引数を追加します。SampleServer の場合、クライアント接続の待機に使用するポート番号を引数として指定します。通常は使用しない大きなポート番号であれば、どの番号でも選択できます。(例、4444)。

次に、Microsoft Windows および Unix システムの両方で使用可能なすべてのコマンドを示します。classpath 項目の区切りとして、UNIX システムではコロンを使用するのに対し、Microsoft Windows システムではセミコロンを使用する点だけが異なります。

重要: これらのコマンドの、<port_number> を適切なポート番号に、<your_realm> を使用する Kerberos レルムに、<your_kdc> を使用する Kerberos KDC にそれぞれ置き換えてください。

次に、Microsoft Windows システムのコマンドを示します。

java -classpath Login.jar;SampleServer.jar 
 -Djava.security.manager 
 -Djava.security.krb5.realm=<your_realm> 
 -Djava.security.krb5.kdc=<your_kdc> 
 -Djava.security.policy=server.policy 
 -Djava.security.auth.login.config=csLogin.conf 
 Login SampleServer <port_number>

次に、UNIX システムのコマンドを示します。

java -classpath Login.jar:SampleServer.jar 
 -Djava.security.manager 
 -Djava.security.krb5.realm=<your_realm> 
 -Djava.security.krb5.kdc=<your_kdc> 
 -Djava.security.policy=server.policy 
 -Djava.security.auth.login.config=csLogin.conf 
 Login SampleServer <port_number>

コマンド全体を 1 行で入力してください。ここでは、読みやすくするために複数行に分けて表示してあります。コマンドが長すぎる場合は、.bat ファイル (Microsoft Windows) または .sh ファイル (UNIX) に記述します。このファイルを実行することで、コマンドを実行できます。

サービスプリンシパルの Kerberos パスワードの入力が求められます。ログイン構成ファイルで指定された基盤となる Kerberos 認証メカニズムにより、サービスプリンシパルの Kerberos へのログインが行われます。認証が成功すると、SampleServer のコードがサービスプリンシパルに代わって実行されます。このコードは、指定されたポート上でソケット接続を待機します。

ログイン時のトラブルシューティングについては、「トラブルシューティング」を参照してください。

SampleClient の実行

SampleClient を実行するため、SampleClient の実行準備を行なったディレクトリに移動します。次に、次を指定して、Login クラスを実行します。

Login に、アプリケーションの名前 (「SampleClient」)、そのあと SampleClient に必要な引数を渡します。SampleClient の引数は、(1) SampleServer を表すサービスプリンシパルの Kerberos 名、(2) SampleServer を実行するホスト (マシン) の名前、(3) SampleServer がクライアント接続を待機するポート番号です。

次に、Microsoft Windows および Unix システムの両方で使用可能なすべてのコマンドを示します。

重要: これらのコマンドの <service_principal><host><port_number><your_realm>、および <your_kdc> の位置には、適切な値を指定してください (ポート番号は、SampleServer の引数として渡したポート番号と同じにする)。値を引用符で囲む必要はありません。

次に、Microsoft Windows システムのコマンドを示します。

java -classpath Login.jar;SampleClient.jar 
 -Djava.security.manager 
 -Djava.security.krb5.realm=<your_realm> 
 -Djava.security.krb5.kdc=<your_kdc> 
 -Djava.security.policy=client.policy 
 -Djava.security.auth.login.config=csLogin.conf 
 Login SampleClient <service_principal> <host> <port_number>

次に、UNIX システムのコマンドを示します。

java -classpath Login.jar:SampleClient.jar 
 -Djava.security.manager 
 -Djava.security.krb5.realm=<your_realm> 
 -Djava.security.krb5.kdc=<your_kdc> 
 -Djava.security.policy=client.policy 
 -Djava.security.auth.login.config=csLogin.conf 
 Login SampleClient <service_principal> <host> <port_number>

コマンド全体を 1 行で入力してください。ここでは、読みやすくするために複数行に分けて表示してあります。SampleServer を実行するコマンドと同様、コマンドウィンドウに直接入力するにはコマンドが長すぎる場合、.bat ファイル (Windows) または .sh ファイル (UNIX) に記述して、そのファイルを実行してください。

入力が求められたら、Kerberos ユーザー名およびパスワードを入力します。ログイン構成ファイルで指定された基盤となる Kerberos 認証メカニズムにより、Kerberos へのログインが行われます。認証が成功すると、SampleClient のコードがユーザーに代わって実行されます。このコードは、SampleServer とのソケット接続を要求します。SampleServer が接続を受け付けると、SampleClient および SampleServer により、このチュートリアルで解説した方法で、共有コンテキストの確立およびメッセージの交換が行われます。

ログイン時のトラブルシューティングについては、「トラブルシューティング」を参照してください。



前のチュートリアル チュートリアルの紹介および目次 次のチュートリアル

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