ヘッダーをスキップ
Oracle® Fusion Middlewareアプリケーション・セキュリティ・ガイド
11gリリース1(11.1.1)
B56235-02
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

15 認証の開発

この章はJavaSEアプリケーションのみに適用されます。JavaEEアプリケーションの認証については、他のOracle WebLogicドキュメントへのリンクが記載されています。

この章の内容は次のとおりです。

この情報を使用する前に、これらのAPIが使用されているコンテキストに精通しておくことを強くお薦めします。詳細は、第13.3.2項「OPSS APIによる認証」を参照してください。

15.1 JavaEEアプリケーションの認証トピックへのリンク

次にあげるドキュメントは、JavaEEアプリケーションの認証開発に役立つ情報ソースです。

15.2 JavaSEアプリケーション向け認証の開発

この項の内容は次のとおりです。

JavaSEアプリケーション向け認可の構成の詳細は、第17.4項「JavaSEアプリケーションに対するポリシー・ストアと資格証明ストアの構成」を参照してください。

15.2.1 アイデンティティ・ストア

認証とは、コール元が特定のユーザーまたはシステムの代理として機能していることを証明するメカニズムです。認証は、名前/パスワードの組合せなどのデータを使用して、相手が誰であるかという質問に答えます。アイデンティティ・ストアはアイデンティティ・データの格納場所を示す抽象的概念であり、認証プロバイダはアイデンティティ・ストアにアクセスするための手段です。

アプリケーションがOPSSセキュリティ・ストア(アイデンティティ・ストア、ポリシー・ストアまたは資格証明ストア)から情報を取得して、そのコンテンツを管理するときに、OPSS APIが使用されます。この方法を次の図に示します。

アプリケーションからセキュリティ・ストアへのデータのフロー

15.2.2 JavaSEアプリケーションでのLDAPアイデンティティ・ストアの構成

JavaSEアプリケーションは、次のスニペットに示すように、<serviceProvider><serviceInstance>および<jpsContext>の各要素を含むファイルjps-config-jse.xmlに構成されたLDAPベースのアイデンティティ・ストアを使用できます。

<serviceProviders>
  <serviceProvider type="IDENTITY_STORE" name="idstore.ldap.provider" class="oracle.security.jps.internal.idstore.ldap.LdapIdentityStoreProvider">
    <description>Prototype LDAP-based ID store</description>
  </serviceProvider>
</serviceProviders>

<serviceInstances>
 <serviceInstance name="idstore.ldap" provider="idstore.ldap.provider">
   <property name="idstore.type" value="OID"/>
   <property name="security.principal.alias" value="MyCredentialMapName"/>
   <property name="security.principal.key" value="MyCredentialMapKey"/>
   <property name="ldap.url" value="${LDAP_URI}"/>
   <property name="max.search.filter.length" value="500"/>
   <extendedProperty>
     <name>user.search.bases</name>
     <values>
       <value>cn=users,dc=us,dc=oracle,dc=com</value>
     </values>
   </extendedProperty>
   <extendedProperty>
     <name>group.search.bases</name>
     <values>
       <value>cn=groups,dc=us,dc=oracle,dc=com</value>
      </values>
   </extendedProperty>
 </serviceInstance>
</serviceInstances>

<jpsContexts default="ldap_idstore">
  <jpsContext name="ldap_idstore">
    <serviceInstanceRef ref="idstore.ldap"/>
  </jpsContext>

  <jpsContext name="bootstrap_credstore_context">
     <serviceInstanceRef ref="bootstrap.cred"/>  
   </jpsContext>
</jpsContexts>

次の点に注意してください。

  • <serviceInstance>の名前(この例では<idstore.ldap>)には任意の値を指定できますが、要素<serviceInstanceRef>で参照されるインスタンスと一致している必要があります。

  • <serviceProvider>の名前(この例では<idstore.ldap.provider>)には任意の値を指定できますが、要素<serviceInstance>内のプロバイダと一致している必要があります。

  • 指定したスクリプトを使用してプロバイダ・インスタンスにプロパティを追加するには、付録E「WLSTスクリプトを使用したOPSSサービス・プロバイダ・インスタンスの構成」を参照してください。

  • アイデンティティLDAPストアにアクセスするための資格証明は、インスタンス・プロパティのsecurity.principal.keyおよびsecurity.principal.aliasで指定し、ブートストラップ資格証明ストアに格納します。

15.2.3 JavaSEアプリケーション向けにサポートされるログイン・モジュール

ログイン・モジュールは、ユーザーを認証し、サブジェクトにプリンシパルを移入するコンポーネントです。このプロセスは、2つの異なる段階で行われます。第一段階では、ログイン・モジュールによって要求元のユーザー(必要に応じて名前、パスワードまたはその他の資格証明データ)の認証が試みられます。第一段階が成功した場合にのみ、第二段階が呼び出されます。第二段階では、ログイン・モジュールによって、関連プリンシパルがサブジェクトに割り当てられ、最終的にそれが権限が付与されたアクションを実行するために使用されます。

15.2.3.1 アイデンティティ・ストアのログイン・モジュール

JavaSEアプリケーションではログイン・モジュールのスタックを使用してユーザーを認証でき、各モジュールではスタック内の他のモジュールとは無関係に独自の計算を実行できます。これらのサービスおよびその他のサービスは、ファイルjps-config-jse.xmlで指定されます。

OPSS APIには、インタフェースoracle.security.jps.service.login.LoginServiceが組み込まれており、これによってJavaSEアプリケーションはスタック内のすべてのログイン・モジュールを呼び出せるだけでなく、それらのサブセットを指定の順序で呼び出すことができます。

LoginServiceインタフェースのメソッドLoginContextに渡されるjpsコンテキスト(構成ファイルjps-config-jse.xmlに定義されたもの)の名前によって、アプリケーションが使用するログイン・モジュールのスタックが判別されます。

標準のJAAS API LoginContextを使用して、デフォルトのコンテキストで定義されたログイン・モジュールを呼び出すこともできます。

JPSコンテキストによってスタックにログイン・モジュールがリストされる順序は重要です。それは、認証アルゴリズムでは、モジュールのセキュリティ・レベルを特定するフラグ(required、sufficient、requisite、optional)などのデータに加えてこの順序が考慮されるためです。

すぐに使用できるアイデンティティ・ストア・サービスはファイルベースであり、そのコンテンツはファイルsystem-jazn-data.xmlでプロビジョニングされていますが、LDAPベースのアイデンティティ・ストアとして再構成することも可能です。

OPSSは、アイデンティティ・ストアのログイン・モジュールをJavaSEアプリケーション内でサポートしているため、これを認証またはIDアサーションに使用することができます。

アイデンティティ・ストアのログイン・モジュール

このログイン・モジュールに関連付けられているクラスは、次のとおりです。

oracle.security.jps.internal.jaas.module.idstore.IdStoreLoginModule

このモジュールのインスタンスは、次のコード断片に示すように、ファイルjps-config-jse.xmlに構成されます。

<serviceInstance name="idstore.loginmodule" provider="jaas.login.provider">
  <description>Identity Store Login Module</description>
  <property name="loginModuleClassName" value="oracle.security.jps.internal.jaas.module.idstore.IdStoreLoginModule"/>
  <property name="jaas.login.controlFlag" value="REQUIRED"/>
</serviceInstance>

このログイン・モジュールに固有のプロパティは、次のとおりです。

remove.anonymous.role (defaults to true)
add.application.role (defaults to true)

15.2.3.2 認証のためのアイデンティティ・ストア・ログイン・モジュールの使用

この項では、基本的なユーザー名とパスワードの認証のためのアイデンティティ・ストア・ログイン・モジュールの使用方法を示します。

IdStoreLoginModuleの起動

次のコード断片は、コールバック・ハンドラとコンテキストの設定方法を示しています。

import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;

Subject sub = new Subject();
CallbackHandler cbh = new YourCallbackHandler();
LoginContext context = new LoginContext(appName, subject,  cbh);
context.login();

コールバック・ハンドラでは、NameCallbackPasswordCallbackを処理できる必要があります。

jps-config-jse.xmlの構成

次のjps-config-jse.xmlの断片は、コンテキストappNameの構成を示しています。

<jpsContext name="appName">
   <serviceInstanceRef ref="jaaslm.idstore1"/>
</jpsContext>

<serviceProvider type="JAAS_LM" name="jaaslm.idstore" 
      class="oracle.security.jps.internal.jaas.module.idstore.IdStoreLoginModule">
   <description>Identity Store-based LoginModule
   </description>
</serviceProvider>

<serviceInstance name="jaaslm.idstore1" provider="jaaslm.idstore">
   <property name="jaas.login.controlFlag" value="REQUIRED"/>
   <property name="debug" value="true"/>
   <property name="addAllRoles" value="true"/>
</serviceInstance>

コールバック・ハンドラの書込み

次のコード・スニペットは、コールバック・ハンドラで名前とパスワードのコールバックを処理できることを示しています。

import javax.security.auth.callback.*;
import java.io.IOException; 
public class SampleCallbackHandler implements CallbackHandler {
//For name/password callbacks
private String name = null;private char[] password = null; 
public SampleCallbackHandler(String name, char[] pwd) { 
   if (name == null || name.length() == 0 )         
      throw new IllegalArgumentException("Invalid name ");
   else 
      this.name = name; 
   if (pwd == null || pwd.length == 0)
      throw new IllegalArgumentException("Invalid password ");
   else
      this.password = pwd;
}
public String getName() {
   return name;
   } public char[] getPassword()  {
   return password;
 }    
public void handle(Callback[] callbacks) 
   throws IOException, UnsupportedCallbackException {
   if (callbacks != null && callbacks.length > 0) {
      for (Callback c : callbacks) {
      if (c instanceof NameCallback) {
            ((NameCallback) c).setName(name);
            } 
   else 
      if (c instanceof PasswordCallback) {
         ((PasswordCallback) c).setPassword(password);
              }           
   else {
      throw new UnsupportedCallbackException(c);
 }
          }
      }
  }
}

15.2.3.3 アサーションのためのアイデンティティ・ログイン・モジュールの使用

アイデンティティ・ストアのログイン・モジュールをアサーションのために使用するには、開発者は次の処理を行う必要があります。

  • IdentityAssertionパーミッションに実行アクションを設定して、パーミッションoracle.security.jps.JpsPermissionがアサーションのためにログイン・モジュールを実行できるようにします。

  • クラスoracle.security.jps.callback.IdentityCallbackを拡張するコールバック・ハンドラを実装します。

この2つの要件を次のコードおよび構成サンプルに示します。

JpsPermissionのプロビジョニング

次の構成サンプルでは、必須JpsPermissionがアサーション・ログイン・モジュールを実行できるようにコードMyAppに権限を与えています。

<grant>
  <grantee>
    <codesource>
      <url>file:${domain.home}/servers/MyApp/-</url>
    </codesource>
  </grantee>
  <permissions>
    <permission>
      <class>oracle.security.jps.JpsPermission</class>
      <name>IdentityAssertion</name>
      <actions>execute</actions>
    </permission>
  </permissions>
</grant>

次の構成サンプルでは、必須JpsPermissionがアサーション・ログイン・モジュールを実行できるようにプリンシパルjdoeに権限を与えています。

<grant>
  <grantee>
    <principals>
      <principal>
        <class>weblogic.security.principal.WLSUserImpl</class>
        <name>jdoe</name>
      </principal>
    </principals>
  </grantee>
  <permissions>
    <permission>
      <class>oracle.security.jps.JpsPermission</class>
      <name>IdentityAssertion</name>
      <actions>execute</actions>
    </permission>
  </permissions>
</grant>

CallbackHandlerの実装

次のコード断片は、ハンドラおよびメソッド・ハンドルの実装とそれをインスタンス化する方法を示しています。

import oracle.security.jps.callback.IdentityCallback;
import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
 
class MyAssertionCallbackHandler extends CallbackHandler {
        private String name = null;
 
        public MyAssertionCallbackHandler(String name) {
          this.name = name;
        }
 
        public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
            for (Callback callback : callbacks) {
                if (callback instanceof IdentityCallback) {
                    IdentityCallback idcb = (IdentityCallback) callback;
                    idcb.setIdentity(name);
                } else {
                    //throw exception
                }
            }
        }
}
 
CallbackHandler cbh = new  MyAssertionCallbackHandler("name");
Subject sub = new Subject();

// The first parameter must be the name of the jpsContext in which the
// IdStore Login Module is referrenced
LoginContext context = new LoginContext("myContext", sub,  cbh);

context.login();
Subject s = context.getSubject();
...

15.2.4 JavaSEアプリケーションでのOPSS API LoginServiceの使用

JavaSEアプリケーションでログイン・モジュールをプログラムによって呼び出すには、インタフェースoracle.security.jps.service.login.LoginServiceのメソッドgetLoginContextを使用します。

標準JAAS APIのメソッドLoginContextと同様に、getLoginContextは、ユーザーを認証するために使用できるLoginContextオブジェクトのインスタンスを返しますが、これによって、任意の順序で任意の数のログイン・モジュールを使用することもできます。これらのログオン・モジュールのみに対して、それらが渡された順序で認証が実行されます。

次のコード断片は、ログイン・モジュールのサブセットに対するユーザー認証が、指定された順序で、getLoginContextを使用して実行されることを示しています。

import oracle.security.jps.service.ServiceLocator;
import oracle.security.jps.service.JpsServiceLocator;
import oracle.security.jps.service.login.LoginService;

//Obtain the login service
ServiceLocator locator = JpsServiceLocator.getServiceLocator();
LoginService loginService = locator.lookup(LoginService.class);

//Create the handler for given name and password
CallbackHandler cbh = new MyCallbackHandler("name", "password".toCharArray());

//Invoke login modules selectively in a given order
selectiveModules = new Sting[]{"lmName1", "lmName2", "lmName3"};
LoginContext ctx = loginService.getLoginContext(new Subject(), cbh, selectiveModules);
ctx.login();
Subject s = ctx.getSubject();

selectiveModulesは、(ログイン・モジュールの)名前の配列であり、認証では、その配列内で名前を指定されたログイン・モジュールが配列内にリストされた順序で使用されます。配列内のそれぞれの名前は、ファイルjps-config-jse.xmlのデフォルトのコンテキストにリストされたサービス・インスタンスの名前にする必要があります。

次のコード断片は、2つのログイン・モジュールからなるスタックの構成を示しています。

<serviceProvider type="LOGIN" name="jaas.login.provider" class="oracle.security.jps.internal.login.jaas.JaasLoginServiceProvider">
   <description>Common definition for any login module instances</description>
</serviceProvider>

<serviceInstance name="auth.loginmodule" provider="jaas.login.provider">
   <description>User Authentication Login Module</description>
   <property name="loginModuleClassName" value="oracle.security.jps.internal.jaas.module.authentication.JpsUserAuthenticationLoginModule"/>
   <property name="jaas.login.controlFlag" value="REQUIRED"/>
</serviceInstance>
 
<serviceInstance name="custom.loginmodule" provider="jaas.login.provider">
   <description>My Custom Login Module</description>
   <property name="loginModuleClassName" value="my.custom.MyLoginModuleClass"/>
   <property name="jaas.login.controlFlag" value="REQUIRED"/>
</serviceInstance>
 
<jpsContexts default="aJpsContext">
   <jpsContext name="aJpsContext">
     <serviceInstanceRef ref="auth.loginmodule"/>
     <serviceInstanceRef ref="custom.loginmodule"/>
   </jpsContext>
</jpsContexts>