この章の情報はJava SEアプリケーションにのみ適用され、Java SEアプリケーションの開発者を対象読者としています。Java EEアプリケーションについての同様の情報は、第21章「OPSSを使用するためのJava EEアプリケーションの構成」を参照してください。
この章の内容は次のとおりです。
Java SEアプリケーションでOPSSを使用するためには、開発者は次のことを理解する必要があります。
jps-manifest.jar
ファイルがクラスパスに存在している必要があります。
初期化の際に、アプリケーションはJpsStartup.start()
をコールする必要があります。
次のシステム・プロパティを設定する必要があります。
oracle.security.jps.config
。jps-config-jse.xml
ファイルへのファイル・パス。
common.components.home
。oracle commonディレクトリへのパス。
java.security.policy
。java.policy
ファイルへのファイル・パス。
その他の設定可能な(オプションの)システム・プロパティの詳細は、第F.1項「OPSSシステム・プロパティ」を参照してください。
次のサンプル・スニペットで示すように、アプリケーションはOPSSクラスAppSecurityContext
を使用します。
String appID = AppSecurityContext.getApplicationID(); try { setApplicationID(appName); ..... } finally { setApplicationID(appID ); } } private static void setApplicationID(final String applicationID) { AccessController.doPrivileged(new PrivilegedAction() { public Object run() { AppSecurityContext.setApplicationID(applicationID); return null; } }); }
AppSecurityContext.setApplicationID
コールには、次のようなコードソース・パーミッションが必要です。
<grant> <grantee> <codesource> <url>myJavaSEapp/-</url> </codesource> </grantee> <permissions> <permission> <class>oracle.security.jps.JpsPermission</class> <name>AppSecurityContext.setApplicationID.myAppStripeID</name> </permission> </permissions> </grant>
OPSSセキュリティ・ストアを構成する方法の詳細は、第8章「OPSSセキュリティ・ストアの構成」を参照してください。
この項では、Java SEアプリケーションのOPSSサポートについて、サービスごとに説明します。
この項では、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="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「スクリプトを使用したOPSSサービス・プロバイダ・インスタンスの構成」を参照してください。
ログイン・モジュールは、ユーザーを認証し、サブジェクトにプリンシパルを移入するコンポーネントです。このプロセスは、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 String[]{"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