18 資格証明ストア・フレームワークを使用した開発
この章の内容は次のとおりです。
- 資格証明ストア・フレームワークAPIについて
- 資格証明ストア・フレームワークAPIの使用のガイドライン
- 「マップとキー名について」
- アクセス・パーミッションのプロビジョニング
- 資格証明ストア・フレームワークAPIの使用
- 「資格証明ストア・フレームワークAPIの例」
親トピック: OPSS APIを使用した開発
資格証明ストア・フレームワークAPIについて
Credential Store Framework APIは、資格証明ストアに格納されている資格証明へのアクセス、取得および管理に使用します。このAPIを使用すると、次の操作が可能です。
-
資格証明マップまたはマップとキーのどちらが資格証明ストアに格納されているかのチェック。
-
マップまたはマップとキーに関連付けられている資格証明の取得。
-
マップまたはマップとキーへの資格証明の割当て。
-
マップまたはマップとキーの資格証明の削除。
資格証明ストアに対する操作は、資格証明フレームワークで使用されるファイングレイン制御を実装するクラスであるCredentialAccessPermissionクラスによって保護されます。
関連項目:
親トピック: 資格証明ストア・フレームワークを使用した開発
資格証明ストア・フレームワークAPIの使用のガイドライン
資格証明ストア・フレームワークAPIを使用するアプリケーションを開発する際には、必ず次のようにします。
-
アプリケーションによる資格証明へのアクセスを可能にするセキュリティ・ポリシーをプロビジョニングします。
-
特に、複数のアプリケーションが同じ資格証明ストアを使用する環境では、使用する適切なマップとキー名を決定します。
-
必ず
jps-config.xmlファイルで資格証明ストア・インスタンスを定義し、適切に構成します。
親トピック: 資格証明ストア・フレームワークを使用した開発
マップとキー名について
各アプリケーションには、資格証明ストア内で一意のマップ名が関連付けられている必要があります。これにより、ストア内のマップおよびキーの様々な名前の間で競合が発生せず、マップ名によってアプリケーションが一義的に特定されることが保証されます。アプリケーションは、特定のマップの中に、それぞれが同様に一意の名前を持っている複数のキーを格納できるため、マップ名/キー名のペアによって資格証明ストア内でただ1つのキーが特定されます。
親トピック: 資格証明ストア・フレームワークを使用した開発
アクセス・パーミッションのプロビジョニング
資格証明フレームワークにより、マップ、マップ内のすべてのキーおよびマップ内の特定のキーへのアクセスが保護されます。資格証明ストア・フレームワークAPIを使用するには、アプリケーションでAPIを使用できるようにするアクセス・パーミッションを指定する必要があります。さらに、このAPIをコールするコードにもコードソース・パーミッションが必要ですが、これらのパーミッションは通常、特定のJarのみに制限されます。すべてのマップおよびキーに対してアクセス・パーミッションを定義することはお薦めしません。
次の各項では、アクセス・パーミッションの定義について説明します。
1つのキーにアクセスするためのパーミッションの例
次の例では、マップ内の特定のキーに対してアクションを実行するソース・コードに対してのアクセス・パーミッションを示しています。
<jazn-policy>
<grant>
<grantee>
<principals>...</principals>
<codesource>
<url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
</codesource>
</grantee>
<permissions>
<permission>
<class>oracle.security.jps.service.credstore.
CredentialAccessPermission</class>
<name>context=SYSTEM,mapName=myMap,keyName=myKey</name>
<actions>*</actions>
</permission>
</permissions>
</grant>
</jazn-policy>親トピック: アクセス・パーミッションのプロビジョニング
マップにアクセスするためのパーミッションの例
次の例では、マップとそのマップ内のすべてのキーに対して特定のアクションを実行するソース・コードに対してのアクセス・パーミッションを示しています。
<jazn-policy>
<grant>
<grantee>
<principals>...</principals>
<codesource>
<url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
</codesource>
</grantee>
<permissions>
<permission>
<class>oracle.security.jps.service.credstore.
CredentialAccessPermission</class>
<name>context=SYSTEM,mapName=myMap,keyName=*</name>
<actions>read,write,update,delete</actions>
</permission>
</permissions>
</grant>
</jazn-policy>親トピック: アクセス・パーミッションのプロビジョニング
資格証明ストア・フレームワークAPIの使用
次の各項では、Java SEアプリケーションおよびJava EEアプリケーションでこのフレームワークを使用する方法について説明します。
親トピック: 資格証明ストア・フレームワークを使用した開発
Java SEアプリケーションでの資格証明ストア・フレームワークAPIの使用
Java SEアプリケーションで資格証明ストア・フレームワークAPIを使用するには、次の手順を実行します。
親トピック: 資格証明ストア・フレームワークAPIの使用
Java EEアプリケーションでの資格証明ストア・フレームワークAPIの使用
資格証明ストア・フレームワークAPIをJava EEアプリケーションで使用するには、アプリケーションをOracle WebLogic Serverにデプロイする前に、動作に必要なアクセス・パーミッションを指定します。
関連項目:
親トピック: 資格証明ストア・フレームワークAPIの使用
資格証明ストア・フレームワークAPIの例
次の各例では、資格証明ストア操作で必要なアクセス・パーミッションを使用する方法を示します。
- 資格証明ストア・フレームワーク操作の例
- ファイル資格証明を使用するJava SEアプリケーションの例
- ファイル資格証明を使用するJava EEアプリケーションの例
- LDAPストアを使用するJava EEアプリケーションの例
- DBストアを使用するJava EEアプリケーションの例
親トピック: 資格証明ストア・フレームワークを使用した開発
資格証明ストア・フレームワーク操作の例
次の例では、他の例で使用されている資格証明ストア・フレームワークAPI操作を示します。
package demo.util;
import java.security.AccessController;
import java.security.PrivilegedAction;
import oracle.security.jps.JpsException;
import oracle.security.jps.service.credstore.Credential;
import oracle.security.jps.service.credstore.CredentialAlreadyExistsException;
import oracle.security.jps.service.credstore.CredentialFactory;
import oracle.security.jps.service.credstore.CredentialStore;
import oracle.security.jps.service.credstore.PasswordCredential;
public class CsfUtil {
final CredentialStore store;
public CsfUtil(CredentialStore store) {
super();
this.store = store;
}
private void doOperation() {
try {
PasswordCredential pc = null;
try {
// this call requires read privilege
pc = (PasswordCredential)store.getCredential("pc_map", "pc_key");
if (pc == null) {
// key not found, create one
pc = CredentialFactory.newPasswordCredential("jdoe",
"password".toCharArray());
// this call requires write privilege
store.setCredential("pc_map", "pc_key", pc);
System.out.print("Created ");
}
else {
if (pc instanceof PasswordCredential){
System.out.print("Found ");
} else {
System.out.println("Unexpected credential type found");
}
System.out.println("password credential: Name=" + pc.getName() +
",Password=" +
new String(pc.getPassword()));
} catch (CredentialAlreadyExistsException e) {
// ignore because credential already exists.
System.out.println("Credential already exists for
<pc_map, pc_key>: " + pc.getName() + ":" +
new String(pc.getPassword()));
}
try {
// permission corresponding to
// "context=SYSTEM,mapName=gc_map,keyName=gc_key"
byte[] secret =
new byte[] { 0x7e, 0x7f, 0x3d, 0x4f, 0x10,
0x20, 0x30 };
Credential gc =
CredentialFactory.newGenericCredential(secret);
store.setCredential("gc_map", "gc_key", gc);
System.out.println("Created generic credential");
} catch (CredentialAlreadyExistsException e) {
// ignore because credential already exists.
System.out.println("Generic credential already exists
for <gc_map,gc_key>");
}
try {
//no permission for pc_map2 & pc_key2 to perform
//operation on store
Credential pc2 =
CredentialFactory.newPasswordCredential("pc_jode2",
"pc_password".toCharArray());
store.setCredential("pc_map2", "pc_key2", pc2);
} catch (Exception expected) {
//CredentialAccess Exception expected here. Not enough permission
System.out.println("This is expected :" +
expected.getLocalizedMessage());
}
} catch (JpsException e) {
e.printStackTrace();
}
}
/*
* This method performs a non-privileged operation. all code
* in the call stack must have CredentialAccessPermission
* OR
* the caller must have the CredentialAccessPermission only and
* invoke this operation in doPrivileged block
*/
public void doCredOperation() {
doOperation();
}
/*
* because the following performs a privileged operation, only
* jar containing this class needs CredentialAccessPermission
*/
public void doPrivilegedCredOperation() {
AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
doOperation();
return "done";
}
};
}
}親トピック: 資格証明ストア・フレームワークAPIの例
ファイル資格証明を使用するJava SEアプリケーションの例
この項の例では、$DOMAIN_HOME/config/fmwconfig/system-jazn-data.xmlファイルで表されるファイル資格証明ストアを使用するJava SEアプリケーションを示します。
この例では、システム・プロパティprojectsrc.homeはJava SEアプリケーションを格納しているディレクトリを指し、clientApp.jarはdistディレクトリに存在するアプリケーションJARファイルです。
次の権限付与は、アクセス・パーミッションを示しています。
<grant>
<grantee>
<codesource>
<url>file:${projectsrc.home}/dist/clientApp.jar</url>
</codesource>
</grantee>
<permissions>
<permission>
<class>oracle.security.jps.service.credstore.CredentialAccessPermission
</class>
<name>context=SYSTEM,mapName=pc_map,keyName=*</name>
<actions>read,write</actions>
</permission>
<permission>
<class>oracle.security.jps.service.credstore.CredentialAccessPermission
</class>
<name>context=SYSTEM,mapName=gc_map,keyName=gc_key</name>
<actions>write</actions>
</permission>
</permissions>
</grant>
mapName=pc_map2,keyName=pc_key2にはパーミッションが付与されないため、そのマップおよびキーのsetCredentialへのコールは失敗します。
アプリケーションで使用される資格証明ストアは、jps-config-jse.xmlに指定します。
<serviceInstances>
<serviceInstance name="credstore_file_instance"
provider="credstore_file_provider">
<property name="location" value="store" />
</serviceInstance>
</serviceInstances>
次に、プログラムをコールするJava SEコードを示します。
package demo;
import java.io.ByteArrayInputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import oracle.security.jps.JpsContext;
import oracle.security.jps.JpsStartup;
import oracle.security.jps.JpsContextFactory;
import oracle.security.jps.JpsException;
import oracle.security.jps.jaas.JavaPolicy;
import oracle.security.jps.service.credstore.Credential;
import oracle.security.jps.service.credstore.CredentialAlreadyExistsException;
import oracle.security.jps.service.credstore.CredentialFactory;
import oracle.security.jps.service.credstore.CredentialStore;
import oracle.security.jps.service.credstore.PasswordCredential;
import oracle.security.jps.service.policystore.PolicyStore;
import oracle.security.jps.service.policystore.PolicyStoreException;
import demo.util.CsfUtil;
public class CsfApp {
public CsfApp() {
super();
}
public static void main(String[] a) {
// perform operation as privileged code
JpsContextFactory ctxFactory;
try {
new JpsStartup().start();
ctxFactory = JpsContextFactory.getContextFactory();
JpsContext ctx = ctxFactory.getContext();
CredentialStore store =
ctx.getServiceInstance(CredentialStore.class);
CsfUtil csf = new CsfUtil(store);
// next call is in a doPrivileged block and should succeed
csf.doPrivilegedCredOperation();
// because next call is not in a doPrivileged block,
// it fails if CredentialAccessPermission is not granted to this class
csf.doCredOperation();
} catch (JpsException e) {
e.printStackTrace();
}
}
}親トピック: 資格証明ストア・フレームワークAPIの例
ファイル資格証明を使用するJava EEアプリケーションの例
この例では、資格証明ストア・フレームワークAPIをコールするファイル資格証明を使用するJava EEアプリケーションを示します。jazn-data.xmlファイルでは、適切なアクセス・パーミッション、コードソース・パーミッション、マップとキーの様々な組合せで必要なパーミッションを定義します。
次の権限付与は、アクセス・パーミッションを示しています。
<grant>
<grantee>
<codesource>
<url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
</codesource>
</grantee>
<permissions>
<permission>
<class>oracle.security.jps.service.credstore.CredentialAccessPermission
</class>
<name>context=SYSTEM,mapName=pc_map,keyName=*</name>
<actions>read,write</actions>
</permission>
<permission>
<class>oracle.security.jps.service.credstore.CredentialAccessPermission
</class>
<name>context=SYSTEM,mapName=gc_map,keyName=gc_key</name>
<actions>write</actions>
</permission>
</permissions>
</grant>
アプリケーションで使用される資格証明ストアは、jps-config.xmlに指定します。
<serviceProviders>
<serviceProvider type="CREDENTIAL_STORE" name="credstoressp"
class="oracle.security.jps.internal.credstore.ssp.SspCredentialStoreProvider">
<description>SecretStore-based CSF provider</description>
</serviceProvider>
</serviceProviders>
<serviceInstances>
<serviceInstance name="credstore" provider="credstoressp">
<property name="location" value="./" />
</serviceInstance>
</serviceInstances>
<jpsContexts default="default">
<jpsContext name="default">
...
<serviceInstanceRef ref="credstore"/>
...
</jpsContext>
</jpsContexts>
locationプロパティでは、cwallet.ssoファイルの場所を指定します。
次に、このような構成を使用する例を示します。
package demo;
import demo.util.CsfUtil;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
import java.util.Date;
import javax.servlet.*;
import javax.servlet.http.*;
import oracle.security.jps.JpsException;
import oracle.security.jps.service.JpsServiceLocator;
import oracle.security.jps.service.credstore.CredentialStore;
public class CsfDemoServlet extends HttpServlet {
private static final String CONTENT_TYPE = "text/html; charset=windows-1252";
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
//ServletOutputStream out = response.getOutputStream();
try {
response.setContentType("text/html");
out.println("<html><body bgcolor=\"#FFFFFF\">");
out.println("<b>Current Time: </b>" + new Date().toString() +
"<br><br>");
//get hold of app-level CSF service store
//Outside app context, it returns the domain CSF store
final CredentialStore store =
JpsServiceLocator.getServiceLocator().lookup(CredentialStore.class);
CsfUtil csf = new CsfUtil(store);
csf.doPrivilegedCredOperation();
out.println("Credential operations completed using privileged code.");
} catch (JpsException e) {
e.printStackTrace(out);
}
}
}
作成操作は、権限が付与されたブロックの中に実装されます。Java SE環境では、次の2つのコールは同等です。
CredentialStore store = JpsServiceLocator.getServiceLocator().lookup(CredentialStore.class); CredentialStore store = JpsContextFactory.getContextFactory().getContext().getServiceInstance(CredentialStore.class);
親トピック: 資格証明ストア・フレームワークAPIの例
LDAPストアを使用するJava EEアプリケーションの例
次の例では、ファイル資格証明を使用するJava EEアプリケーションの例で使用されている同じアプリケーションを使用していますが、資格証明ストアはここではファイルではなくLDAPです。
次に、LDAPストア構成の例を示します。
<serviceProviders>
<serviceProvider name="ldap.credentialstore.provider"
class="oracle.security.jps.internal.credstore.ldap.LdapCredentialStoreProvider">
<description>Prototype LDAP CSF provider</description>
</serviceProvider>
</serviceProviders>
<serviceInstances>
<serviceInstance provider="ldap.credentialstore.provider"
name="credstore.ldap">
<property value="bootstrap"
name="bootstrap.security.principal.key"/>
<property value="cn=wls-jrfServer"
name="oracle.security.jps.farm.name"/>
<property value="cn=jpsTestNode"
name="oracle.security.jps.ldap.root.name"/>
<property value="ldap://mynode.us.mycorp.com:1234"
name="ldap.url"/>
</serviceInstance>
</serviceInstances>
<jpsContexts default="appdefault">
<jpsContext name="appdefault">
<serviceInstanceRef ref="credstore.ldap"/>
</jpsContext>
</jpsContexts>親トピック: 資格証明ストア・フレームワークAPIの例
DBストアを使用するJava EEアプリケーションの例
次の例では、ファイル資格証明を使用するJava EEアプリケーションの例で使用されている同じアプリケーションを使用していますが、資格証明ストアはここではファイルではなくデータベースです。
次に、DBストア構成の例を示します。
<serviceProviders> <serviceProvider type="CREDENTIAL_STORE" name="db.credentialstore.provider" class="oracle.security.jps.internal.credstore.rdbms.DbmsCredentialStoreProvider"/> <description>DB CSF provider</description> </serviceProvider> </serviceProviders> <serviceInstances> <serviceInstance provider="db.credentialstore.provider" name="credstore.db"> <property value="bootstrap" name="bootstrap.security.principal.key"/> <property value="cn=wls-jrfServer" name="oracle.security.jps.farm.name"/> <property value="cn=jpsTestNode" name="oracle.security.jps.ldap.root.name"/> <property name="jdbc.url" value="jdbc:oracle:thin:@localhost:5521:ldapoid"/> <property name="jdbc.driver" value="oracle.jdbc.OracleDriver"/> <property name="datasource.jndi.name" value="jdbc/OpssDS"/> </serviceInstance> </serviceInstances> <jpsContexts default="appdefault"> <jpsContext name="appdefault"> <serviceInstanceRef ref="credstore.db"/> </jpsContext> </jpsContexts>
親トピック: 資格証明ストア・フレームワークAPIの例