この章の情報はJava SEアプリケーションにのみ適用され、Java SEアプリケーションの開発者を対象読者としています。Java EEアプリケーションの認証の詳細は、「Java EEアプリケーションの認証トピックへのリンク」にリストされているドキュメントを参照してください。
この章の内容は次のとおりです。
次にあげるドキュメントは、Java EEアプリケーションの認証開発に役立つ情報ソースです。
Oracle WebLogic Serverにおける認証の一般情報は、『Oracle Fusion Middleware Oracle WebLogic Serverセキュリティについて』の第3章にある認証に関する項を参照してください。
『Oracle Fusion Middleware Oracle WebLogic Serverセキュリティのプログラミング』
第3章「Webアプリケーションの保護」
第4章「Java ClientでのJAAS認証の使用」
第5章「Java ClientでのSSL認証の使用」
『Oracle Fusion Middleware Oracle WebLogic Serverセキュリティ・プロバイダの開発』
第4章「認証プロバイダ」
第5章「IDアサーション・プロバイダ」
第13章「サーブレットの認証フィルタ」
Java EEアプリケーション内のカスタム・モジュールは、認証プロバイダでラップする必要があります。詳細は、『Oracle Fusion Middleware Oracle WebLogic Serverセキュリティ・プロバイダの開発』のカスタムの認証プロバイダの開発方法に関する項を参照してください。
Java EEアプリケーションで使用されるログイン・モジュールについては、次のドキュメントを参照してください。
『Oracle Fusion Middleware Oracle WebLogic Serverセキュリティ・プロバイダの開発』の第4章にあるログイン・モジュールに関する項
『Oracle Fusion Middleware Oracle WebLogic Serverセキュリティのプログラミング』の第4章にあるJAAS認証の開発環境に関する項
すべてのOPSS API javadocへのリンクについては、第H.1項「OPSS APIリファレンス」を参照してください。
この項では、Java SEアプリケーションに対するアイデンティティ・ストアのサポートについて説明します。内容は次のとおりです。
Java SEアプリケーションでの認可の詳細は、第23.1項「Java SEアプリケーションでのポリシー・ストアと資格証明ストアの構成」を参照してください。
認証とは、コール元が特定のユーザーまたはシステムの代理として機能していることを証明するメカニズムです。認証では、名前とパスワードの組合せなどのデータを使用して、相手が誰であるかという質問への回答が提供されます。アイデンティティ・ストアという用語はアイデンティティ・データの格納場所を表し、認証プロバイダはアイデンティティ・ストアにアクセスするための手段です。
アプリケーションによるOPSSセキュリティ・ストア(アイデンティティ・ストア、ポリシー・ストアまたは資格証明ストア)からの情報の取得と、そのコンテンツの管理には、OPSS APIが使用されます。次の図はこれを示したものです。
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
で指定し、ブートストラップ資格証明ストアに格納します。
ログイン・モジュールは、ユーザーを認証し、サブジェクトにプリンシパルを移入するコンポーネントです。このプロセスは、2つの異なる段階で行われます。第一段階では、ログイン・モジュールによって要求元のユーザー(必要に応じて名前、パスワードまたはその他の資格証明データ)の認証が試みられます。第一段階が成功した場合にのみ、第二段階が呼び出されます。第二段階では、ログイン・モジュールによって、関連プリンシパルがサブジェクトに割り当てられ、最終的にそれが権限が付与されたアクションを実行するために使用されます。
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)
この項では、基本的なユーザー名とパスワードの認証のためのアイデンティティ・ストア・ログイン・モジュールの使用方法を示します。
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();
コールバック・ハンドラでは、NameCallback
とPasswordCallback
を処理できる必要があります。
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); } } } } }
アイデンティティ・ストアのログイン・モジュールをアサーションのために使用するには、開発者は次の処理を行う必要があります。
コール元が保護されたメソッド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(); } } }
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>
この項では、次のアーティファクトの構成を示します。
XMLのポリシー・ストアおよび資格証明ストア
XMLおよびLDAPのアイデンティティ・ストア
ログイン・モジュールのプリンシパル
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