プライマリ・コンテンツに移動
Oracle® Fusion Middleware WebLogicセキュリティ・サービスによるアプリケーションの開発
12c (12.2.1.3.0)
E90346-03
目次へ移動
目次

前
次

5 JavaクライアントでのSSL認証の使用

JSSE (Java Secure Socket Extension)は、SSLとTLSプロトコルをサポートおよび実装するパッケージのセットです。WebLogic Serverは、WebLogic Serverクライアントとサーバー、Javaクライアント、Webブラウザ、および他のサーバーの間で転送されるデータを暗号化するためにSecure Sockets Layer (SSL)をサポートしています。JavaクライアントにおけるSSLとデジタル証明書認証の実装方法を学習します。

これらの項で参照するサンプル・コードは、オプションでWebLogic Server配布キットの次の場所に含まれています。

EXAMPLES_HOME\src\examples\security\sslclient

EXAMPLES_HOMEディレクトリは、ORACLE_HOME\wlserver\samples\server\examplesにあります。

sslclientディレクトリには、instructions.htmlファイル、antビルド・ファイル、および以下のJavaファイルとJavaServer Pageファイル(.jsp)が含まれています。

以降の説明は、実際のサンプルを見ながら読み進めてください。

JSSEとWebLogic Server

WebLogicのサーバー側アプリケーションでSSLを使用する際には、一定の制限があります。

WebLogicクライアントではWebLogic ServerのJSSEの実装を使用できますが、これは必須ではありません。他のJSSEの実装も、サーバーの外側のクライアント側のコードで同じように使用できます。

注意:

JSSEは、サポートされる唯一のSSL実装です。CerticomベースのSSL実装は削除され、WebLogic Serverでサポートされません。

WebLogicのサーバー側アプリケーションでSSLを使用する際には、以下の制限が適用されます。

  • WebLogic Serverアプリケーションの開発における他の(サード・パーティの)JSSE実装の使用はサポートされていません。WebLogic Serverが使用するSSLの実装はサーバーの構成に対して固定であり、ユーザーのアプリケーションによって置き換えることはできません。

  • JSSEのWebLogic実装はJCE暗号サービス・プロバイダ(Cryptographic Service Provider : CSP)をサポートしていますが、プロバイダのJCEに対するサポートが一定していないため、テストされていないプロバイダがそのまま機能するかどうかは保証されていません。以下のプロバイダではWebLogic Serverをテスト済みです。

    その他のプロバイダはWebLogic Serverで機能する可能性はありますが、テストされていないプロバイダの場合、おそらくそのままでは機能しません。WebLogic ServerでサポートされているJCEプロバイダの使用方法の詳細は、『Oracle WebLogic Serverセキュリティの管理』のWebLogic ServerでのJCEプロバイダの使用に関する項を参照してください。

WebLogic Serverでは、Secure Sockets Layer (SSL)で暗号化された通信にHTTPSポートを使用します。このポートはSSLにしか使用できません。

注意:

WebLogicクライアントでセキュリティを実装するためには、JavaクライアントでWebLogic Serverソフトウェア配布キットをインストールする必要があります。

注意:

JSSEはそのSSL実装においてServer Name Indication(SNI)をサポートしますが、WebLogic ServerはSNIをサポートしません。

JNDI認証の使い方

Javaクライアントは、Java Naming and Directory Interface (JNDI)を使用してWebLogic Serverに資格証明を渡します。Javaクライアントは、JNDI InitialContextを取得してOracle WebLogic Serverとの通信を確立します。その後、InitialContextを使用して、Oracle WebLogic Server JNDIツリーで必要なリソースをルックアップします。

注意:

JAASは認証方法として望ましい選択肢ですが、認証プロバイダのLoginModuleはユーザー名とパスワードの認証しかサポートしていません。したがって、クライアントの証明書認証(双方向SSL認証ともいう)ではJNDIを使用します。クライアントの証明書認証にJAASを使用するには、LoginModuleで証明書の認証を行うカスタム認証プロバイダを記述する必要があります。

ユーザーとユーザーの資格証明を指定するには、表5-1で示されているJNDIプロパティを設定します。

表5-1 認証に使用されるJNDIプロパティ

プロパティ 意味
INITIAL_CONTEXT_FACTORY 

エントリ・ポイントをOracle WebLogic Server環境に提供します。クラスweblogic.jndi.WLInitialContextFactoryOracle WebLogic Server用のJNDI SPIです。

PROVIDER_URL 

ネーム・サービスを提供するWebLogic Serverのホストとポートを指定します。例: t3s://weblogic:7002.

(t3sはSSLのWebLogic Server独自のバージョンです。)

SECURITY_PRINCIPAL 

ユーザーがデフォルトの(アクティブな)セキュリティ・レルムに対して認証されているときのユーザーのIDを指定します。

SECURITY_CREDENTIALS 

ユーザーがデフォルトの(アクティブな)セキュリティ・レルムに対して認証されているときのユーザーの資格証明を指定します。

これらのプロパティは、InitialContextコンストラクタに渡されるハッシュ表に格納されます。

例5-1は、Javaクライアントで一方向SSL証明書認証を使用する方法を示しています。双方向SSL認証のコード例については、例5-4を参照してください。

注意:

JNDIのコンテキストとスレッドおよび潜在的なJNDIコンテキスト問題の予防方法の詳細は、Oracle WebLogic ServerのJNDIアプリケーションの開発でJNDIのコンテキストとスレッドと潜在的なJNDIコンテキスト問題の予防方法を参照してください。

例5-1 JNDIを使用する一方向SSL認証の例

...
Hashtable env = new Hashtable();
      env.put(Context.INITIAL_CONTEXT_FACTORY,
              "weblogic.jndi.WLInitialContextFactory");
      env.put(Context.PROVIDER_URL, "t3s://weblogic:7002");
      env.put(Context.SECURITY_PRINCIPAL, "javaclient");
      env.put(Context.SECURITY_CREDENTIALS, "javaclientpassword");
      Context ctx = new InitialContext(env);

SSL証明書認証の開発環境

WebLogic ServerでSSL認証を実装するには、Javaアプリケーション・プログラミング・インタフェース(API)とWebLogic APIを組み合せて使用します。WebLogic ServerでのSSLの実装を容易にする、HostnameVerifierとTrustManagerなど、SSLクライアント・アプリケーションのいくつかのコンポーネントがあります。

この節では、以下の内容について説明します。

SSL認証API

WebLogic ServerでSSL認証を使用するJavaクライアントを実装するには、Javaアプリケーション・プログラミング・インタフェース(API)とWebLogic APIを組み合わせて使用します。

表5-1では、証明書認証の実装に使用されるJava APIパッケージについて説明します。表5-1の情報はJava APIのドキュメントから取られており、WebLogic Server固有の情報がコメントで追加されています。Java APIの詳細は、http://docs.oracle.com/javase/7/docs/api/index.htmlおよびhttp://docs.oracle.com/javaee/7/api/のJavadocを参照してください。

表5-3では、証明書認証の実装に使用されるWebLogic APIについて説明します。Oracle WebLogic Server Java APIリファレンスを参照してください。

表5-2 Java証明書API

Java証明書API 説明

javax.crypto (http://docs.oracle.com/javase/7/docs/api/index.html)

このパッケージは暗号操作のためのクラスとインタフェースを提供します。このパッケージで定義されている暗号操作には、暗号化、鍵の生成と照合、およびMessage Authentication Code (MAC)の生成が含まれます。

暗号化のサポートには、対称、非対称、ブロック、およびストリームの各暗号方式が含まれています。このパッケージは、セキュア・ストリームおよび暗号化されたオブジェクトもサポートしています。

このパッケージで提供されるクラスの多くは、プロバイダ・ベースです(java.security.Providerクラスを参照)。クラス自体では、アプリケーションを記述できるプログラミング・インタフェースが定義されています。独立したサード・パーティ・ベンダーは、必要に応じて、実装自体を作成し、シームレスに組み込むことができます。したがって、アプリケーション開発者は、コードを追加したり書き直したりしなくても、プロバイダ・ベースの実装をいくつでも利用できます。

javax.net (http://docs.oracle.com/javase/7/docs/api/index.html)

このパッケージはネットワーク・アプリケーション用のクラスを提供します。ソケット作成用のファクトリが含まれています。ソケット・ファクトリを使うと、ソケットの作成と構成の動作をカプセル化できます。

javax.net.SSL (http://docs.oracle.com/javase/7/docs/api/index.html)

このパッケージのクラスとインタフェースはWebLogic Serverでサポートされていますが、WebLogic ServerでSSLを使用するときにはweblogic.security.SSLパッケージの使用をお薦めします。

java.security.cert (http://docs.oracle.com/javase/7/docs/api/index.html)

このパッケージは、証明書、証明書失効リスト(CRL)、および証明書パスの解析と管理を行うためのクラスとインタフェースを提供します。X.509 v3証明書およびX.509 v2 CRLのサポートが含まれています。

java.security.KeyStore (http://docs.oracle.com/javase/7/docs/api/index.html)

このクラスは、鍵と証明書のメモリー内コレクションを表します。以下の2タイプのキーストア・エントリの管理に使用されます。

  • キー・エントリ

    このタイプのキーストア・エントリは暗号鍵情報を保持しています。これは不正アクセスを防ぐため、保護された形式で格納されます。

    通常、このタイプのエントリに格納された鍵は、対応する公開鍵の証明書チェーンを伴う秘密鍵または秘密鍵です。

    秘密鍵および証明書チェーンは、自動認証のための指定されたエンティティによって使用されます。この認証のためのアプリケーションには、ソフトウェアのリリースやライセンス付与の一環としてJARファイルに署名するソフトウェア配布組織が含まれます。

  • 信頼性のある証明書エントリ

    このタイプのエントリには、別の相手に属する単一の公開鍵証明書が含まれます。これは信頼性のある証明書と呼ばれます。その証明書内の公開鍵が、実際に証明書のサブジェクト(オーナー)によって識別されるIDに属するものであるとキーストアのオーナーが信頼するからです。

    このタイプのエントリは、他の相手を認証するのに使用できます。

java.security.PrivateKey (http://docs.oracle.com/javase/7/docs/api/index.html)

秘密鍵。このインタフェースには、メソッドまたは定数が含まれません。すべての秘密鍵インタフェースのグループ化(およびタイプ保証)を行う役割を持つのみです。

注: 特殊化された非公開鍵インタフェースはこのインタフェースを拡張します。たとえば、java.security.interfacesDSAPrivateKeyインタフェースを参照してください。

java.security.Provider (http://docs.oracle.com/javase/7/docs/api/index.html)

このクラスは、Java Security APIの「暗号サービス・プロバイダ」を表します。プロバイダは、以下のようなJava Securityの一部または全部を実装します。

  • アルゴリズム(DSA、RSA、MD5、SHA-1など)

  • キーの生成、変換、および管理機能(アルゴリズム固有キーなど)

各プロバイダには名前とバージョン番号が付いており、インストールされる各実行時において構成されます。

暗号サービスの実装を提供するには、開発者チームまたはサード・パーティのベンダーが実装コードを記述し、Providerクラスのサブクラスを作成します。

javax.servlet.http.HttpServletRequest (http://docs.oracle.com/javaee/7/api/index.html)

このインタフェースは、ServletRequestインタフェースを拡張して、HTTPサーブレットのリクエスト情報を提供します。

サーブレット・コンテナは、HttpServletRequestオブジェクトを作成し、サーブレットのサービス・メソッド(doGetdoPostなど)に引数として渡します。

javax.servlet.http.HttpServletResponse (http://docs.oracle.com/javaee/7/api/index.html)

このインタフェースは、ServletResponseインタフェースを拡張して、レスポンス送信の際にHTTP固有の機能を提供します。たとえば、このインタフェースにはHTTPヘッダーおよびCookieにアクセスする方法が含まれます。

サーブレット・コンテナは、HttpServletRequestオブジェクトを作成し、サーブレットのサービス・メソッド(doGetdoPostなど)に引数として渡します。

javax.servlet.ServletOutputStream (http://docs.oracle.com/javaee/7/api/index.html)

このクラスは、バイナリ・データをクライアントに送信するための出力ストリームを提供します。ServletOutputStreamオブジェクトは通常、ServletResponse.getOutputStream()メソッドを通じて取得されます。

これは、サーブレット・コンテナが実装する抽象クラスです。このクラスのサブクラスは、java.io.OutputStream.write(int)メソッドを実装する必要があります。

javax.servlet.ServletResponse (http://docs.oracle.com/javaee/7/api/index.html)

このクラスは、クライアントにレスポンスを送信する際にサーブレットを支援するオブジェクトを定義します。サーブレット・コンテナは、ServletResponseオブジェクトを作成し、サーブレットのサービス・メソッド(doGetdoPostなど)に引数として渡します。

表5-3 WebLogic証明書API

WebLogic証明書API 説明

weblogic.net.http.HttpsURLConnection

リモートのオブジェクトにHTTP with SSL (HTTPS)を提示するのに使用されるクラスを提供します。このクラスは、クライアントとして機能しているWebLogic Serverから別のWebLogic ServerへのアウトバウンドSSL接続を確立するために使われます。

weblogic.security.SSL.HostnameVerifier

SSLハンドシェーク時のホスト名検証によって、URL内のホスト名がサーバーのID内のホスト名に一致するかどうかが検証されます。この検証は、介入者攻撃を防ぐために必要となります。

WebLogic Serverでは、HostnameVerifierの証明書ベースの実装がデフォルトで使用され、URLホスト名がサーバー証明書のCNフィールドと一致するかどうかが検証されます。

WebLogic Server管理コンソールの「SSL」タブにある「詳細オプション」ペインを使用すると、このデフォルトのホスト名検証をカスタム・ホスト名検証に変更できます。その場合、WebLogic SSL APIを使用しているサーバーで実行されているSSLクライアントのデフォルトに影響が生じます。また、HttpsURLConnectionSSLContextなどのWebLogic SSL APIを使用すると、カスタムHostnameVerifierを明示的に設定できます。

weblogic.security.SSL.TrustManager

このインタフェースを使うと、ユーザーはピアの証明書チェーンでの何らかの検証エラーをオーバーライドし、ハンドシェークを継続できます。また、ピア証明書チェーンに対しさらに検証を実行し、必要に応じてハンドシェークを中断することもできます。

weblogic.security.SSL.CertPathTrustManager

このクラスは、構成済みのCertPathValidationプロバイダを使用して、失効チェックなどの追加的な検証を実行します。

デフォルトでは、CertPathTrustManagerはインストールされますが、CertPathValidatorsを呼び出さないように構成されています(InboundCertificateValidationおよびOutboundCertificateValidationのSSLMBean属性で制御します)。

カスタムTrustManagerをインストールするアプリケーションでは、CertPathTrustManagerが置き換えられます。カスタムTrustManagerを使用するアプリケーションでCertPathProvidersも呼び出したい場合は、カスタムTrustManagerからCertPathTrustManagerに委任できます。

weblogic.security.SSL.SSLContext

このクラスは、このコンテキスト下で作成されたすべてのソケットで共有されるすべての状態情報を保持します。

weblogic.security.SSL.SSLSocketFactory

このクラスは、SSLソケットを作成するためのAPIを提供します。

weblogic.security.SSL.SSLValidationConstants

このクラスは、コンテキスト要素名を定義します。SSLは、1つまたは複数のCertPathValidatorオブジェクトを呼び出して追加検証を実行する前に、一部の組込み検証を実行します。検証プロバイダは、実行済みの検証を検出することで、必要な検証の規模を縮小できます。

SSLクライアント・アプリケーション・コンポーネント

SSLクライアント・アプリケーションには、少なくとも以下のコンポーネントが含まれます。

  • Javaクライアント

    通常、Javaクライアントは以下の機能を実行します。

    • クライアントID、信頼、HostnameVerifier、およびTrustManagerによるSSLContextの初期化

    • キーストアのロード、および秘密鍵と証明書チェーンの取得

    • SSLSocketFactoryの使用

    • WebLogic Serverのインスタンスによって提供されるJSPに接続するためのHTTPSの使用

  • HostnameVerifier

    HostnameVerifierはweblogic.security.SSL.HostnameVerifierインタフェースを実装します。

  • HandshakeCompletedListener

    HandshakeCompletedListenerは、javax.net.ssl.HandshakeCompletedListenerインタフェースを実装します。このインタフェースは、SSLクライアントが、指定されたSSL接続に対するSSLハンドシェークの完了について通知を受け取るために使用します。

  • TrustManager

    TrustManagerは、weblogic.security.SSL.TrustManagerインタフェースを実装します。

ここで説明しているコンポーネントを実装する完全で実践的なSSL認証クライアントの詳細は、EXAMPLES_HOME\src\examples\security\sslclientのSSLClientのサンプル・アプリケーションを参照してください。EXAMPLES_HOMEは、WebLogic Serverのコード・サンプルが構成されているディレクトリで、ORACLE_HOME\wlserver\samples\serverにあります。

JSSE認証の詳細は、JSSE(Java Secure Socket Extension)リファレンス・ガイド(http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.htmlで入手可能)を参照してください。

SSLを使用するアプリケーションの記述

SSLを使用するアプリケーションを記述する場合、アプリケーションがどのように使用されるかと安全な通信のための特別な要件を考慮してください。アプリケーションが、別のWebLogic Serverインスタンスに対するクライアントとして動作するWebLogic Serverインスタンスにホストされるかどうかなどです。その他の考慮事項には、双方向SSL、カスタム・ホスト名検証、トラスト・マネージャまたはその他のセキュリティ・アーティファクトを使用する必要があるかなどが含まれます。

WebLogic Server間の安全な通信

URLオブジェクトを使用すると、クライアントとして機能しているWebLogic Serverインスタンスから別のWebLogic ServerインスタンスへのアウトバウンドSSL接続を確立することができます。weblogic.net.http.HttpsURLConnectionクラスを使用して、秘密鍵とデジタル証明書を含む、クライアントのセキュリティ・コンテキスト情報を指定できます。

weblogic.net.http.HttpsURLConnectionクラスは、ネゴシエーションされた暗号スイートの判別、ホスト名検証の取得と設定、サーバーの証明書チェーンの取得、および新しいSSLソケットを作成するためのSSLSocketFactoryの取得と設定を行うメソッドを提供します。

SSLClientのサンプル・コードでは、weblogic.net.http.HttpsURLConnectionクラスを使用してアウトバウンドSSL接続を確立しています。SSLClientのサンプル・コードは、EXAMPLES_HOME\src\examples\security\sslclientexamples.security.sslclientパッケージで入手できます。EXAMPLES_HOMEは、WebLogic Serverのサンプル・コードが構成されているディレクトリで、ORACLE_HOME\wlserver\samples\serverにあります。

SSLクライアントの作成

ここでは、様々なタイプのSSLクライアントを作成する方法を、サンプルを使って説明します。以下のタイプのSSLクライアントについて説明します。

SSLClientサンプル

SSLClientサンプルでは、URLおよびURLConnectionオブジェクトによって発信SSL接続をWebLogic SSLライブラリを使用して確立する方法が示されています。スタンドアロンのアプリケーションからだけでなく、WebLogic Server内のサーブレットからこの処理を行う方法も示されています。

注意:

SSLクライアントとして機能するWebLogic Serverでは、発信SSL接続にサーバーのID証明書を使用します。WebLogic Serverで実行するアプリケーションで以前に記述されたSSL APIを使用している場合、デフォルトではサーバーのID証明書は共有されません(信頼のみ)。

例5-2は、SSLClientサンプルの抜粋コードです。完全なサンプルは、SSLClient.javaファイルのEXAMPLES_HOME\src\examples\security\sslclientディレクトリにあります。

EXAMPLES_HOMEディレクトリは、ORACLE_HOME\wlserver\samples\server.にあります

例5-2 SSLClientサンプル・コードの抜粋

package examples.security.sslclient;

import java.io.*;
import java.net.URL;
import java.security.Provider;
import javax.servlet.ServletOutputStream;
...
  /*
   * This method contains an example of how to use the URL and
   *  URLConnection objects to create a new SSL connection, using
   *  WebLogic SSL client classes.
   */
  public void wlsURLConnect(String host, String port,
                            String sport, String query,
                            OutputStream out)
      throws Exception {
...
      URL wlsUrl = null;
      try {
        wlsUrl = new URL("http", host, Integer.valueOf(port).intValue(),
                               query);
        weblogic.net.http.HttpURLConnection connection =
            new weblogic.net.http.HttpURLConnection(wlsUrl);
        tryConnection(connection, out);
      } 
...
      wlsUrl = new URL("https", host, Integer.valueOf(sport).intValue(),
                             query);
      weblogic.net.http.HttpsURLConnection sconnection =
          new weblogic.net.http.HttpsURLConnection(wlsUrl);
...

SSLSocketClientサンプル

SSLSocketClientサンプルでは、直接セキュア・ポートからWebLogic Serverのインスタンスによって提供されるJSPに接続し、その接続の結果を表示する方法を示します。以下の機能を実装する方法が示されています。

  • クライアントID、HostnameVerifier、およびTrustManagerによるSSLContextの初期化

  • キーストアのロード、および秘密鍵と証明書チェーンの取得

  • SSLSocketFactoryの使用

  • WebLogic Serverによって提供されるJSPに接続するためのHTTPSの使用

  • javax.net.ssl.HandshakeCompletedListenerインタフェースの実装

  • サンプルが接続するサーバーが目的のホスト上で稼働していることを確認するための、weblogic.security.SSL.HostnameVerifierクラスのダミー実装の作成

例5-2は、SSLSocketClientサンプルの抜粋コードです。完全なサンプルは、SSLSocketClient.javaファイルのEXAMPLES_HOME\src\examples\security\sslclientディレクトリにあります。(sslclientディレクトリにあるSSLClientServletサンプルは、SSLClientサンプルの簡単なサーブレット・ラッパーです。)EXAMPLES_HOMEディレクトリは、ORACLE_HOME\wlserver\samples\serverにあります。

例5-3 SSLSocketClientサンプル・コードの抜粋

package examples.security.sslclient;

import java.io.*;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLSocket;
import weblogic.security.SSL.HostnameVerifier;
import weblogic.security.SSL.SSLContext;
import weblogic.security.SSL.SSLSocketFactory;
import weblogic.security.SSL.TrustManager;
...
      SSLContext sslCtx = SSLContext.getInstance("https");
      File KeyStoreFile  = new File ("mykeystore");
...
    // Open the keystore, retrieve the private key, and certificate chain
      KeyStore ks = KeyStore.getInstance("jks");
      ks.load(new FileInputStream("mykeystore"), null);
      PrivateKey key = (PrivateKey)ks.getKey("mykey",
                            "testkey".toCharArray());
      Certificate [] certChain = ks.getCertificateChain("mykey");
      sslCtx.loadLocalIdentity(certChain, key);
      HostnameVerifier hVerifier = null;
      if (argv.length < 3)
        hVerifier = new NulledHostnameVerifier();
      else
         hVerifier = (HostnameVerifier)
                         Class.forName(argv[2]).newInstance();

      sslCtx.setHostnameVerifier(hVerifier);
      TrustManager tManager = new NulledTrustManager();
      sslCtx.setTrustManager(tManager);
       System.out.println(" Creating new SSLSocketFactory with SSLContext");
      SSLSocketFactory sslSF = (SSLSocketFactory)
                                      sslCtx.getSocketFactory();
      System.out.println(" Creating and opening new SSLSocket with
                           SSLSocketFactory");
      // using createSocket(String hostname, int port)
      SSLSocket sslSock = (SSLSocket) sslSF.createSocket(argv[0],
                           new Integer(argv[1]).intValue());
      System.out.println(" SSLSocket created");
       HandshakeCompletedListener mListener = null;
        mListener = new MyListener();
       sslSock.addHandshakeCompletedListener(new MyListener());
      ...

双方向SSL認証の使用

証明書認証では、Oracle WebLogic Serverは、リクエスト元のクライアントにデジタル証明書を送信します。クライアントは、デジタル証明書を調べて、本物かどうか、期限切れでないかどうか、認証元のOracle WebLogic Serverインスタンスに一致しているかどうかを確認します。

双方向SSL認証(相互認証の一形態)を使用する場合は、リクエスト元のクライアントもデジタル証明書をOracle WebLogic Serverに提示します。双方向SSL認証をするようWebLogic Serverのインスタンスを構成すると、指定した認証局からデジタル証明書を送信するようにリクエスト元のクライアントに要求できるようになります。Oracle WebLogic Serverでは、信頼性のある認証局によって署名されたデジタル証明書のみが受け付けられます。

WebLogic Serverを双方向SSL認証用に構成する方法の詳細は、Oracle WebLogic Serverセキュリティの管理のSSLの構成に関する項を参照してください。

以降の節では、双方向SSL認証をWebLogic Serverに実装する様々な方法について説明します。

JNDIを使用した双方向SSL認証

Javaクライアントでの双方向SSL認証でJNDIを使用する場合、WebLogic JNDI Environmentクラスの次のどちらかのメソッドを使用できます。
  • loadLocalIdentity(): このメソッドは、クライアント認証のために証明書の配列、およびローカル・アイデンティティの秘密鍵を現在のスレッドにロードします。

  • setSSLContext(): このメソッドは、クライアント認証のためにSSLContextを現在のスレッドに設定します。

注意:

setSSLClientCertificate()およびsetSSLClientKeyPassword()は、このリリースでは非推奨になりました。

サーバーが双方向SSL用に構成されている場合は、loadLocalIdentity(certs, privateKey)を使用して、クライアントのアイデンティティ証明書をサーバーに渡すことができます。このメソッドは、X509Certificate配列、および証明書に関連付けられた秘密鍵という2つのパラメータを取ります。多くの場合、証明連鎖配列は、1つの要素のみで構成されます。

例5-4は、Javaクライアントで双方向SSL認証のためにloadLocalIdentity()メソッドを使用する方法を示しています。

例5-4 JNDI Environment loadLocalIdentityメソッドを使用する双方向SSL認証クライアントの例

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import java.security.KeyStore;
import weblogic.jndi.Environment;
import weblogic.security.PEMInputStream;
import java.io.InputStream;
import java.io.FileInputStream;
...

public class SSLJNDIClient 

{ 
  public static void main(String[] args) throws Exception
  {
    Context context = null;
    try {
      Environment env = new Environment();
      // set connection parameters
      env.setProviderUrl("t3s://localhost:7002");      
      // The next two set methods are optional if you are using
      // a UserNameMapper interface.
      env.setSecurityPrincipal("system");
      env.setSecurityCredentials("weblogic");

      // Read the certificate & private key entry from a JKS file
      // This example assumes the private key and certificate chain were stored to the keystore with
      // setKeyEntry(String alias, Key key, char[] password, Certificate[] chain)
      KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
      // For simplicity, this example just uses a hardcoded password for the keystore
      char[] keyStorePassword = "a keystore password".getBytes();
      java.io.FileInputStream fis = null;
      try {
        fis = new java.io.FileInputStream("full_path_to_keystore_file");
        ks.load(fis, keyStorePassword);
      } finally {
        if (fis != null) {
            fis.close();
        }
      }
      
      // The private key password that was used to store the private key entry
      // This example uses a hardcoded private key password for simplicity
      char[] privateKeyPassword = "a private key entry password".getBytes();
      KeyStore.ProtectionParameter passwordProtParam = new KeyStore.PasswordProtection(privateKeyPassword);

      // get my private key
      KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry("privateKeyAlias", passwordProtParam);
      PrivateKey privateKey = pkEntry.getPrivateKey();
      Certificate[] certs = pkEntry.getCertificateChain();
      
      env.loadLocalIdentity(certs, privateKey);
      env.setInitialContextFactory(Environment.DEFAULT_INITIAL_CONTEXT_FACTORY); 
      context = env.getInitialContext();
      Object myEJB = (Object) context.lookup("myEJB");
    }
    finally {
      if (context != null) context.close();
    }
  }
}

setSSLContext(SSLContext sslctx)を使用するには、サーバーが双方向SSL用に構成されている場合に、JNDIを使用して、trustManagerおよびkeyManagerから作成されたクライアント証明書とともにSSLContextをサーバーに渡します。Java™ Platform Standard Edition 7 API仕様クラスSSLContextを参照してください。

注意:

setSSLContextメソッドの呼出しには、WebLogicシンT3クライアント(wlthint3client.jar)が必要となります。

setSSLContext()は、現在の秘密鍵および証明書のロードloadLocalIdentity(Certificate[] certs, PrivateKey privateKey)またはsetSSLClientCertificate(InputStream[] chain)より優先されます。つまり、クライアント証明書およびprivateKeyと同時にsslContextが構成されている場合は、sslContextが使用されます。

例5-5は、Javaクライアントで双方向SSL認証のためにsetSSLContext()メソッドを使用する方法を示しています。

例5-5 JNDI Environment setSSLContextを使用する双方向SSL認証クライアントの例

import java.security.*;
import java.net.*;
import javax.naming.Context;
import javax.net.ssl.*;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import javax.security.auth.Subject;
import weblogic.jndi.Environment;
import weblogic.jndi.api.ServerEnvironment;
import weblogic.security.auth.Authenticate;
...

public class JNDISSLContextClient
{
	private static javax.net.ssl.SSLContext m_sslContext = null;
	
	public static void main(String[] args) {
               
               try {
                    KeyStore keystore;
                    keystore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
                    keystore.load(null, null);
                    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        			kmf.init(keystore, null);
         			KeyManager[] keyManagers = kmf.getKeyManagers();

					KeyStore truststore;
                    truststore = KeyStore.getInstance("Windows-ROOT", "SunMSCAPI");
                    truststore.load(null, null);
                    TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
                    tmf.init(truststore);
                    TrustManager[] trustManagers = tmf.getTrustManagers();
     
                    m_sslContext = SSLContext.getInstance("TLS");
                    m_sslContext.init(keyManagers, trustManagers, new SecureRandom());
      
                    weblogic.jndi.api.ServerEnvironment env = new Environment();
                    env.setProviderUrl(url); //e.g t3s://host:port
                    env.setSecurityPrincipal("system");
					env.setSecurityCredentials("weblogic");
                    env.setSSLContext(m_sslContext);
                    env.setInitialContextFactory("weblogic.jndi.WLInitialContextFactory");
					
                    Context context = env.getInitialContext();
                    Subject soggetto = weblogic.security.Security.getCurrentSubject();
                    Object ejbObj = context.lookup("ejb");
					...
               } catch (Exception e) {                
                    ;
               } finally {
        		    if (context != null) context.close();          
               }            	
	}
}

注意:

セキュリティ・プロバイダ・プラグインがシステム・クラスパスからロードされます。システム・クラスパスはカスタムweblogic.security.providers.authentication.UserNameMapperインタフェースの実装を指定する必要があります。

証明書ベースの認証を実行するIDアサーション・プロバイダが構成されていない場合、SSL接続のJVMで動作しているJavaクライアントは、新しいJNDI InitialContextを作成し、JNDI SECURITY_PRINCIPALSECURITY_CREDENTIALSプロパティで新しいユーザー名とパスワードを指定することでOracle WebLogic ServerユーザーのIDを変更できます。SSL接続後にJavaクライアントによって渡されたデジタル証明書は使用されません。新しいOracle WebLogic Serverユーザーは、最初のユーザーのデジタル証明書でネゴシエーションしたSSL接続を使用し続けます。

証明書ベースの認証を実行するIDアサーション・プロバイダが構成されている場合、Oracle WebLogic Serverはデジタル証明書をJavaクライアントからUserNameMapperインタフェースを実装するクラスへ渡し、UserNameMapperクラスがデジタル証明書をOracle WebLogic Serverユーザー名にマップします。したがって、証明書ベースのIDアサーションを使用していて新しいユーザーIDを設定する場合、そのIDは変更できません。この理由は、デジタル証明書は、EnvironmentごとにJVMからの最初の接続リクエストの時点でのみ処理されるからです。

注意:

双方向SSLとJNDIを使用している場合は、1つのクライアントJVMから複数のユーザーが同時にWebLogic Serverにログインすることはできません。異なるスレッドで複数のログインが実行された場合、その結果は確認不能であり、片方のユーザーのリクエストが別のユーザーのログインで実行され、ユーザーが別のユーザーのデータにアクセスできるようになることも考えられます。WebLogic Serverでは、1つのクライアントJVMからの証明書ベースの複数の同時ログインをサポートしていません。JNDIのコンテキストとスレッドおよび潜在的なJNDIコンテキスト問題の予防方法の詳細は、Oracle WebLogic ServerのJNDIアプリケーションの開発でJNDIのコンテキストとスレッドと潜在的なJNDIコンテキスト問題の予防方法を参照してください。

JNDIのgetInitialContext()メソッドが呼び出されると、JavaクライアントとOracle WebLogic Serverは、Webブラウザが相互認証を実行してセキュリティ保護されたWebサーバー接続を取得するのと同じ方法で相互認証を実行します。デジタル証明書を確認できない場合やJavaクライアントのデジタル証明書をデフォルトの(アクティブな)セキュリティ・レルムで認証できない場合、例外がスローされます。認証されたユーザー・オブジェクトはJavaクライアントのサーバー・スレッドに格納され、保護されたWebLogicリソースへのJavaクライアントのアクセスを管理する許可のチェックに使用されます。

WebLogic JNDI Environmentクラスを使用する場合、getInitialContext()メソッドの呼出しごとに新しいEnvironmentオブジェクトを作成する必要があります。Userオブジェクトとセキュリティ資格証明を一度指定すると、ユーザーおよびユーザーに関連する資格証明はEnvironmentオブジェクトの設定に残ります。再設定を試みてJNDI getInitialContext()メソッドを呼び出した場合は、元のユーザーと資格証明が使用されます。

Javaクライアントによる双方向SSL認証を使用する場合、Oracle WebLogic Serverは、クライアントJVMごとに一意のJava仮想マシン(JVM) IDを取得し、JavaクライアントとOracle WebLogic Serverの間の接続が切断されないようにします。処理がないために接続がタイムアウトになるまで、JavaクライアントのJVMが実行されている間は接続が続行されます。Javaクライアントが新しいSSL接続を確実にネゴシエーションできる唯一の方法は、そのJVMを停止してJVMの他のインスタンスを実行することです。

例5-4のコードでは、weblogic.security.providers.authentication.UserNameMapperインタフェースを実装するWebLogic IDアサーション・プロバイダの呼出しが生成されます。UserNameMapperインタフェースを実装するクラスは、デジタル証明書が有効な場合にユーザー・オブジェクトを返します。Oracle WebLogic Serverでは、この認証されたユーザー・オブジェクトはOracle WebLogic Server内のJavaクライアントのスレッドに格納されます。格納されたユーザー・オブジェクトは、以降の認可リクエストで、スレッドがデフォルトの(アクティブな)セキュリティ・レルムで保護されているWebLogicリソースにアクセスする際に使用されます。

ユーザー名マッパーの作成

双方向SSLを使用している場合、WebLogic ServerはSSL接続を確立するときにWebブラウザまたはJavaクライアントのデジタル証明書を確認します。ただし、デジタル証明書はWebブラウザまたはJavaクライアントをWebLogic Serverセキュリティ・レルムのユーザーとしては認識しません。WebブラウザまたはJavaクライアントがセキュリティ・ポリシーで保護されたWebLogic Serverリソースをリクエストすると、WebLogic ServerはWebブラウザまたはJavaクライアントにIDを持つように要求します。このリクエストに対応するため、WebLogic IDアサーション・プロバイダは、WebブラウザまたはJavaクライアントのデジタル証明書をWebLogic Serverセキュリティ・レルムのユーザーにマップするユーザー名マッパーを、有効にできるようにします。ユーザー名マッパーは、weblogic.security.providers.authentication.UserNameMapperインタフェースの実装でなければなりません。

weblogic.security.providers.authentication.UserNameMapperインタフェースのデフォルト実装、DefaultUserNameMapperImplを使用することも、独自の実装を開発することもできます。

WebLogic IDアサーション・プロバイダは、以下のIDアサーション・トークン・タイプについて、UserNameMapperインタフェースの実装を呼び出すことができます。

  • SSLハンドシェークを通じて渡されたX.509デジタル証明書

  • CSIv2を通じて渡されたX.509デジタル証明書

  • CSIv2を通じて渡されたX.501識別名

その他のタイプの証明書をマップする場合は、UserNameMapperインタフェースの独自の実装を記述します。

デジタル証明書をユーザー名にマップするUserNameMapperインタフェースを実装するには、次の処理を実行するUserNameMapperクラスを記述します。

  1. UserNameMapper実装クラスをインスタンス化します。

  2. UserNameMapperインタフェース実装を作成します。

  3. mapCertificateToUserName()メソッドを使用して、クライアントから提示された証明書チェーンに基づいて証明書をユーザー名にマップします。

  4. 文字列属性タイプを対応するAttribute Value Assertionフィールド・タイプにマップします。

セキュリティ・プロバイダ・プラグインがシステム・クラスパスからロードされます。システム・クラスパスはweblogic.security.providers.authentication.UserNameMapperインタフェースの実装を指定する必要があります。

WebLogic Serverインスタンス間で双方向SSL認証の使用

一方のWebLogic Serverインスタンスがもう一方のWebLogic Serverインスタンスのクライアントとして機能するサーバー間通信で双方向SSL認証を使用できます。サーバー間通信で双方向SSL認証を使用すると、一般的なクライアント/サーバー環境でない場合でも、信頼できる高度なセキュリティで保護した接続を利用することができます。

例5-6は、あるWebLogic Serverインスタンスで動作するサーブレットからserver2.weblogic.comという別のWebLogic Serverインスタンスへのセキュリティで保護された接続を確立する方法の例を示しています。

  • setProviderURL - SSLサーバーとして機能するOracle WebLogic ServerインスタンスのURLを指定します。SSLクライアントとして機能するWebLogic Serverインスタンスは、このメソッドを呼び出します。URLでは、SSLを基にした、WebLogic Server独自のプロトコルであるt3sプロトコルを指定します。SSLプロトコルは、2つのWebLogic Serverインスタンス間の接続および通信を保護します。

  • setSSLClientCertificate - SSL接続に使用する秘密鍵と証明書チェーンを指定します。このメソッドを使用して、秘密鍵(配列内の最初の入力ストリーム)とX.509証明書のチェーン(配列内の残りの入力ストリームを構成する)から成る入力ストリーム配列を指定します。証明書チェーン内の各証明書は、チェーン内の前の証明書の発行元です。

  • setSSLServerName - SSLサーバーとして機能するOracle WebLogic Serverインスタンスの名前を指定します。SSLサーバーがデジタル証明書をSSLクライアントとして機能するWebLogic Serverに提示すると、setSSLServerNameメソッドを使用して指定された名前がデジタル証明書内の一般名と比較されます。ホスト名検証が成功するためには、名前が一致する必要があります。このパラメータは、介入者攻撃を防ぐために使用されます。

  • setSSLRootCAFingerprint - 信頼性のある認証局のセットを表すデジタル・コード(つまり、信頼性のある証明書のフィンガープリントに基づく信頼)を指定します。SSLサーバーとして機能するWebLogic Serverインスタンスから受け取った証明書チェーンのルート証明書は、このメソッドで指定されたフィンガープリントのいずれかと一致しないと信頼を確立できません。このパラメータは、介入者攻撃を防ぐために使用されます。これにより、WebLogic Serverの信頼構成でWebLogic Serverで動作するクライアント用に指定されているデフォルト・レベルの信頼を補完できます。

    注意:

    JNDIのコンテキストとスレッドおよび潜在的なJNDIコンテキスト問題の予防方法の詳細は、Oracle WebLogic ServerのJNDIアプリケーションの開発でJNDIのコンテキストとスレッドと潜在的なJNDIコンテキスト問題の予防方法を参照してください。

例5-6 他のWebLogic Serverインスタンスへのセキュリティ保護された接続の確立

FileInputStream [] f = new FileInputStream[3]; 
   f[0]= new FileInputStream("demokey.pem");
   f[1]= new FileInputStream("democert.pem");
   f[2]= new FileInputStream("ca.pem");
Environment e = new Environment ();
e.setProviderURL("t3s://server2.weblogic.com:443");
e.setSSLClientCertificate(f);
e.setSSLServerName("server2.weblogic.com");
e.setSSLRootCAFingerprints("ac45e2d1ce492252acc27ee5c345ef26");

e.setInitialContextFactory
("weblogic.jndi.WLInitialContextFactory");
Context ctx = new InitialContext(e.getProperties())

例5-6では、WebLogic JNDI Environmentクラスは次のパラメータを格納するハッシュ表を作成します。

サーブレットで双方向SSL認証の使用

Javaクライアントをサーブレット(または他のサーバー側Javaクラス)で認証するには、クライアントがデジタル証明書を提供したかどうかをチェックする必要があります。提供した場合は、証明書が信頼できる認証局で発行されたかどうかをさらにチェックします。サーブレットの開発者には、Javaクライアントが有効なデジタル証明書を持っているかどうかを尋ねる責任があります。WebLogic Servlet APIでサーブレットを開発する場合、HTTPServletRequestオブジェクトの getAttribute()メソッドでSSL接続に関する情報にアクセスする必要があります。

以下の属性が、WebLogic Serverサーブレットでサポートされています。

  • javax.servlet.request.X509Certificate

  • java.security.cert.X509Certificate [] - X509証明書の配列を返します。

  • javax.servlet.request.cipher_suite - HTTPSが使用する暗号スイートを表す文字列を返します。

  • javax.servlet.request.key_size - 対称(バルク暗号化)キー・アルゴリズムのビット・サイズを表す整数(0、40、56、128、168)を返します。

  • weblogic.servlet.request.SSLSession

  • javax.net.ssl.SSLSession - 暗号スイートを含むSSLセッション・オブジェクト、およびSSLセッション・オブジェクトが作成された日付と最後に使用された日付を返します。

デジタル証明書に定義されているユーザー情報にアクセスできます。javax.servlet.request.X509Certificate属性を取得すると、情報はjava.security.cert.X509Certificate型の配列になっています。配列をその型にキャストして証明書を調べるだけで済みます。

デジタル証明書には、以下のような情報が指定されています。

  • サブジェクト(保持者、オーナー)の名前と、そのサブジェクトのIDを一意に確認するために必要なその他の識別情報

  • サブジェクトの公開鍵

  • デジタル証明書を発行した認証局の名前

  • シリアル番号

  • デジタル証明書の有効期間(存続期間)(開始日と終了日で定義)

カスタム・ホスト名検証の使用

ホスト名検証を使用すると、SSL接続先のホストが予定していた通信先、または許可された通信先であることを確認できます。ホスト名検証は、WebLogicクライアントまたはWebLogic Serverインスタンスが別のアプリケーション・サーバーのSSLクライアントとして動作している場合に便利です。介入者攻撃(man-in-the-middle attack)を防ぐのに役立ちます。

注意:

デモ用デジタル証明書はインストール時に生成されるので、WebLogic Serverソフトウェアがインストールされるシステムのホスト名を格納します。したがって、開発またはテスト目的でデモ用証明書を使用する場合は、ホスト名検証をオンのままにしておく必要があります。

WebLogic ServerのSSLハンドシェーク機能としてのデフォルトの動作は、SSLサーバーの証明書のサブジェクトDNにあるCNフィールドと、サーバーへの接続に使用するURL内のホスト名を比較することです。これらの名前が一致しない場合はSSL接続が中断されます。

SSL接続の中断は、サーバーのホスト名をサーバーのデジタル証明書と照らし合せて有効性を検証するSSLクライアントによって実行されます。デフォルト以外の動作が必要な場合は、ホスト名検証を無効にするか、カスタム・ホスト名検証を登録することができます。ホスト名検証を無効にすると、SSL接続は介入者攻撃に対して無防備な状態になります。

ホスト名検証は、次の方法で無効にできます。

  • WebLogic Server管理コンソールで、サーバー(たとえばmyserver)のキーストアおよびSSLタブの「詳細オプション」にある「ホスト名の検証」フィールドで「なし」を指定します。

  • SSLクライアントのコマンド・ラインで、次の引数を入力します。

-Dweblogic.security.SSL.ignoreHostnameVerification=true
 

カスタム・ホスト名検証を記述できます。weblogic.security.SSL.HostnameVerifierインタフェースではコールバック・メカニズムが提供されるため、このインタフェースを実装することで、URLのホスト名への接続を許可するかどうかについてのポリシーを指定できます。ポリシーは、証明書ベースにすることも、他の認証スキームに依存させることも可能です。

カスタム・ホスト名検証を使用するには、weblogic.security.SSL.HostnameVerifierインタフェースを実装するクラスを作成し、サーバーのセキュリティIDに関する情報を取得するメソッドを定義します。

注意:

このインタフェースは新しいスタイルの証明書を受け取り、非推奨になったweblogic.security.SSL.HostnameVerifierJSSEインタフェースにかわるものです。

カスタム・ホスト名検証を使用する前に、次に示す方法で実装するクラスを指定する必要があります。

  • WebLogic Server管理コンソールで、「サーバー構成」の「SSL」タブのSSL.HostName検証フィールドに、このインタフェースを実装するクラスの名前を指定します。指定するクラスには、引数を取らないパブリック・コンストラクタが必要です。

  • コマンド・ラインに、次の引数を入力します。

-Dweblogic.security.SSL.hostnameVerifier=hostnameverifier 

hostnameverifierの値は、カスタム・ホスト名検証を実装するクラスの名前です。

例5-7は、NulledHostnameVerifierサンプルの抜粋コードです。完全なサンプルは、NulledHostnameVerifier.javaファイルのEXAMPLES_HOME\src\examples\security\sslclientディレクトリにあります。EXAMPLES_HOMEディレクトリは、ORACLE_HOME\wlserver\samples\serverにあります。このサンプル・コードには、比較のために常にtrueを返すNulledHostnameVerifierクラスが含まれています。このサンプルでは、WebLogic SSLクライアントは、サーバーのホスト名とデジタル証明書のSubjectDNとの比較に関係なく、どのSSLサーバーにも接続できます。

例5-7 ホスト名検証のサンプル・コードの抜粋

public class NulledHostnameVerifier implements
                     weblogic.security.SSL.HostnameVerifier {
  public boolean verify(String urlHostname, javax.net.ssl.SSLSession session) {
    return true;
  }
}

トラスト・マネージャの使い方

weblogic.security.SSL.TrustManagerインタフェースは以下を可能にします。

  • 特定の証明書検証エラーを無視します

  • ピア証明書チェーンに対して追加の検証を実行します

    注意:

    このインタフェースは新しいスタイルの証明書を受け取り、非推奨になったweblogic.security.SSL.TrustManagerJSSEインタフェースにかわるものです。

SSLクライアントがWebLogic Serverのインスタンスに接続すると、サーバーは認証のためにデジタル証明書チェーンをクライアントに提示します。提示されたチェーンに無効なデジタル証明書が含まれている場合もあります。SSL仕様では、クライアントが無効な証明書を検出した場合、SSL接続が中断されることになっています。TrustManagerインタフェースのカスタム実装を使用すると、どのような場合にSSLハンドシェークを継続するか(または中止するか)を制御できます。トラスト・マネージャを使用することで、特定の検証エラーを無視(必要に応じてカスタム検証チェックを実行)してから、ハンドシェークを継続するかどうかを決定できます。

トラスト・マネージャを作成するには、weblogic.security.SSL.TrustManagerインタフェースを使用します。このインタフェースには、証明書検証で使用する一連のエラー・コードが含まれています。また、必要に応じて、ピア証明書での付加的な検証を実行したり、SSLハンドシェークを中断したりできます。デジタル証明書の検証が済むと、weblogic.security.SSL.TrustManagerインタフェースがコールバック関数を使用して、デジタル証明書の検証結果をオーバーライドします。トラスト・マネージャのインスタンスは、setTrustManager()メソッドを使用してSSLコンテキストに関連付けることができます。

トラスト・マネージャはプログラムでのみ設定できます。その使用は、WebLogic Server管理コンソールやコマンド・ラインでは定義できません。

注意:

実行する検証によっては、トラスト・マネージャを使用するとパフォーマンスに影響します。

例5-8は、NulledTrustManagerサンプルの抜粋コードです。完全なサンプルは、NulledTrustManager.javaファイルのEXAMPLES_HOME\src\examples\security\sslclientディレクトリにあります。EXAMPLES_HOMEディレクトリは、ORACLE_HOME\wlserver\samples\serverにあります。SSLSocketClientサンプルでは、カスタム・トラスト・マネージャを使用します。SSLSocketClientでは、トラスト・マネージャでSSLコンテキストを使用して新しいSSL接続を設定する方法が示されています。

例5-8 NulledTrustManagerサンプル・コードの抜粋

package examples.security.sslclient;

import weblogic.security.SSL.TrustManager;
import java.security.cert.X509Certificate;
...
public class NulledTrustManager implements TrustManager{ 
  public boolean certificateCallback(X509Certificate[] o, int validateErr) {
   System.out.println(" --- Do Not Use In Production ---\n" + 
                          " By using this NulledTrustManager, the trust in" +
                            " the server's identity is completely lost.\n" +                           " --------------------------------");
   for (int i=0; i<o.length; i++)
     System.out.println(" certificate " + i + " -- " + o[i].toString());
   return true;
  }
}

証明書パス・トラスト・マネージャの使い方

CertPathTrustManager (weblogic.security.SSL.CertPathTrustManager)は、デフォルトのセキュリティ・レルムの構成済み証明書パス検証プロバイダを使用して、失効チェックなどの追加的な検証を実行します。

デフォルトでは、サーバーのアウトバウンドSSLで使用するアプリケーション・コードからは、組込みのSSL証明書検証にしかアクセスできません。しかし、管理者がサーバーに構成した追加の証明書検証にアクセスするために、アプリケーション・コードでCertPathTrustManagerを指定することは可能です。アプリケーション・コードにおいて証明書パス検証プロバイダも実行する場合は、アプリケーション・コードでCertPathTrustManagerを使用する必要があります。

このクラスは、以下の3つの方法で使用できます。

  • アウトバウンドSSLで検証プロバイダを使用することを示すスイッチがSSLMBeanに設定されている場合にのみ、Trust Managerが構成済みのCertPathValidatorsを呼び出します。つまり、管理者が構成したものに、検証を完全に委任することになります。この方法には、setUseConfiguredSSLValidation()メソッドを使用します。これがデフォルトです。

  • Trust Managerが常に構成済みのCertPathValidatorsを呼び出します。この方法には、setBuiltinSSLValidationAndCertPathValidators()メソッドを使用します。

  • Trust Managerは構成済みのCertPathValidatorsを呼び出しません。この方法には、setBuiltinSSLValidationOnly()メソッドを使用します。

ハンドシェーク完了リスナーの使い方

javax.net.ssl.HandshakeCompletedListenerは、指定されたSSL接続に対するSSLプロトコル・ハンドシェークの完了についてSSLクライアントが通知を受け取る方法を定義します。例5-9は、MyListenerサンプルの抜粋コードです。完全なサンプルは、MyListener.javaファイルのEXAMPLES_HOME\src\examples\security\sslclientディレクトリにあります。EXAMPLES_HOMEディレクトリは、ORACLE_HOME\wlserver\samples\serverにあります。

例5-9 MyListener (HandshakeCompletedListener)サンプル・コードの抜粋

package examples.security.sslclient;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileInputStream;
import javax.net.ssl.HandshakeCompletedListener;
import java.util.Hashtable;
import javax.net.ssl.SSLSession;
...
  public class MyListener implements HandshakeCompletedListener
  {
    public void handshakeCompleted(javax.net.ssl.HandshakeCompletedEvent
                                          event)
    {
      SSLSession session = event.getSession();
      System.out.println("Handshake Completed with peer " +
                               session.getPeerHost());
      System.out.println("   cipher: " + session.getCipherSuite());
      Certificate[] certs = null;
      try
      {
        certs = session.getPeerCertificates();
      }
      catch (SSLPeerUnverifiedException puv)
      {
        certs = null;
      }
      if  (certs != null)
      {
        System.out.println("   peer certificates:");
        for (int z=0; z<certs.length; z++) 
                 System.out.println("      certs["+z+"]: " + certs[z]);
      }
      else
      {
        System.out.println("No peer certificates presented");
      }
    }
  }

SSLContextの使い方

SSLContextクラスを使用すると、SSLをプログラムによって構成し、SSLセッション情報を保持できます。各インスタンスは、認証の実行に使用するキー、証明書チェーン、および信頼性のあるCA証明書を使用して構成できます。同じSSLContextで作成し、同じSSLサーバーへの接続に使用するSSLソケットは、SSLセッション情報を再利用できます。セッション情報が実際に再利用されるかどうかは、SSLサーバーによって異なります。

セッション・キャッシングの詳細は、Oracle WebLogic Serverセキュリティの管理のSSLセッション動作に関する項を参照してください。トラスト・マネージャ・クラスのインスタンスをSSLコンテキストと関連付けるには、weblogic.security.SSL.SSLContext.setTrustManager()メソッドを使用します。

SSLコンテキストは、プログラムでのみ設定できます。WebLogic Server管理コンソールやコマンド・ラインでは設定できません。SSLContextオブジェクトは、Javaのnew式またはSSLContextクラスのgetInstance()メソッドで作成できます。getInstance()メソッドは静的で、指定されたセキュア・ソケット・プロトコルを実装する新しいSSLContextオブジェクトを生成します。SSLContextクラスの使用例は、EXAMPLES_HOME\src\examples\security\sslclientSSLSocketClient.javaサンプルで提供されます。EXAMPLES_HOMEは、WebLogic Serverのサンプル・コードが構成されているディレクトリで、ORACLE_HOME\wlserver\samples\serverにあります。SSLSocketClientサンプルでは、SSLContextを使って新しいSSLソケットを作成する新しいSSLソケット・ファクトリを作成する方法が示されています。

例5-10は、getInstance()メソッドを使用したインスタンス化のサンプルです。

例5-10 SSLコンテキストのサンプル・コード

import weblogic.security.SSL.SSLContext;
  SSLcontext sslctx = SSLContext.getInstance ("https")

URLを使用したアウトバウンドSSL接続

URLオブジェクトを使用すると、クライアントとして機能しているWebLogic Serverインスタンスから別のWebLogic ServerインスタンスへのアウトバウンドSSL接続を確立することができます。WebLogic Serverは、アウトバウンドSSL接続について一方向と双方向のSSL認証を両方ともサポートしています。

一方向SSL認証の場合は、java.net.URLjava.net.URLConnection、およびjava.net.HTTPURLConnectionクラスを使用して、URLオブジェクトを使用するアウトバウンドSSL接続を確立します。例5-11は、HTTPおよびHTTPSのURLを両方ともサポートし、これらのJavaクラスのみを使用する(つまりWebLogicクラスは不要)simpleURLクラスを示しています。WebLogic Serverで一方向SSL認証(HTTPS)にsimpleURLクラスを使用するための必要条件は、java.protocols.handler.pkgsのシステム・プロパティで「weblogic.net」が定義されていることだけです。

注意:

例5-11 simpleURLサンプルは、デフォルトで信頼性とホスト名をチェックするため、このサンプルでは信頼されていてホスト名チェックを通過する実際のWebサーバーにデフォルトで接続する必要があります。そうしない場合は、コマンド・ライン上で信頼性とホスト名チェックをオーバーライドする必要があります。

例5-11 Javaクラスのみを使用する一方向SSL認証URLアウトバウンドSSL接続クラス

import java.net.URL;
import java.net.URLConnection;
import java.net.HttpURLConnection;
import java.io.IOException;
public class simpleURL
{
   public static void main (String [] argv)
   {
     if (argv.length != 1)
     {
       System.out.println("Please provide a URL to connect to");
       System.exit(-1);
     }
     setupHandler();
     connectToURL(argv[0]);
   }
   private static void setupHandler()
   {
     java.util.Properties p = System.getProperties();
     String s = p.getProperty("java.protocol.handler.pkgs");
     if (s == null)
       s = "weblogic.net";
     else if (s.indexOf("weblogic.net") == -1)
       s += "|weblogic.net";
     p.put("java.protocol.handler.pkgs", s);
     System.setProperties(p);
   }
   private static void connectToURL(String theURLSpec)
   {
     try
     {
       URL theURL = new URL(theURLSpec);
       URLConnection urlConnection = theURL.openConnection();
       HttpURLConnection connection = null;
       if (!(urlConnection instanceof HttpURLConnection))
       {
         System.out.println("The URL is not using HTTP/HTTPS: " +
                              theURLSpec);
         return;
       }
       connection = (HttpURLConnection) urlConnection;
       connection.connect();
       String responseStr = "\t\t" +
              connection.getResponseCode() + " -- " +
              connection.getResponseMessage() + "\n\t\t" +
                   connection.getContent().getClass().getName() + "\n";
       connection.disconnect();
       System.out.println(responseStr);
     }
     catch (IOException ioe)
     {
       System.out.println("Failure processing URL: " + theURLSpec);
       ioe.printStackTrace();
     }
   }
}

双方向SSL認証の場合は、weblogic.net.http.HttpsURLConnectionクラスを使用して、秘密鍵とデジタル証明書を含む、クライアントのセキュリティ・コンテキスト情報を指定できます。このクラスのインスタンスは、リモート・オブジェクトに対するHTTPS接続を表しています。

SSLClientサンプル・コード(例5-12)には、WebLogic URLオブジェクトを使用して、アウトバウンドSSL接続を確立する方法が示されています。例5-12のサンプル・コードは、EXAMPLES_HOME\src\examples\security\sslclientディレクトリのSSLClient.javaファイルからの抜粋です。EXAMPLES_HOMEディレクトリは、ORACLE_HOME\wlserver\samples\serverにあります。

例5-12 WebLogic双方向SSL認証URLアウトバウンドSSL接続のサンプル・コード

wlsUrl = new URL("https", host, Integer.valueOf(sport).intValue(),
                 query);
weblogic.net.http.HttpsURLConnection sconnection =
         new weblogic.net.http.HttpsURLConnection(wlsUrl);
...
InputStream [] ins = new InputStream[2];
      ins[0] = new FileInputStream("clientkey.pem");
      ins[1] = new FileInputStream("client2certs.pem");
       String pwd = "clientkey";
      sconnection.loadLocalIdentity(ins[0], ins[1], pwd.toCharArray());

SSLクライアントのサンプル・コード

WebLogic Server製品では、完全で実践的なSSL認証サンプルを提供します。WebLogic Serverによって提供されるサンプルは、EXAMPLES_HOME\src\examples\security\sslclientにあります。EXAMPLES_HOMEは、WebLogic Serverのサンプル・コードが構成されているディレクトリで、ORACLE_HOME\wlserver\samples\serverにあります。このサンプルの説明と、構築、構成、および実行の手順については、サンプル・ディレクトリのpackage.htmlファイルを参照してください。このサンプル・コードは、修正して再利用できます。