Oracle® Fusion Middleware Oracle WebLogic Serverセキュリティ・プロバイダの開発 11g リリース1(10.3.4) B61623-02 |
|
![]() 前 |
![]() 次 |
認可とは、ユーザーのIDなどの情報に基づいて、ユーザーとWebLogicリソースとの対話を管理するプロセスのことです。言い換えれば、認可とは「自分は何にアクセスできますか」という質問に答えるものです。WebLogic Serverでは、認可プロバイダはユーザーとWebLogicリソースとの対話を制限して、整合性、機密性、および可用性を確保します。
以下の節では、認可プロバイダの概念と機能、およびカスタム認可プロバイダの開発手順について説明します。
認可プロバイダを開発する前に、以下の概念を理解しておく必要があります。
認証プロバイダのLoginModuleと同じく、アクセス決定は、「アクセスは許可されるのか」という質問に答える認可プロバイダのコンポーネントです。具体的には、指定された操作をWebLogicリソースに対して実行するパーミッションをサブジェクトが持っているかどうかが、アプリケーション内の特定のパラメータを用いてアクセス決定に質問されます。この情報が与えられると、アクセス決定はそれに対する回答をPERMIT
、DENY
、またはABSTAIN
のいずれかで返します。
Java Authorization Contract for Containers (JACC)はJava EEの一部です。JACCは、EJBおよびサーブレットに対するパーミッション・ベースのセキュリティ・モデルです。JACCはJSR-115 (http://www.jcp.org/en/jsr/detail?id=115
)によって定義されます。
JACCは、WebLogic Serverドメイン内のEJBおよびサーブレット・コンテナに代替認可メカニズムを提供します。JACCが構成されている場合、WebLogic Securityフレームワークのアクセス決定、裁決、およびロール・マッピング機能は、EJBおよびサーブレットの認可判定には使用されません。
注意: WebLogic Securityフレームワークと一緒にJACCフレームワークを使用することはできません。WebLogic Serverで使用されるJACCクラスには、決定を下すためのポリシー・オブジェクトの実装は含みません。かわりに、JACCクラスは、java.security.Policy (http://java.sun.com/javase/6/docs/api/java/security/Policy.html )オブジェクトに依存します。 |
WebLogic Serverは、JSR-115に完全に準拠しているものの、WebLogic認証プロバイダほどには最適化されていないJACCプロバイダを実装します。Java JACCクラスは、アクセス決定を下す際に使用します。JSR-115はロール・マッピングに対処する方法を定義しないので、ロールとプリンシパルの間のマッピングにはWebLogic JACCクラスが使用されます。JACCプロバイダの開発の詳細は、(http://java.sun.com/javaee/5/docs/api/javax/security/jacc/package-frame.html
)を参照してください。
図7-1に、認可プロセスにおける認可プロバイダ(および関連する裁決プロバイダとロール・マッピング・プロバイダ)とWebLogic Securityフレームワークとの対話を示します。その後、この図について説明します。
一般に、認可は以下のように実行されます。
ユーザーまたはシステム・プロセスがWebLogicリソースをリクエストし、特定の操作を実行しようとします。
リクエストされたWebLogicリソースのタイプを処理するリソース・コンテナがリクエストを受け取ります。たとえばEJBコンテナはEJBリソースに対するリクエストを受け取ります。
リソース・コンテナは、ContextHandler
オブジェクトを作成します。このオブジェクトは、構成済みのロール・マッピング・プロバイダおよび認可プロバイダのアクセス決定で、そのリクエストのコンテキストに関連付けられている情報を取得する際に使用できます。
注意: ContextHandlerの詳細は、「ContextHandlerとWebLogicリソース」を参照してください。アクセス決定の詳細は、「アクセス決定」を参照してください。ロール・マッピング・プロバイダの詳細は、「ロール・マッピング・プロバイダ」を参照してください。 |
リソース・コンテナは、サブジェクト、WebLogicリソース、そして場合によっては決定用の追加入力を提供するContextHandler
オブジェクトを渡してWebLogic Securityフレームワークを呼び出します。
WebLogic Securityフレームワークは、構成済みのロール・マッピング・プロバイダを呼び出します。
ロール・マッピング・プロバイダはContextHandler
を用いて、リクエストに関する様々な情報をリクエストします。また、ロール・マッピング・プロバイダは、リクエストする情報のタイプを表す一連のCallback
オブジェクトを作成します。そのCallback
オブジェクト群は、handle
メソッドを通じて、配列としてContextHandler
に渡されます。
ロール・マッピング・プロバイダは、Callback
オブジェクトに格納されている値、サブジェクト、およびリソースを用いて、リクエスト側のサブジェクトに付与されるセキュリティ・ロールを計算し、該当するセキュリティ・ロールをWebLogic Securityフレームワークに返します。
WebLogic Securityは、リクエストされたアクションをリソースに対して実行する資格がサブジェクトにあるかどうかに関し、実際の判定を認可プロバイダに委託します。
認可プロバイダのアクセス決定ではまた、ContextHandler
を用いてリクエストに関する様々な情報をリクエストします。アクセス決定は、リクエストする情報のタイプを表す一連のCallback
オブジェクトを作成します。そのCallback
オブジェクト群は、handle
メソッドを通じて、配列としてContextHandler
に渡されます。このプロセスは、ステップ5のロール・マッピング・プロバイダの場合と同じです。
構成済みの各認可プロバイダのアクセス決定のisAccessAllowed
メソッドが呼び出され、リクエストされたアクセスを実行する権限がサブジェクトにあるかどうかが、ContextHandler
、サブジェクト、WebLogicリソース、およびセキュリティ・ロールに基づいて判定されます。各isAccessAllowed
メソッドは、以下の3つの値のいずれかを返します。
PERMIT
- リクエストされたアクセスが許可されることを示します。
DENY
- リクエストされたアクセスが明示的に拒否されることを示します。
ABSTAIN
- 明示的な判定をアクセス決定が下せなかったことを示します。
このプロセスは、すべてのアクセス決定が使用されるまで続きます。
WebLogic Securityフレームワークは、構成済みの認可プロバイダのアクセス決定から返された判定結果に食い違いがあった場合、その調停を裁決プロバイダに委託します。裁決プロバイダでは、認可判定の最終結果を決定します。
裁決プロバイダはTRUE
またはFALSE
の判定を返し、この判定はWebLogic Securityフレームワークを通してリソース・コンテナに転送されます。
判定がTRUE
の場合、リソース・コンテナはリクエストを保護対象のWebLogicリソースにディスパッチします。
判定がFALSE
の場合、リソース・コンテナはセキュリティ例外を送出します。この例外は、リクエスト側にはリクエストしたアクセスを保護されたWebLogicリソースに対して行う権限がなかったことを示します。
WebLogic Serverのデフォルト(つまりアクティブな)セキュリティ・レルムにはWebLogic認可プロバイダが含まれています。WebLogic認可プロバイダは、このバージョンのWebLogic Serverの認可機能をデフォルトで適用するものです。WebLogic認可プロバイダは、特定のユーザーが保護対象のWebLogicリソースへのアクセスを許可されているかどうかを判定するためのポリシー・ベースの認可エンジンを使用して、アクセス決定を返します。また、WebLogic認可プロバイダは、システム内のセキュリティ・ポリシーのデプロイメントとアンデプロイメントもサポートしています。自社の既存の認可メカニズムを使用する場合は、カスタム認可プロバイダを作成してそれを既存のメカニズムに結合できます。
セキュリティ・レルムのすべての認可プロバイダ、ロール・マッピング・プロバイダ、および資格証明マッピング・プロバイダは、アプリケーションのデプロイにバージョンを使用するために、アプリケーションのバージョン管理をサポートする必要があります。認可、ロール・マッピング、または資格証明マッピング用にカスタム・セキュリティ・プロバイダを開発する際に、バージョン管理されたアプリケーションをサポートする必要がある場合は、「バージョン管理可能なアプリケーションのプロバイダ」の説明に従って、バージョン管理可能なアプリケーションのSSPIを実装する必要があります。
最高のパフォーマンスを実現するため、デフォルトでは、アプリケーションおよびモジュールのデプロイメント中にセキュリティ・ポリシーおよびロールに対して並列変更を実行できます。この理由から、セキュリティ・レルムに構成されているデプロイ可能な認可プロバイダおよびロール・マッピング・プロバイダでは、並列呼出しがサポートされている必要があります。WebLogicのデプロイ可能なXACML認可プロバイダおよびロール・マッピング・プロバイダは、この要件を満たしています。
ただし、カスタムのデプロイ可能な認可プロバイダおよびロール・マッピング・プロバイダでは、並列呼出しがサポートされている場合とサポートされていない場合があります。カスタムのデプロイ可能な認可プロバイダまたはロール・マッピング・プロバイダで並列呼出しがサポートされていない場合は、セキュリティ・ポリシーとロールの並列変更を無効にして、かわりに同期化メカニズムを強制的に使用する必要があります。この場合、各アプリケーションとモジュールはキューに入り、順番にデプロイされます。
注意: 同期化メカニズムを有効にした場合、定義済のWebLogic Serverプロバイダも含めて、レルム内に構成されているすべてのデプロイ可能なプロバイダが影響を受けます。同期化メカニズムを有効にすると、これらのプロバイダのパフォーマンスに悪影響を与える可能性があります。 |
この同期化強制メカニズムを有効にする方法については、『Oracle WebLogic Serverの保護』を参照してください。
WebLogic認可プロバイダが開発者のニーズを満たさない場合、次の手順でカスタム認可プロバイダを開発することができます。
適切なSSPIによる実行時クラスの作成、または必要に応じてバルク認可プロバイダを実装
必要に応じて、ポリシー・コンシューマSSPIを実装
必要に応じて、PolicyStoreMBeanを実装
実行時クラスを作成する前に、以下の作業が必要です。
この情報を理解し、設計に関する判断を下したら、次の手順でカスタム認可プロバイダの実行時クラスを作成します。
AuthorizationProvider SSPIの実装またはDeployableAuthorizationProviderV2 SSPIの実装
注意: セキュリティ・レルムでは、少なくとも1つの認可プロバイダがDeployableAuthorizationProvider SSPIを実装している必要があります。実装していない場合、WebアプリケーションやEJBをデプロイできなくなります。 |
カスタム認可プロバイダの実行時クラスの作成例については、「例:サンプル認可プロバイダの実行時クラスの作成」を参照してください。
AuthorizationProvider
SSPIを実装するには、「「Provider」SSPIの目的について」で説明されているメソッドと以下の実装を提供する必要があります。
getAccessDecision
public AccessDecision getAccessDecision();
getAccessDecision
メソッドは、AccessDecision
SSPIの実装を取得します。MyAuthorizationProviderImpl
.java
という1つの実行時クラスの場合、getAccessDecision
メソッドの実装は次のようになります。
return this;
実行時クラスが2つの場合、getAccessDecision
メソッドの実装は次のようになります。
return new MyAccessDecisionImpl;
これは、AuthorizationProvider
SSPIを実装する実行時クラスが、AccessDecision
SSPIを実装するクラスを取得する場合のファクトリとして使用されるためです。
AuthorizationProvider
SSPIとgetAccessDecision
メソッドの詳細は、WebLogic Server APIリファレンスJavadocを参照してください。
DeployableAuthorizationProviderV2
SSPIを実装するには、「「Provider」SSPIの目的について」と「AuthorizationProvider SSPIの実装」で説明されているメソッド、および次のメソッドの実装を提供する必要があります。
deleteApplicationPolicies
public void deleteApplicationPolicies(ApplicationInfo application) throws ResourceRemovalException
deleteApplicationPolicies
メソッドは、アプリケーションのポリシーをすべて削除します。deleteApplicationPolicies
メソッドは、管理サーバーでのみ呼び出されます。
deployExcludedPolicy
public void deleteApplicationPolicies(DeployPolicyHandle handle, Resource resource) throws ResourceCreationException
deployExcludedPolicy
メソッドは、アクセスを常に拒否するポリシーをデプロイします。
deployPolicy
public void deployPolicy(DeployPolicyHandle handle, Resource resource, String[] roleNames) throws ResourceCreationException
deployPolicy
メソッドは、セキュリティ・ポリシーの適用対象となるWebLogicリソースと、セキュリティ・ポリシー内に記載されるセキュリティ・ロール名を基に、デプロイ済みのWebアプリケーションやEJBにかわってセキュリティ・ポリシーを作成します。
deployUncheckedPolicy
public void deployUncheckedPolicy(DeployPolicyHandle handle, Resource resource) throws ResourceCreationException
deployUncheckedPolicy
メソッドは、アクセスを常に許可するポリシーをデプロイします。ポリシーがすでに存在する場合は削除され、このポリシーによって置き換えられます。
endDeployPolicies
public void endDeployPolicies(DeployPolicyHandle handle) throws ResourceCreationException
deployExcludedPolicy
メソッドは、アクセスを常に拒否するポリシーをデプロイします。
startDeployPolicies
public deployPolicyHandle startDeployPolicies(ApplicationInfo application) throws DeployHandleCreationException
startDeployPolicies
メソッドは、アプリケーションのポリシー・デプロイメントの開始をマークし、アプリケーションがターゲット指定されているWebLogic Serverドメイン内のすべてのサーバーで呼び出されます。
undeployAllPolicies
public void undeployAllPolicies(DeployPolicyHandle handle) throws ResourceRemovalException
undeployAllPolicies
メソッドは、デプロイされていないWebアプリケーションまたはEJBにかわって、ポリシー定義のセットを削除します。
DeployableAuthorizationProviderV2
SSPIとdeployPolicy
およびundeployPolicy
メソッドの詳細は、WebLogic Server APIリファレンスJavadocを参照してください。
ApplicationInfoインタフェースは、アプリケーションのデプロイメントに関するデータをセキュリティ・プロバイダに渡します。このデータを使用すると、アプリケーションをユニークに識別できます。
WebLogic Securityフレームワークは、ユーザーの利便を図るためにApplicationInfoインタフェースを実装します。このインタフェースのメソッドを実装する必要はありません。
DeployableAuthorizationProviderV2
インタフェースとDeployableRoleProviderV2
インタフェースはApplicationInfo
を使用します。たとえば、DeployableAuthorizationProviderV2
のメソッドの実装を例にあげます。Securityフレームワークは、DeployableAuthorizationProviderV2
のstartDeployPolicies
メソッドを呼び出し、このアプリケーションのApplicationInfoインタフェースを渡します。ApplicationInfo
データは、アプリケーションのデプロイ時に管理コンソールで提供される情報を基に決められます。
startDeployPolicies
メソッドは、DeployableAuthorizationProviderV2
の他のメソッドでこの後使用できるDeployPolicyHandle
を戻します。
ApplicationInfo
インタフェースを使用すると、このアプリケーションのアプリケーション識別子、コンポーネント名、およびコンポーネントの種類を取得できます。コンポーネントの種類は、ApplicationInfo.ComponentType
クラスの定義に従って、APPLICATION
、CONTROL_RESOURCE
、EJB
、WEBAPP
のいずれかです。
次のコードは、このタスクを実行する方法の一例です。
public DeployPolicyHandle startDeployPolicies(ApplicationInfo appInfo) throws DeployHandleCreationException : // Obtain the application information... String appId = appInfo.getApplicationIdentifier(); ComponentType compType = appInfo.getComponentType(); String compName = appInfo.getComponentName();
Securityフレームワークは、DeployableAuthorizationProviderV2
のdeleteApplicationPolicies
メソッドを呼び出し、このアプリケーションのApplicationInfo
インタフェースを渡します。deleteApplicationPolicies
メソッドは、アプリケーションのポリシーをすべて削除します。このメソッドは、アプリケーションが削除されたときにWebLogic Serverドメイン内の管理サーバーでのみ呼び出されます。
AccessDecision
SSPIを実装する際には、以下のメソッドの実装を用意する必要があります。
isAccessAllowed
public Result isAccessAllowed(Subject subject, Map roles, Resource resource, ContextHandler handler, Direction direction) throws InvalidPrincipalException
isAccessAllowed
メソッドは、サブジェクトに格納されている情報を利用して、リクエスト側に保護対象リソースへのアクセスを許可すべきかどうかを決定します。isAccessAllowed
メソッドはリクエストの前または後に呼び出すことができ、PERMIT
、DENY
、またはABSTAIN
のいずれかの値を返します。複数のアクセス決定が構成されていて、それらが相反する値を返す場合、最終結果を決定するには裁決プロバイダが必要になります。詳細については、「裁決プロバイダ」を参照してください。
isProtectedResource
public boolean isProtectedResource(Subject subject, Resource resource) throws InvalidPrincipalException
isProtectedResource
メソッドは、指定されたWebLogicリソースが保護対象かどうかを実際にアクセス・チェックを行わずに決定するために使用します。これは呼出し側のサブジェクトに付与できる一連のセキュリティ・ロールを計算するわけではないので、軽量のメカニズムに過ぎません。
AccessDecision
SSPIとisAccessAllowed
およびisProtectedResource
メソッドの詳細は、WebLogic Server APIリファレンスJavadocを参照してください。
認証プロバイダは、サブジェクト内へのユーザーおよびグループの格納を担当するセキュリティ・プロバイダです。ユーザーおよびグループはその後、認可プロバイダなど、他のタイプのセキュリティ・プロバイダによって、サブジェクトから抽出されます。セキュリティ・レルム内で構成された認証プロバイダがレルム・アダプタ認証プロバイダである場合、ユーザーおよびグループの情報は、他の認証プロバイダとは少し異なる形でサブジェクト内に格納されます。したがって、このユーザーおよびグループの情報もまた、少し異なる方法で抽出する必要があります。
例7-1は、サブジェクトへの格納にレルム・アダプタ認証プロバイダが使用された場合に、サブジェクトがユーザー名またはグループ名に一致するかどうかをチェックするために、カスタム認可プロバイダで使用できるコードです。このコードは、isAccessAllowed
メソッドとisProtectedResource
メソッドの双方に属しています。
例7-1 サンプル・コード:サブジェクトがユーザー名またはグループ名に一致するかどうかのチェック
/** * Determines if the Subject matches a user/group name. * * @param principalWant A String containing the name of a principal in this role * (that is, the role definition). * * @param subject A Subject that contains the Principals that identify the user * who is trying to access the resource as well as the user's groups. * * @return A boolean. true if the current subject matches the name of the * principal in the role, false otherwise. */ private boolean subjectMatches(String principalWant, Subject subject) { // first, see if it's a group name match if (SubjectUtils.isUserInGroup(subject, principalWant)) { return true; } // second, see if it's a user name match if (principalWant.equals(SubjectUtils.getUsername(subject))) { return true; } // didn't match return false; }
例7-2は、サンプル認可プロバイダの実行時クラスであるSampleAuthorizationProviderImpl.java
クラスを示しています。実行時クラスには以下の実装が含まれています。
initialize
、getDescription
、およびshutdown
というSecurityProvider
インタフェースから継承した3つのメソッド(「「Provider」SSPIの目的について」を参照)。
AuthorizationProvider
SSPIから継承したgetAccessDecision
メソッド(「AuthorizationProvider SSPIの実装」を参照)。
deleteApplicationPolicies
、deployExcludedPolicy
、deployPolicy
、deployUncheckedPolicy
、endDeployPolicies
、starteployPolicies
、およびundeployAllPolicies
というDeployableAuthorizationProviderV2
SSPIの7つのメソッド(「DeployableAuthorizationProviderV2 SSPIの実装」を参照)。
AccessDecision
SSPIのisAccessAllowed
およびisProtectedResource
メソッド(「AccessDecision SSPIの実装」を参照)
例7-2 SimpleSampleAuthorizationProviderImpl.java
package examples.security.providers.authorization.simple; import java.security.Principal; import java.util.Date; import java.util.Enumeration; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.security.auth.Subject; import weblogic.management.security.ProviderMBean; import weblogic.security.SubjectUtils; import weblogic.security.WLSPrincipals; import weblogic.security.service.ContextHandler; import weblogic.security.spi.AccessDecision; import weblogic.security.spi.ApplicationInfo; import weblogic.security.spi.ApplicationInfo.ComponentType; import weblogic.security.spi.DeployableAuthorizationProviderV2; import weblogic.security.spi.DeployPolicyHandle; import weblogic.security.spi.Direction; import weblogic.security.spi.InvalidPrincipalException; import weblogic.security.spi.Resource; import weblogic.security.spi.Result; import weblogic.security.spi.SecurityServices; import weblogic.security.spi.VersionableApplicationProvider; public final class SimpleSampleAuthorizationProviderImpl implements DeployableAuthorizationProviderV2, AccessDecision, VersionableApplicationProvider { private static String[] NO_ACCESS = new String[0]; private static String[] ALL_ACCESS = new String[] {WLSPrincipals.getEveryoneGroupname()}; private String description; private SimpleSampleAuthorizerDatabase database; public void initialize(ProviderMBean mbean, SecurityServices services) { System.out.println("SimpleSampleAuthorizationProviderImpl.initialize"); SimpleSampleAuthorizerMBean myMBean = (SimpleSampleAuthorizerMBean)mbean; description = myMBean.getDescription() + "\n" + myMBean.getVersion(); database = new SimpleSampleAuthorizerDatabase(myMBean); } public String getDescription() { return description; } public void shutdown() { System.out.println("SampleAuthorizationProviderImpl.shutdown"); } public AccessDecision getAccessDecision() { return this; } public Result isAccessAllowed(Subject subject, Map roles, Resource resource, ContextHandler handler, Direction direction) { System.out.println("SimpleSampleAuthorizationProviderImpl.isAccessAllowed"); System.out.println("\tsubject\t= " + subject); System.out.println("\troles\t= " + roles); System.out.println("\tresource\t= " + resource); System.out.println("\tdirection\t= " + direction); Set principals = subject.getPrincipals(); for (Resource res = resource; res != null; res = res.getParentResource()) { if (database.policyExists(res)) { Result result = isAccessAllowed(res, subject, roles); System.out.println("\tallowed\t= " + result); return result; } } Result result = Result.ABSTAIN; System.out.println("\tallowed\t= " + result); return result; } public boolean isProtectedResource(Subject subject, Resource resource) throws InvalidPrincipalException { System.out.println("SimpleSampleAuthorizationProviderImpl. isProtectedResource"); System.out.println("\tsubject\t= " + subject); System.out.println("\tresource\t= " + resource); for (Resource res = resource; res != null; res = res.getParentResource()) { if (database.policyExists(res)) { System.out.println("\tprotected\t= true"); return true; } } System.out.println("\tprotected\t= false"); return false; } public DeployPolicyHandle startDeployPolicies(ApplicationInfo application) { String appId = application.getApplicationIdentifier(); String compName = application.getComponentName(); ComponentType compType = application.getComponentType(); DeployPolicyHandle handle = new SampleDeployPolicyHandle(appId,compName,compType); database.removePoliciesForComponent(appId, compName, compType); return handle; public void deployPolicy(DeployPolicyHandle handle, Resource resource, String[] roleNamesAllowed) { System.out.println("SimpleSampleAuthorizationProviderImpl.deployPolicy"); System.out.println("\thandle\t= " + ((SampleDeployPolicyHandle)handle).toString()); System.out.println("\tresource\t= " + resource); for (int i = 0; roleNamesAllowed != null && i < roleNamesAllowed.length; i++) { System.out.println("\troleNamesAllowed[" + i + "]\t= " + roleNamesAllowed[i]); } database.setPolicy(resource, roleNamesAllowed); } public void deployUncheckedPolicy(DeployPolicyHandle handle, Resource resource) { System.out.println("SimpleSampleAuthorizationProviderImpl.deployUncheckedPolicy"); System.out.println("\thandle\t= " + ((SampleDeployPolicyHandle)handle).toString()); System.out.println("\tresource\t= " + resource); database.setPolicy(resource, ALL_ACCESS); } public void deployExcludedPolicy(DeployPolicyHandle handle, Resource resource) { System.out.println("SimpleSampleAuthorizationProviderImpl.deployExcludedPolicy"); System.out.println("\thandle\t= " + ((SampleDeployPolicyHandle)handle).toString()); System.out.println("\tresource\t= " + resource); database.setPolicy(resource, NO_ACCESS); } public void endDeployPolicies(DeployPolicyHandle handle) { database.savePolicies(); } public void undeployAllPolicies(DeployPolicyHandle handle) { System.out.println("SimpleSampleAuthorizationProviderImpl.undeployAllPolicies"); SampleDeployPolicyHandle myHandle = (SampleDeployPolicyHandle)handle; System.out.println("\thandle\t= " + myHandle.toString()); // remove policies database.removePoliciesForComponent(myHandle.getApplication(), myHandle.getComponent(), myHandle.getComponentType()); } public void deleteApplicationPolicies(ApplicationInfo application) { System.out.println("SimpleSampleAuthorizationProviderImpl.deleteApplicationPolicies"); String appId = application.getApplicationIdentifier(); System.out.println("\tapplication identifier\t= " + appId); // clear out policies for the application database.removePoliciesForApplication(appId); } private boolean rolesOrSubjectContains(Map roles, Subject subject, String roleOrPrincipalWant) { // first, see if it's a role name match if (roles.containsKey(roleOrPrincipalWant)) { return true; } // second, see if it's a group name match if (SubjectUtils.isUserInGroup(subject, roleOrPrincipalWant)) { return true; } // third, see if it's a user name match if (roleOrPrincipalWant.equals(SubjectUtils.getUsername(subject))) { return true; } // didn't match return false; } private Result isAccessAllowed(Resource resource, Subject subject, Map roles) { // loop over the principals and roles in our database who are allowed to access this resource for (Enumeration e = database.getPolicy(resource); e.hasMoreElements();) { String roleOrPrincipalAllowed = (String)e.nextElement(); if (rolesOrSubjectContains(roles, subject, roleOrPrincipalAllowed)) { return Result.PERMIT; } } // the resource was explicitly mentioned and didn't grant access return Result.DENY; } public void createApplicationVersion(String appId, String sourceAppId) { System.out.println("SimpleSampleAuthorizationProviderImpl.createApplicationVersion"); System.out.println("\tapplication identifier\t= " + appId); System.out.println("\tsource app identifier\t= " + ((sourceAppId != null) ? sourceAppId : "None")); // create new policies when existing application is specified if (sourceAppId != null) { database.clonePoliciesForApplication(sourceAppId,appId); } } public void deleteApplicationVersion(String appId) { System.out.println("SimpleSampleAuthorizationProviderImpl.deleteApplicationVersion"); System.out.println("\tapplication identifier\t= " + appId); // clear out policies for the application database.removePoliciesForApplication(appId); } public void deleteApplication(String appName) { System.out.println("SimpleSampleAuthorizationProviderImpl.deleteApplication"); System.out.println("\tapplication name\t= " + appName); // clear out policies for the application database.removePoliciesForApplication(appName); } class SampleDeployPolicyHandle implements DeployPolicyHandle { Date date; String application; String component; ComponentType componentType; SampleDeployPolicyHandle(String app, String comp, ComponentType type) { this.application = app; this.component = comp; this.componentType = type; this.date = new Date(); } public String getApplication() { return application; } public String getComponent() { return component; } public ComponentType getComponentType() { return componentType; } public String toString() { String name = component; if (componentType == ComponentType.APPLICATION) name = application; return componentType +" "+ name +" ["+ date.toString() +"]"; } } }
WebLogic Serverには、JMX (MBean)デフォルト・ポリシーとWebサービス・アノテーション用のポリシー・コンシューマが実装されています。このリリースのWebLogic Serverには、認可プロバイダがポリシー・コレクションを取得するために使用できるSSPIがあります。
PolicyConsumer
SSPIは省略可能です。ポリシー・コレクションを消費するためには、このSSPIを実装する認可プロバイダのみが呼び出されます。
このSSPIでは、初期状態のポリシー・コレクションの配信と、更新後のポリシー・コレクションの配信の両方がサポートされます。
ポリシー・コレクションの消費においては、PolicyConsumer
SSPIをサポートするすべての認可プロバイダが呼び出されます。各認可プロバイダは、特定のポリシー・セットのポリシー・コレクションを取得するかしないかを選択できます。プロバイダでポリシーが永続化される場合、ポリシーを取得する必要があるのは一度のみです。一方、プロバイダでポリシーがメモリーに保持される場合、ポリシー・コレクションを再び取得することも可能です。
用意されているWebLogic Server認可プロバイダでは、ポリシーはLDAP内に永続化されます。
カスタム認可プロバイダでポリシー・コレクションの配信をサポートするには、以下の3つのインタフェースを実装する必要があります。
weblogic.security.spi.PolicyConsumerFactory
weblogic.security.spi.PolicyConsumer
weblogic.security.spi.PolicyCollectionHandler
これらのインタフェースについては、これ以降の節で説明します。
認可プロバイダには、PolicyConsumerのインスタンスをWebLogic Securityフレームワークで使用できるように、PolicyConsumerFactory
インタフェースが実装されています。WebLogic SecurityフレームワークではPolicyConsumerFactory
の実装を呼び出して、プロバイダのポリシー・コンシューマの実装を取得します。
PolicyConsumerFactory
SSPIにはメソッドが1つあり、このメソッドはPolicyConsumer
SSPIインタフェースの実装を返します。
public interface PolicyConsumerFactory { /** * Obtain the implementation of the PolicyConsumer * security service provider interface (SSPI). * * @return a PolicyConsumer SSPI implementation. */ public PolicyConsumer getPolicyConsumer(); }
PolicyConsumer
SSPIは、ポリシー・コレクションを消費するためのポリシー・コレクション・ハンドラを戻します。これにはgetPolicyCollectionHandler()
というメソッドが1つあり、このメソッドは引数にPolicyCollectionInfo
の実装を取って、PolicyCollectionHandler
インタフェースの実装を戻します。
public interface PolicyConsumer { /** * Obtain a policy handler for consumption of a policy set. * * @param info the PolicyCollectionInfo for the policy set. * * @return a PolicyCollectionHandler or NULL which indicates * that the policy set is not needed. * * @exception ConsumptionException if an error occurs * obtaining the handler and the policy set cannot be consumed. */ public PolicyCollectionHandler getPolicyCollectionHandler( PolicyCollectionInfo info) throws ConsumptionException; }
WebLogic SecurityフレームワークではgetPolicyCollectionHandler()
メソッドを呼び出して、ポリシー・コレクションに関するデータをPolicyCollectionInfo
インタフェースの実装としてセキュリティ・プロバイダに渡します(このインタフェースはあらかじめ実装されているので、ユーザーが実装する必要はありません)。
PolicyCollectionInfo
のgetName()
、getVersion()
、getTimestamp()
、およびgetResourceTypes()
メソッドを使用して、このポリシー・セットに関する情報を検索します。検索後にはPolicyCollectionHandler
を返すか、ポリシー・コレクションが不要であることを示すNULLを返します。
public interface PolicyCollectionInfo { /** * Get the name of the collection. */ public String getName(); /** * Get the runtime version of the policy. */ public String getVersion(); /** * Get the timestamp of the policy. */ public String getTimestamp(); /** * Get the resource types used in the policy collection. */ public Resource[] getResouceTypes(); }
PolicyConsumer.getPolicyCollectionHandler()
メソッドはPolicyCollectionHandler
インタフェースの実装を返します。PolicyCollectionHandler
にはsetPolicy
、setUncheckedPolicy
、およびdone()
という3つのメソッドがあります。setPolicy()
はリソースおよびロールの名前を取り、ロールに基づいてポリシーを設定します。setUncheckedPolicy()
メソッドはすべてのユーザーにアクセスを許可します。
done()
メソッドはポリシー・コレクションの完了を示します。done()
メソッドでは、ポリシー・セットの古いポリシーをすべて削除することをお薦めします。
public interface PolicyCollectionHandler { /** * Set a policy for the specified resource. */ public void setPolicy(Resource resource, String[] roleNames) throws ConsumptionException; /** * Sets a policy which always grants access. */ public void setUncheckedPolicy(Resource resource) throws ConsumptionException; /** * Signals the completion of the policy collection. */ public void done() throws ConsumptionException; }
更新後のポリシー・コレクションの配信をサポートするには、PolicyConsumer
SSPIをサポートするすべての認可プロバイダでPolicyConsumer.getPolicyCollectionHandler()
メソッドに渡されたPolicyCollectionInfo
の内容を調べて、ポリシー・セットが変更されているかどうかを判断する必要があります。各プロバイダでは、初期状態のポリシー・コレクションとSSPIの外部から受け取ったカスタマイズ後のポリシーとの衝突を解決する方法を(できれば構成によって)決定しておくことが必要です。
WebLogic Serverで提供されている認可プロバイダでは、カスタマイズ後のポリシーが更新後のポリシー・コレクションで置き換えられません。初期状態のポリシー・コレクションのポリシーはすべて削除され、カスタマイズ後のポリシーと更新後のポリシー・コレクションのみが有効になります。ポリシー・コレクションの情報に異なるタイムスタンプやバージョンがある場合、更新後のポリシー・コレクションとして扱われます。コレクションの名前は永続キーとして使用されます。
このリリースのWebLogic Serverでは、weblogic.management.security.authorization.PolicyStoreMBean
という新しいMBeanがサポートされています。このMBeanは、管理者が生成したXACMLポリシーおよびポリシー・セットの標準的な管理操作(追加、削除、取得、リスト表示、変更、読込み)に使用できます。認可プロバイダMBeanやロール・マッピング・プロバイダMBeanには、必要に応じてこのMBeanインタフェースを実装できます。
セキュリティ管理者は、PolicyStoreMBeanのメソッドを使用して、サーバー内のポリシーをXACMLドキュメントとして管理できます。たとえば、デフォルトのXACMLプロバイダを使用するドメインを作成および管理したり、作成済みのXACMLドキュメントを管理したりできます。これらのXACMLポリシーは、WebLogic ServerではWLSTを使用して管理できます。
WebLogic ServerにはこのMBeanの実装が含まれており、付属のXACMLプロバイダで使用できます。また、このMBeanの独自の実装を記述して、カスタムの認可プロバイダやロール・マッピング・プロバイダで使用することも可能です。WebLogic Serverに用意されているXACMLプロバイダでは、XACML 2.0のコア仕様(http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-core-spec-os.pdf
)に記載されているXACMLの必須機能がサポートされています。Oracle固有の使用方法については、『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』を参照してください。
ポリシーはXACML 2.0のポリシーまたはPolicySetドキュメントで表現されます。カスタム認可プロバイダでは、XACML 2.0のコア仕様(http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-core-spec-os.pdf
)に記載されている標準のPolicyまたはPolicySetドキュメントを想定する必要があります。カスタム・ロール・マッピング・プロバイダでは、Core and hierarchical role based access control (RBAC) profile of XACML v2.0 (http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-rbac-profile1-spec-os.pdf
)に記載されているロール割当てポリシーと整合性があるPolicyまたはPolicySetドキュメントを想定する必要があります。
具体的には、Targetに以下を含める必要があります。
ActionAttributeDesignator
(anyURI-equal
で一致する、urn:oasis:names:tc:xacml:1.0:action:action-id
というIDと、urn:oasis:names:tc:xacml:2.0:actions:enableRole
という値の指定されているもの)。例:
<Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:anyURI-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#anyURI">urn:oasis:names:tc:xacml:2.0 :actions:enableRole </AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#anyURI" MustBePresent="true"/> </ActionMatch> </Action>
ResourceAttributeDesignator
(string-equalで一致する、urn:oasis:names:tc:xacml:2.0:subject:role
というIDと、割り当てられたロールの名前である値の指定されているもの)。例:
<ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:2.0:resource:resource-ancestor-or-self" DataType="http://www.w3.org/2001/XMLSchema#string" MustBePresent="true"/>
XACML 2.0のコア仕様(http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-core-spec-os.pdf
)および『Oracle WebLogic Serverロールおよびポリシーによるリソースの保護』で説明しているOracle拡張が、提供されているXACML認可プロバイダおよびロール・マッピング・プロバイダで使用するXACMLポリシー・ファイルについての最も確実な情報です。
ただしサポートされているXACMLファイルの形式を開発プロセスの一環として確認する場合は、おそらく、管理コンソールを使用して、XACML認可またはロール・マッピング・プロバイダのデータベースからデータをXACMLファイルとしてエクスポートする方法が最も便利です。エクスポートしたXACMLファイルをコピーして別の名前で保存し、任意のツールで確認します。
注意: エクスポートしたファイルは読取り専用としてください。変更した場合、そのファイルはWebLogic Serverにインポートし直さないでください。エクスポートしたファイルを編集すると、WebLogic Server構成が使用できなくなる可能性があります。エクスポートしたファイルの編集はサポートされていません。 |
例7-3に、WLSTを使用してXACMLファイルからPolicyStoreMBeanのインスタンスに1つのポリシーを追加する例を示します。
この例ではこのスクリプトで使用するプロパティを、次のant
スクリプトから抜粋した行に似た方法で、あらかじめ別の場所に定義してあるものと想定しています。
<property name="xacml-docs-dir" value="${xacmldir}/xacml-docs"/> <sysproperty key="file" value="${xacml-docs-dir}/policy-getSubject.xacml"/>
例7-3 WLSTを使用してPolicyStoreMBeanにポリシーの追加
: try: protocol = System.getProperty("protocol") host = System.getProperty("host") user = System.getProperty("authuser") passwd = System.getProperty("authpwd") port = System.getProperty("port") dom = System.getProperty("domain") rlm = System.getProperty("realm") fil = System.getProperty("file") prov = System.getProperty("provider") stat = System.getProperty("status") def configure(): try: url = protocol + "://" + host + ":" + port connect(user,passwd, url) path = "/SecurityConfiguration/" + dom + "/Realms/" + rlm + "/" + prov print("cd'ing to " + path) cd(path) print("calling open()") xacmlFile = open(fil,"r") print("calling read()") xacmlDoc = xacmlFile.read() print("calling cmo.addPolicy") if stat == "none": cmo.addPolicy(xacmlDoc) else: cmo.addPolicy(xacmlDoc, stat) print("Add error handling") : :
『Oracle WebLogic Scripting Tool』のMBeanの移動と照会に関する項で説明しているように、WLSTが初めてWebLogic Serverインスタンスに接続すると、変数cmo
(現在の管理オブジェクト)がすべての構成管理オブジェクトのルートDomainMBean
に初期化されます。MBeanタイプに移動すると、このSecurityConfigurationMBean
の場合、cmo
の値はSecurityConfigurationMBean
を反映したものになります。MBeanインスタンス、つまりこの場合にはPolicyStoreMBeanを実装する認可プロバイダMBean(例では変数prov
で指定)に移動するときには、WLSTによってcmo
の値が現在のMBeanインスタンスに変更されます。
この例ではPolicyStoreMBeanのaddPolicy()メソッドを使用して、XACMLファイルからポリシー・ストアに読み込まれるポリシーを追加しています。addPolicy()メソッドの2つのバリアント(ステータスを伴うものと伴わないもの)が示されています。
ステータスを指定しないaddPolicy()メソッドを使用する場合、デフォルトでACTIVEに設定されます。これは、ポリシーがその対象で適用されるどのような決定でも評価されることを示します。ステータスは明示的にACTIVE、INACTIVE、またはBYREFERENCEに設定できます。INACTIVEステータスは、ポリシーが評価されずに格納されるだけであることを示します。BYREFERENCEステータスは、評価されるポリシー・セットによって参照された場合にだけ、ポリシーが評価されることを示します。
このタイプのWLSTスクリプトは、次のような方法でコマンド・ラインから呼び出せます。
java -Dhost="localhost " -Dprotocol="t3" -Dauthuser="weblogic" -Dauthpwd="weblogic" -Dport="7001" -Ddomain="mydomain" -Drealm="myrealm" -Dprovider="Authorizers/XACMLAuthorizer" -Dfile="C:/XACML/xacml-docs/policy12.xml" -Dstatus="none" weblogic.WLST XACML/scripts/XACMLaddPolicy.py
例7-4に、WLSTを使用してPolicySetをStringとして読み込む例を示します。
この例ではこのスクリプトで使用するプロパティを、次のant
スクリプトから抜粋した行に似た方法で、あらかじめ別の場所に定義してあるものと想定しています。
<sysproperty key="identifier" value="urn:sample:xacml:2.0:wlssecqa:resource:type@E@Fejb@G@M@Oapplication@ENoD DRolesOrPoliciesEar@M@Omodule@Eejb11inEarMiniAppBean.jar@M@Oejb@EMiniAppBean@ M@Omethod@EgetSubject@M@OmethodInterface@ERemote"/> <sysproperty key="version" value="1.0"/>
例7-4 WLSTを使用してPolicySetをStringとして読み込む
: : try: print("start XACMLreadPolicySet.py") protocol = System.getProperty("protocol") host = System.getProperty("host") user = System.getProperty("authuser") passwd = System.getProperty("authpwd") port = System.getProperty("port") dom = System.getProperty("domain") rlm = System.getProperty("realm") prov = System.getProperty("provider") id = System.getProperty("identifier") vers = System.getProperty("version") : : def configure(): try: url = protocol + "://" + host + ":" + port connect(user,passwd, url) path = "/SecurityConfiguration/" + dom + "/Realms/" + rlm + "/" + prov print("cd'ing to " + path) cd(path) polset = cmo.readPolicySetAsString(id, vers) print("readPolicySetAsString() returned the following policy set: " + polset) print"Add error handling." : :
XACML 2.0のコア仕様(http://docs.oasis-open.org/xacml/2.0/access_control-xacml-2.0-core-spec-os.pdf
)で説明されているように、<PolicySet>
要素には<Policy>
のセットまたは別の<PolicySet>
要素、およびそれらの評価結果を結合するための指定された手順が含まれます。詳細については、XACML 2.0のコア仕様を参照してください。
WebLogic Serverのこのリリースには、以下に示すバルク・アクセス・バージョンの認可プロバイダSSPIインタフェースがあります。
BulkAuthorizationProvider
BulkAccessDecision
バルク・アクセスSSPIインタフェースを使用すると、認可プロバイダにおいて1回の呼出しで複数の判定リクエストを取得できます。これまでのように、たとえば「for」
ループで複数の呼出しを実行する必要はありません。バルクSSPIバリアントの目的は、プロバイダ実装において内部的なパフォーマンスの最適化を利用できるようにすることです。たとえば、渡されたResource
オブジェクトの多くが同じポリシーで保護されていることを検出することで、それらの判定結果が同じになると推測できるようになります。
バルク・バージョンでないSSPIインタフェースとバルク・バージョンのSSPIインタフェースの使用方法には若干の違いがあります。
BulkAccessDecision.isAccessAllowed()
メソッドはロールのMap
を引数に取ります。これは、第1にResource
オブジェクト、続いてロール名(Map<Resource, Map<String, SecurityRole>> roles)
で索引付けされ、サブジェクトに関連付けられているもので、認可判定時に考慮に入れる必要があります。
BulkAccessDecision.isAccessAllowed()
メソッドはMap
(Resource、結果で索引付け)
を返します。これは、リソースに定義された認可ポリシーが、リクエストされたメソッドの実行を許可するかどうかを示します。
カスタム・セキュリティ・プロバイダのMBeanタイプを生成する前に、以下の作業が必要です。
この情報を理解し、設計に関する判断を下したら、次の手順でカスタム認可プロバイダのMBeanタイプを作成します。
WebLogic Server環境にMBeanタイプをインストールする
注意: この手順の実行方法を説明するサンプル・セキュリティ・プロバイダ(Oracle Technology Network Webサイトのhttps://codesamples.samplecode.oracle.com/servlets/tracking?id=S224 から入手可能)がいくつか用意されています。
この節で説明する手順はすべて、Windows環境での作業を想定しています。 |
MBean定義ファイル(MDF)を作成するには、次の手順に従います。
サンプル認可プロバイダのMDFをテキスト・ファイルにコピーします。
注意: サンプル認可プロバイダのMDFは、SimpleSampleAuthorizer.xml という名前です。 |
MDFで<MBeanType>
要素と<MBeanAttribute>
要素の内容をカスタム認可プロバイダに合わせて修正します。
カスタム属性および操作(つまり、<MBeanAttribute>
および<MBeanOperation>
要素)をMDFに追加します。
ファイルを保存します。
MDFを作成したら、WebLogic MBeanMakerを使用してそれを実行できます。WebLogic MBeanMakerは現在のところコマンド・ライン・ユーティリティで、入力としてMDFを受け取り、MBeanインタフェース、MBean実装、関連するMBean情報ファイルなどの中間Javaファイルをいくつか出力します。これらの中間ファイルが合わさって、カスタム・セキュリティ・プロバイダのMBeanタイプになります。
MBeanタイプの作成手順は、カスタム認可プロバイダの設計に応じて異なります。必要な設計に合わせて適切な手順を実行してください。
カスタム認可プロバイダのMDFに任意SSPI MBeanもカスタム操作も実装しない場合、次の手順を行います。
新しいDOSシェルを作成します。
次のコマンドを入力します。
java -DMDF=xmlfile -Dfiles=filesdir -DcreateStubs=true weblogic.management.commo.WebLogicMBeanMaker
ここで、-DMDF
フラグはWebLogic MBeanMakerがMDFをコードに変換すべきであることを示し、xmlFileはMDF (XML MBeanの記述ファイル)、filesdirはWebLogic MBeanMakerで作成されたMBeanタイプの中間ファイルが格納される場所を示します。
xmlfileが入力されるたびに、新しい出力ファイル群が生成されます。
-DcreateStubs=true
フラグを使用するたびに、既存のMBean実装ファイルがすべて上書きされます。
注意: バージョン9.0以降のWebLogic Serverでは、-DMDFDIR <MDF directory name>オプションを使用して、複数のMDFを格納するディレクトリを指定することができます。旧バージョンのWebLogic Serverでは、WebLogic MBeanMakerで一度に処理されるMDFは1つだけです。したがって、MDF (つまり認可プロバイダ)が複数ある場合には、このプロセスを繰り返す必要がありました。 |
カスタム認可プロバイダのMDFに任意SSPI MBeanまたはカスタム操作を実装する場合、以下の質問に答えながら手順を進めてください。
MBeanタイプを作成するのは初めてですか。初めての場合は、次の手順に従ってください。
新しいDOSシェルを作成します。
次のコマンドを入力します。
java -DMDF=xmlfile -Dfiles=filesdir -DcreateStubs=true weblogic.management.commo.WebLogicMBeanMaker
ここで、-DMDF
フラグはWebLogic MBeanMakerがMDFをコードに変換すべきであることを示し、xmlFileはMDF (XML MBeanの記述ファイル)、filesdirはWebLogic MBeanMakerで作成されたMBeanタイプの中間ファイルが格納される場所を示します。
xmlfileが入力されるたびに、新しい出力ファイル群が生成されます。
-DcreateStubs=true
フラグを使用するたびに、既存のMBean実装ファイルがすべて上書きされます。
注意: バージョン9.0以降のWebLogic Serverでは、-DMDFDIR <MDF directory name>オプションを使用して、複数のMDFを格納するディレクトリを指定することができます。旧バージョンのWebLogic Serverでは、WebLogic MBeanMakerで一度に処理されるMDFは1つだけです。したがって、MDF (つまり認可プロバイダ)が複数ある場合には、このプロセスを繰り返す必要がありました。 |
任意SSPI MBeanをMDFに実装した場合は、次の手順に従います。
MBean実装ファイルを見つけます。
WebLogic MBeanMakerによって生成されるMBean実装ファイルには、MBeanNameImpl.java
という名前が付けられます。たとえば、SampleAuthorizer
という名前のMDFの場合、編集されるMBean実装ファイルはSampleAuthorizerImpl.java
という名前になります。
MDFで実装した任意SSPI MBeanごとに、各メソッドを実装します。任意SSPI MBeanが継承するメソッドもすべて実装してください。
MDFにカスタム操作を含めた場合、メソッド・スタブを使用してメソッドを実装します。
ファイルを保存します。
既存のMBeanタイプの更新ですか。更新の場合は、次の手順に従ってください。
WebLogic MBeanMakerによって現在のメソッドの実装が上書きされないように、既存のMBean実装ファイルを一時ディレクトリにコピーします。
新しいDOSシェルを作成します。
次のコマンドを入力します。
java -DMDF=xmlfile -Dfiles=filesdir -DcreateStubs=true weblogic.management.commo.WebLogicMBeanMaker
ここで、-DMDF
フラグはWebLogic MBeanMakerがMDFをコードに変換すべきであることを示し、xmlFileはMDF (XML MBeanの記述ファイル)、filesdirはWebLogic MBeanMakerで作成されたMBeanタイプの中間ファイルが格納される場所を示します。
xmlfileが入力されるたびに、新しい出力ファイル群が生成されます。
-DcreateStubs=true
フラグを使用するたびに、既存のMBean実装ファイルがすべて上書きされます。
注意: バージョン9.0以降のWebLogic Serverでは、-DMDFDIR <MDF directory name>オプションを使用して、複数のMDFを格納するディレクトリを指定することができます。旧バージョンのWebLogic Serverでは、WebLogic MBeanMakerで一度に処理されるMDFは1つだけです。したがって、MDF (つまり認可プロバイダ)が複数ある場合には、このプロセスを繰り返す必要がありました。 |
任意SSPI MBeanをMDFに実装した場合は、次の手順に従います。
MBean実装ファイルを見つけます。
WebLogic MBeanMakerによって生成されるMBean実装ファイルには、MBeanNameImpl.java
という名前が付けられます。たとえば、SampleAuthorizer
という名前のMDFの場合、編集されるMBean実装ファイルはSampleAuthorizerImpl.java
という名前になります。
ステップ1で一時ディレクトリに保存した既存のMBean実装ファイルを開きます。
既存のMBean実装ファイルを、WebLogic MBeanMakerによって生成されたMBean実装ファイルと同期させます。
これには、メソッドの実装を既存のMBean実装ファイルから新しく生成されたMBean実装ファイルにコピー(または、新しく生成されたMBean実装ファイルから既存のMBean実装ファイルに新しいメソッドを追加)し、いずれのMBean実装ファイルにも入っているメソッドのメソッド・シグネチャへの変更が、使用するMBean実装ファイルに反映されていることを確認するといった作業が必要です。
MDFを修正して元のMDFにはない任意SSPI MBeanを実装した場合は、各メソッドを実装します。任意SSPI MBeanが継承するメソッドもすべて実装してください。
MDFを変更して元のMDFにはないカスタム操作を含めた場合、メソッド・スタブを使用してメソッドを実装します。
完成した、つまりすべてのメソッドを実装したMBean実装ファイルを保存します。
このMBean実装ファイルを、WebLogic MBeanMakerがMBeanタイプの実装ファイルを配置したディレクトリにコピーします。このディレクトリは、ステップ3でfilesdirとして指定したものです。(ステップ3の結果としてWebLogic MBeanMakerで生成されたMBean実装ファイルがオーバーライドされます)。
MBeanインタフェース・ファイルとは、実行時クラスまたはMBean実装が構成データを取得するために使用するMBeanのクライアント側APIです。「「Provider」SSPIの目的について」で説明されているように、これはinitializeメソッドで使用するのが一般的です。
WebLogic MBeanMakerでは、作成済みのMDFからMBeanタイプを生成するので、生成されるMBeanインタフェース・ファイルの名前は、そのMDF名の後に「MBean」というテキストが付いたものになります。たとえば、WebLogic MBeanMakerでSampleAuthorizer
MDFを実行すると、結果としてSampleAuthorizerMBean.java
というMBeanインタフェース・ファイルが生成されます。
WebLogic MBeanMakerでMDFを実行して中間ファイルを作成し、MBean実装ファイルを編集して適切なメソッドの実装を提供したら、カスタム認可プロバイダのMBeanファイルと実行時クラスをMBean JARファイル(MJF)にパッケージ化する必要があります。このプロセスも、WebLogic MBeanMakerによって自動化されます。
カスタム認可プロバイダのMJFを作成するには、次の手順に従います。
新しいDOSシェルを作成します。
次のコマンドを入力します。
java -DMJF=jarfile -Dfiles=filesdir weblogic.management.commo.WebLogicMBeanMaker
ここで、-DMJF
フラグはWebLogic MBeanMakerが新しいMBeanタイプを含むJARファイルを構築すべきであることを示し、jarfileはMJFの名前、filesdirはWebLogic MBeanMakerでMJFにJAR化する対象ファイルが存在する場所を示します。
この時点でコンパイルが行われるので、エラーが発生するおそれがあります。jarfileが指定されていて、エラーが発生しなかった場合には、指定された名前のMJFが作成されます。
注意: カスタム・セキュリティ・プロバイダのJARファイルを作成する際には、一連のXMLバインディング・クラスと1つのスキーマも生成されます。そのスキーマに関連付けるネームスペースを選択できます。それにより、使用しているカスタム・クラスとOracleのカスタム・クラスとの衝突を防ぐことができます。ネームスペースのデフォルトはvendorです。-targetNameSpace引数をWebLogicMBeanMakerまたは関連するWLMBeanMaker antタスクに渡すことで、このデフォルトを変更できます。既存のMJFを更新する場合は、単純にMJFを削除して再生成します。WebLogic MBeanMakerにも -DIncludeSourceオプションがあり、それを指定すると、生成されるMJFにソース・ファイルを含めるかどうかを制御できます。ソース・ファイルには、生成されたソースとMDFそのものがあります。デフォルトはfalseです。このオプションは、-DMJFを使用しない場合には無視されます。 |
生成されたMJFは、自らのWebLogic Server環境にインストールすることも、顧客に配布してそれぞれのWebLogic Server環境にインストールしてもらうこともできます。
MBeanタイプをWebLogic Server環境にインストールするには、MJFをWL_HOME\server\lib\mbeantypes
ディレクトリにコピーします。ここで、WL_HOMEはWebLogic Serverの最上位のインストール・ディレクトリです。このインストール・コマンドによって、カスタム認可プロバイダが「デプロイ」されます。つまり、カスタム認可プロバイダをWebLogic Server管理コンソールから管理できるようになります。
注意: WL_HOME\server\lib\mbeantypes は、MBeanタイプのインストール用のデフォルト・ディレクトリです。(9.0から、セキュリティ・プロバイダを...\domaindir\lib\mbeantypes からロードすることもできるようになりました。)ただし、サーバーを起動するときに-Dweblogic.alternateTypesDirectory=<dir> コマンド・ライン・フラグを使用すれば、WebLogic Serverは追加ディレクトリでMBeanタイプを検索します。<dir>は、ディレクトリ名のカンマ区切りのリストです。このフラグを使用する場合、WebLogic Serverは常に、まずWL_HOME\server\lib\mbeantypes からMBeanタイプをロードします。次に、追加ディレクトリにあるすべての有効なアーカイブを検索して、ロードします。このとき拡張子は考慮されません。
たとえば、 |
カスタム認可プロバイダを構成することによって(「管理コンソールによるカスタム認可プロバイダの構成」を参照)、MBeanタイプのインスタンスを作成して、GUI、他のJavaコード、またはAPIからそれらのMBeanインスタンスを使用することができます。たとえば、WebLogic Server管理コンソールを使用して、属性を取得/設定したり操作を呼び出したりすることもできますし、他のJavaオブジェクトを開発して、そのオブジェクトでMBeanをインスタンス化し、それらのMBeanから提供される情報に自動的に応答させることもできます。なお、これらのMBeanインスタンスをバックアップしておくことをお薦めします。
カスタム認可プロバイダを構成するということは、認可サービスを必要とするアプリケーションがアクセス可能なセキュリティ・レルムにカスタム認可プロバイダを追加するということです。
カスタム・セキュリティ・プロバイダの構成は管理タスクですが、カスタム・セキュリティ・プロバイダの開発者が行うこともできます。この節では、カスタム認可プロバイダの構成担当者向けの重要な情報を取り上げます。
注意: WebLogic Server管理コンソールを使用してカスタム認可プロバイダを構成する手順は、『Oracle WebLogic Serverの保護』のWebLogicセキュリティ・プロバイダの構成に関する項で説明されています。 |
Enterprise JavaBeans (EJB)やWebアプリケーションなどのアプリケーションの中には、Java EEの関連デプロイメント情報とWebLogic Serverデプロイメント記述子を格納するものがあります。Webアプリケーションの場合、デプロイメント記述子ファイル(web.xml
とweblogic.xml
)には、セキュリティ・ポリシーの宣言を含むJava EEセキュリティ・モデルの実装情報が記述されます。この情報は、WebLogic Server管理コンソールで認可プロバイダを初めて構成するときに格納するのが一般的です。
Java EEプラットフォームはデプロイメント記述子でWebアプリケーションおよびEJBのセキュリティを標準化しているので、WebLogic Serverではこの標準メカニズムがWebLogic Securityサービスに統合され、WebアプリケーションおよびEJBリソースを保護する方法を選択できるようになっています。デプロイメント記述子のみを使用することも管理コンソールのみを使用することもできます。また、状況によっては、この2つの方法を組み合せることもできます。
選択した方法によって、セキュリティ・モデルを適用する必要もあります。WebLogicでは、個々のデプロイメントについて複数のセキュリティ・モデルがサポートされ、使用する方法を組み込むレルム全体の構成についてはセキュリティ・モデルがサポートされます。
デプロイメント記述子を使用するように構成すると、WebLogic Serverによりweb.xml
およびweblogic.xml
デプロイメント記述子ファイルからセキュリティ・ポリシー情報が読み込まれます(web.xml
ファイルとweblogic.xml
ファイルの例については、例7-5と例7-6を参照)。この情報は、認可プロバイダのセキュリティ・プロバイダ・データベースにコピーされます。
例7-5 web.xmlファイルのサンプル
<web-app> <welcome-file-list> <welcome-file>welcome.jsp</welcome-file> </welcome-file-list> <security-constraint> <web-resource-collection> <web-resource-name>Success</web-resource-name> <url-pattern>/welcome.jsp</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>developers</role-name> </auth-constraint> </security-constraint> <login-config> <auth-method>BASIC</auth-method> <realm-name>default</realm-name> </login-config> <security-role> <role-name>developers</role-name> </security-role> </web-app>
カスタム認可プロバイダの開発の一環としてDeployableAuthorizationProviderV2
SSPIを実装し、カスタム認可プロバイダでデプロイ可能なセキュリティ・ポリシーをサポートする場合、カスタム認可プロバイダの構成担当者(つまり、開発者または管理者)は、WebLogic Server管理コンソールで「ポリシー・デプロイメントを有効化」チェック・ボックスがチェックされていることを確認する必要があります。チェックがはずれていると、認可プロバイダは「オフ」と見なされます。このため、複数の認可プロバイダが構成されている場合、「ポリシー・デプロイメントを有効化」チェック・ボックスを使用して、セキュリティ・ポリシーのデプロイメントに使用する認可プロバイダを指定できます。
WebLogic Server管理コンソールを使用してカスタム認可プロバイダを構成すると、必要な認可サービスにアプリケーションからアクセスできるようにすることはできますが、このセキュリティ・プロバイダに関連付けられたセキュリティ・ポリシーを管理する方法を管理者にも提供する必要があります。たとえばWebLogic認可プロバイダには、ポリシー・エディタ・ページが管理者向けに用意されており、様々なWebLogicリソースのセキュリティ・ポリシーを追加、変更、または削除することができます。
カスタム認可プロバイダを開発している場合、管理者はポリシー・エディタ・ページも認可サービスへのアクセスも利用できません。したがって、セキュリティ・ポリシーを管理するための独自のメカニズムを提供する必要があります。このメカニズムでは、カスタム認可プロバイダのデータベースのセキュリティ・ポリシー・データ(つまり式)を読み書きできなければなりません。
それには、以下の3通りの方法があります。
WebLogic Server管理コンソールとまったく別のツールを開発する場合には、この方法を選択します。
この方法では、カスタム認可プロバイダ向けにコンソール拡張を作成する必要も、管理MBeanを開発する必要もありません。ただし、ツールでは以下のことを行う必要があります。
WebLogicリソースのIDを特定します。IDがコンソール拡張によって自動的に提供されないためです。詳細については、「WebLogicリソース識別子」を参照してください。
セキュリティ・ポリシーを構成する式を表す方法を決定します。この表現は完全に任意であり、文字列である必要はありません。
カスタム認可プロバイダのデータベースの式を読み書きします。
WebLogic Server管理コンソールとは別のツールを持っており、それを管理コンソールから起動する場合には、この方法を選択します。
この方法の場合、ツールでは以下のことを行う必要があります。
WebLogicリソースのIDを特定します。IDがコンソール拡張によって自動的に提供されないためです。詳細については、「WebLogicリソース識別子」を参照してください。
セキュリティ・ポリシーを構成する式を表す方法を決定します。この表現は完全に任意であり、文字列である必要はありません。
カスタム認可プロバイダのデータベースの式を読み書きします。
『Oracle WebLogic Server管理コンソールの拡張』で説明されているように、基本的なコンソール拡張手法を使用して管理コンソールにリンクします。