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

前
 
次
 

22 Java SEアプリケーションの認証

この章の情報はJava SEアプリケーションにのみ適用され、Java SEアプリケーションの開発者を対象読者としています。Java EEアプリケーションの認証の詳細は、「Java EEアプリケーションの認証トピックへのリンク」にリストされているドキュメントを参照してください。

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

22.1 Java EEアプリケーションの認証トピックへのリンク

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

22.2 Java SEアプリケーションの認証

この項では、Java SEアプリケーションに対するアイデンティティ・ストアのサポートについて説明します。内容は次のとおりです。

Java SEアプリケーションでの認可の詳細は、第23.1項「Java SEアプリケーションでのポリシー・ストアと資格証明ストアの構成」を参照してください。

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

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

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

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

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

Java SEアプリケーションは、次のスニペットに示すように、<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で指定し、ブートストラップ資格証明ストアに格納します。

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

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

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

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

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

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

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

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

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

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

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

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

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)

22.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);
 }
          }
      }
  }
}

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

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

  • コール元が保護されたメソッドsetIdentityを実行するための適切なパーミッションを提供します。これには、IdentityAssertionという名前を持つパーミッションoracle.security.jps.JpsPermissionを付与することが必要になります。

  • 次のコード・サンプルに示すようなクラスoracle.security.jps.callback.IdentityCallbackを使用するコールバック・ハンドラを実装します。

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

JpsPermissionのプロビジョニング

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

<grant>
  <grantee>
    <codesource>
      <url>file:${soa.oracle.home}/application/myApp.ear</url>
                      <--! soa.oracle.home is a system property set when 
      the server JVM is started -->
    </codesource>
  </grantee>
  <permissions>
    <permission>
      <class>oracle.security.jps.JpsPermission</class>
      <name>IdentityAssertion</name>
    </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>
    </permission>
  </permissions>
</grant>

CallbackHandlerの実装

次のコード部分は、コールバック・ハンドラの実装を示しています。

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
 
import oracle.security.jps.callback.IdentityCallback;
 
public class CustomCallbackHandler implements CallbackHandler {
    private String name = null;
    private char[] password;
 
    public CustomCallbackHandler(String name) {
        this.name = name;
    }
    
    public CustomCallbackHandler(String name, char[] password) {
      this.name  = name;
      this.password = password;
    }
 
    public void handle(Callback[] callbacks) throws IOException,
                                                    UnsupportedCallbackException {
        for (Callback callback : callbacks) {
            if (callback instanceof NameCallback) {
              NameCallback nc = (NameCallback) callback;
              nc.setName(name);
            }
            else if (callback instanceof PasswordCallback) {
              PasswordCallback pc = (PasswordCallback) callback;
              pc.setPassword(password);
            }
            else if (callback instanceof IdentityCallback) {
                IdentityCallback idcb = (IdentityCallback)callback;
                idcb.setIdentity(name);
                idcb.setIdentityAsserted(true);
                idcb.setAuthenticationType("CUSTOM");
            } else {
                //throw exception
                throw new UnsupportedCallbackException(callback);
            }
        }
    }
}

次のコード部分は、ログイン・モジュールの実装を示しています。

import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.LoginContext;
 
import oracle.security.jps.service.JpsServiceLocator;
import oracle.security.jps.service.login.LoginService;
 
public class LoginModuleExample {
    private static final String CONTEXT_NAME = "JSE_UserAuthnAssertion";
 
    public LoginModuleExample() {
        super();
    }
 
    public Subject assertUser(final String username) throws Exception {
        CallbackHandler cbh =
            AccessController.doPrivileged(new PrivilegedExceptionAction<CallbackHandler>() {
                public CallbackHandler run() throws Exception {
                    return new CustomCallbackHandler(username);
                }
            });
        Subject sub = new Subject();
        LoginService ls =
            JpsServiceLocator.getServiceLocator().lookup(LoginService.class);
        LoginContext context = ls.getLoginContext(sub, cbh);
 
        context.login();
        Subject s = context.getSubject();
 
        return s;
    }
 
    public Subject authenticate(final String username, final char[] password) throws Exception {
        CallbackHandler cbh = new CustomCallbackHandler(username, password);
        Subject sub = new Subject();
        LoginService ls =
            JpsServiceLocator.getServiceLocator().lookup(LoginService.class);
        LoginContext context = ls.getLoginContext(sub, cbh);
 
        context.login();
        Subject s = context.getSubject();
 
        return s;
    }
 
    public static void main(String[] args) {
        LoginModuleExample loginModuleExample = new LoginModuleExample();
        try {
            System.out.println("authenticated user subject = " + 
                               loginModuleExample.authenticate("testUser", 
 "welcome1".toCharArray()));
            System.out.println("asserted user subject = " +
                               loginModuleExample.assertUser("testUser"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

22.2.4 Java SEアプリケーションでのOPSS API LoginServiceの使用方法

Java SEアプリケーションでログイン・モジュールをプログラムによって呼び出すには、インタフェース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>

22.3 構成例

この項では、次のアーティファクトの構成を示します。

XMLのポリシー・ストアおよび資格証明ストアの構成

次のスニペットは、XMLベースのポリシー・ストアおよび資格証明ストアの構成を示しています。XMLベースのポリシー・ストアのコンテンツは、ファイルsystem-jazn-data.xmlに指定されています。XMLベースの資格証明ストアのコンテンツは、ファイルcwallet.ssoに指定されています。

<serviceProviders> <serviceProvider class="oracle.security.jps.internal.policystore.xml.XmlPolicyStoreProvider" name="policystore.xml.provider" type="POLICY_STORE">
  <description>XML-based PolicyStore Provider</description>
 </serviceProvider>

 <serviceProvider class="oracle.security.jps.internal.credstore.ssp.SspCredentialStoreProvider" name="credstoressp" type="CREDENTIAL_STORE">
  <description>SecretStore-based CSF Provider</description>
 </serviceProvider>
</serviceProviders>

<serviceInstances>
 <serviceInstance location="./" provider="credstoressp" name="credstore">
  <description>File-based Credential Store Service Instance</description>
 </serviceInstance>

<serviceInstance location="./system-jazn-data.xml" provider="policystore.xml.provider" name="policystore.xml">
   <description>File-based Policy Store Service Instance</description>
 </serviceInstance>
</serviceInstances>

XMLのアイデンティティ・ストアの構成

次のスニペットは、XMLベースのアイデンティティ・ストアの構成を示しています。XMLベースのアイデンティティ・ストアのコンテンツは、ファイルsystem-jazn-data.xmlに指定されています。

<serviceProvider
  class="oracle.security.jps.internal.idstore.xml.XmlIdentityStoreProvider"
  name="idstore.xml.provider" 
  type="IDENTITY_STORE">
 <description>XML-based Identity Store Service Provider</description>
</serviceProvider>

<serviceInstance 
  location="./system-jazn-data.xml" provider="idstore.xml.provider"
  name="idstore.xml">
 <description>File Based Identity Store Service Instance</description>
 <property value="jazn.com" name="subscriber.name"/>
</serviceInstance>

LDAPのアイデンティティ・ストアの構成

次のスニペットは、LDAPベースのアイデンティティ・ストアの構成を示しています。このアイデンティティ・ストアには、LDAPサーバーにアクセスするためのブートストラップ資格証明の必須構成が含まれています。サービス・インスタンス・プロパティidstore.typeでは、使用するLDAPに応じて、次の値を設定できます。

表22-1 Idstoreのタイプ

サポートされているLDAP Idstore.typeの値

Oracle Internet Directory 10gおよび11g

OID

Oracle Virtual Directory 10gおよび11g

OVD

Sun Java System Directory Server 6.3

IPLANET

Active Directory 2003、2008

ACTIVE_DIRECTORY

Novell eDirectory 8.8

EDIRECTORY

Oracle Directory Server Enterprise Edition 11gR1 (11.1.1.3+)

IPLANET

IBM Tivoli DS 6.2

OPEN_LDAP

OpenLDAP 2.2。

OPEN_LDAP


  <serviceProvider
   class="oracle.security.jps.internal.idstore.ldap.LdapIdentityStoreProvider"
   name="idstore.ldap.provider" type="IDENTITY_STORE">
         <description>LDAP-based Identity Store Service Provider</description>
</serviceProvider>

<serviceProvider
   class="oracle.security.jps.internal.credstore.ssp.SspCredentialStoreProvider"
   name="credstoressp" type="CREDENTIAL_STORE">
 <description>SecretStore-based CSF Provider</description>
</serviceProvider>
 
<serviceInstance name="idstore.oid" provider="idstore.ldap.provider">
         <property name="subscriber.name" value="dc=us,dc=oracle,dc=com"/>
         <property name="idstore.type" value="OID"/>
         <property value=ldap://myOID.com:3555 name="ldap.url"/>
        <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>
         <property name="username.attr" value="uid"/>
         <propperty name="group.attr" value="cn"/>
</serviceInstance>

<serviceInstance location="./bootstrap" provider="credstoressp"
 name="bootstrap.cred">
 <property value="./bootstrap" name="location"/>
</serviceInstance>

ログイン・モジュールのプリンシパル

出荷時のjps-config-jse.xmlには、次のプロパティが設定されています。

 <property name="oracle.security.jps.enterprise.user.class"
          value="weblogic.security.principal.WLSUserImpl"/>
 
    <property name="oracle.security.jps.enterprise.role.class"
             value="weblogic.security.principal.WLSGroupImpl"/>

どのようなログイン・モジュールでも、前述のプロパティを使用する必要があります。これは、アイデンティティ・ストア内のユーザーおよびグループを表すプリンシパルが、次のとおりであることを意味しています。

weblogic.security.principal.WLSUserImpl
weblogic.security.principal.WLSGroupImpl