この章はJavaSEアプリケーションのみに適用されます。JavaEEアプリケーションの認証については、他のOracle WebLogicドキュメントへのリンクが記載されています。
この章の内容は次のとおりです。
この情報を使用する前に、これらのAPIが使用されているコンテキストに精通しておくことを強くお薦めします。詳細は、第14.3.2項「OPSS APIによる認証」を参照してください。
次にあげるドキュメントは、JavaEEアプリケーションの認証開発に役立つ情報ソースです。
Oracle WebLogic Serverでの認証の一般的な情報は、『Oracle Fusion Middleware Understanding Security for Oracle WebLogic Server』の第3章にある認証に関する項を参照してください。
『Oracle Fusion Middleware Programming Security for Oracle WebLogic Server』
第3章「Webアプリケーションの保護」
第4章「Java ClientでのJAAS認証の使用」
第5章「Java ClientでのSSL認証の使用」
『Oracle Fusion Middleware Developing Security Providers for Oracle WebLogic Server』
第4章「認証プロバイダ」
第5章「IDアサーション・プロバイダ」
第13章「サーブレットの認証フィルタ」
JavaEEアプリケーション内のカスタム・モジュールは、認証プロバイダで折り返す必要があります。詳細は、『Oracle Fusion Middleware Developing Security Providers for Oracle WebLogic Server』のカスタム認証プロバイダの開発方法に関する項を参照してください。
JavaEEアプリケーションで使用されるログイン・モジュールについては、次のドキュメントを参照してください。
『Oracle Fusion Middleware Developing Security Providers for Oracle WebLogic Server』の第4章にあるログイン・モジュールに関する項
『Oracle Fusion Middleware Programming Security for Oracle WebLogic Server』の第4章にあるJAAS認証開発環境に関する項
すべてのOPSS API javadocへのリンクについては、第H.1項「OPSS APIリファレンス」を参照してください。
この項の内容は次のとおりです。
認証とは、コール元が特定のユーザーまたはシステムの代理として機能していることを証明するメカニズムです。認証は、名前/パスワードの組合せなどのデータを使用して、相手が誰であるかという質問に答えます。アイデンティティ・ストアはアイデンティティ・データの格納場所を示す抽象的概念であり、認証プロバイダはアイデンティティ・ストアにアクセスするための手段です。
アプリケーションがOPSSセキュリティ・ストア(アイデンティティ・ストア、ポリシー・ストアまたは資格証明ストア)から情報を取得して、そのコンテンツを管理するときに、OPSS APIが使用されます。この方法を次の図に示します。
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> </jpsContexts>
次の点に注意してください。
<serviceInstance>
の名前(この例では<idstore.ldap>
)には任意の値を指定できますが、要素<serviceInstanceRef>
で参照されるインスタンスと一致している必要があります。
<serviceProvider>
の名前(この例では<idstore.ldap.provider>
)には任意の値を指定できますが、要素<serviceInstance>
内のプロバイダと一致している必要があります。
指定したスクリプトを使用してプロバイダ・インスタンスにプロパティを追加するには、付録E「WLSTスクリプトを使用したOPSSサービス・プロバイダ・インスタンスの構成」を参照してください。
ログイン・モジュールは、ユーザーを認証し、サブジェクトにプリンシパルを移入するコンポーネントです。このプロセスは、2つの異なる段階で行われます。第一段階では、ログイン・モジュールによって要求元のユーザー(必要に応じて名前、パスワードまたはその他の資格証明データ)の認証が試みられます。第一段階が成功した場合にのみ、第二段階が呼び出されます。第二段階では、ログイン・モジュールによって、関連プリンシパルがサブジェクトに割り当てられ、最終的にそれが権限が付与されたアクションを実行するために使用されます。
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)
この項では、基本的なユーザー名とパスワードの認証のためのアイデンティティ・ストア・ログイン・モジュールの使用方法を示します。
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); } } } } }
アイデンティティ・ストアのログイン・モジュールをアサーションのために使用するには、開発者は次の処理を行う必要があります。
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(); ...
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);J 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>