この特集のトップページへ
Chapter 6:ビジネスロジックの設計



6)コンポーネントのセキュリティの設定
 次に,登録したコンポーネントのセキュリティを設定する。

 まず,DataObj.Customerコンポーネントであるが,これはBusiness.Customerコンポーネントとデータベースとのあいだを中継する働きを持つ。それゆえ,プレゼンテーション層から直接呼び出されることは避けたい。たとえば,Business.CustomerコンポーネントのAddCustomerメソッドには,ObjectContextオブジェクトのIsCallerInRoleメソッドを使って,「メソッドを呼び出したユーザーが特定のロールに属していなければエラーを発生させる」という実装をしたわけだが(List 6-8の19〜28行目),プレゼンテーション層が直接DataObj.Customerコンポーネントを実体化して利用してしまうと,このセキュリティチェックを経由せずにデータベースに対してアクセスできることになってしまう。

 そこで,DataObj.Customerコンポーネントを利用できるユーザーを,BusinessUserのみに限定する。先に述べたとおり,BusinessUserユーザーは,このCOMアプリケーションの実行ユーザーである。いい換えれば,このCOMアプリケーション内のCOMコンポーネントは,常にBusinessUserというユーザーによって実行される。したがって,BusinessUserというユーザーだけにDataObj.Customerコンポーネントの利用許可を与えれば,このCOMアプリケーション内のCOMコンポーネントだけがDataObj.Customerコンポーネントを利用できるようになる。それ以外の場合は,BusinessUserというユーザーによる呼び出しではなくなるので,DataObj.Customerコンポーネントを利用することはできない。その結果,プレゼンテーション層から直接DataObj.Customerコンポーネントを使用することもできなくなるのである。

 セキュリティを設定するためには,作成したBusinessSampleという名前のCOM+アプリケーションのプロパティで[セキュリティ]ページを開き,[このアプリケーションへのアクセスチェックを行う]を有効にする(Fig.6-28)。

Fig.6-28 COM+アプリケーションのプロパティの[セキュリティ]ページ
fig6_28

 そして次に,DataObj.Customerコンポーネントのセキュリティを設定する。ただし,COM+におけるセキュリティ設定はロールを対象としており,BusinessUserという実ユーザーに対して実行権限の有無を設定することはできない。そこで,BusinessRoleという名前のロール(ロール名は任意でかまわない)を新規に作成し,BusinessRoleにはBusinessUserユーザーをマッピングしておくことにする(Fig.6-29Fig.6-30)。

Fig.6-29 BusinessRoleロールの作成
fig6_29

Fig.6-30 BusinessRoleロールにBusinessUserユーザーをマッピングする
fig6_30a

fig6_30b

 BusinessRoleロールの追加とBusinessUserユーザーのマッピングが完了したら,DataObj.Customerコンポーネントのプロパティで[セキュリティ]ページを開き,[コンポーネントレベルでのアクセスチェックを行う]を有効にし,BusinessRoleのみにチェックを付ける(Fig.6-31)。この作業によって,DataObj.CustomerコンポーネントはBusinessRoleに属するユーザー,すなわちBusinessUserユーザーからしか利用できなくなる。

Fig.6-31 DataObj.Customerコンポーネントのプロパティ
fig6_31

 さて,次にBusiness.Customerコンポーネントのほうだが,これは若干考慮の余地がある。というのは,セキュリティを設定する方法としては,[コンポーネントサービス]管理ツールのロール設定によって利用できるかどうかを判断する方法と,プログラム側でロールを判定する方法の2通りがあるためである。

 List 6-8を例に考えてみよう。List 6-8の19〜28行目には,ObjectContextオブジェクトのIsCallerInRoleメソッドを使い,AddCustomerメソッドを呼び出したユーザーがSalesロールに属していなければエラーとなるような処理を実装した。これは,後者の例である。この部分を省き,[コンポーネントサービス]管理ツールでBusiness.Customerコンポーネントのプロパティの[セキュリティ]ページでSalesロールにしかチェックを付けなければ,同じようにしてアクセスを制限することができる(Fig.6-32)。これが,前者の例である。

Fig.6-32 Business.Customerコンポーネントのプロパティ
fig6_32

 では,プロパティで設定する方法と,プログラム側でObjectContextオブジェクトのIsCallerInRoleメソッドを使ってロールを判定する方法のどちらが好ましいのであろうか。それぞれのメリットとデメリットは,次のとおりである。

・プロパティで設定する場合

[メリット]

 どのコンポーネントのどのメソッドを呼び出せるのかを管理者側で自由に設定することができる。

[デメリット]

 個々のコンポーネントやコンポーネントに備わるメソッドに対して適切なロールを設定することは,コンポーネントやメソッドの数が多くなるにつれ,面倒な作業になる。また,管理者がコンポーネントの動作を熟知しているわけではないため,正しくないロールを設定してしまうおそれもある。

・プログラムで判断する場合

[メリット]

 プログラム側でロールを規定するため,管理者は個々のコンポーネントやメソッドについてロールの割り当てを逐一設定する必要がない。管理者がすべきことは,ロールに実ユーザーを割り当てるという比較的わかりやすい作業のみとなる。

[デメリット]

 ロール名がプログラム内で決められたものとなってしまうため,管理者がロール名やその役割を変更することができず,汎用性が低くなる。

 以上のメリットとデメリットを考えるに,汎用性と操作性という立場から見れば,プログラム側でロールによる識別をせず,管理者がプロパティとして設定できるようにしておいたほうが柔軟性が高いといえる。ただしこの場合,管理者が誤ったロールを設定することも考えられる。もっとも,COM+アプリケーションを納品する場合には,配布するCOM+アプリケーションにロールの設定も含まれるので,デフォルトのロール設定を保持したままCOM+アプリケーションを配布すれば,特別問題があるわけではない(実際にCOM+アプリケーションを配布する方法については,本連載の最後に扱う予定である)。


One Point! ただし,COMコンポーネントのメソッドで,Aというロールに属するユーザーが呼び出したならばXという処理,Bというロールに属するユーザーが呼び出したならばYという処理をするというように,ユーザーが属するロールによって実行する処理内容を変えたいという場合には,上記の説明の限りではない。この場合には,プログラム内でObjectContextオブジェクトのIsCallerInRoleメソッドを用いて条件判断するしか手はない。

 そこで,本サンプルでも,プログラムでロールを判断するのではなく,プロパティでロールを判断することにする。List 6-8は,ObjectContextオブジェクトのIsCallerInRoleメソッドを使ったロールの判定処理を含んでいるので,この部分をコメントアウトして無効化しておく(List 6-10)。

 List 6-10のように変更したことで,AddCustomerメソッドにおけるプログラム側でのロール判定は無効になった。つまり,管理者がBusiness.Customerコンポーネントのセキュリティを設定するときに,適切なロールを使うことで,利用の可否が決まるようになったわけである。

 では,[コンポーネントサービス]管理ツールを使って実際にBusiness.Customerコンポーネントのセキュリティを設定してゆく。

 Business.CustomerコンポーネントもDataObj.Customerコンポーネントと同様に,コンポーネントのプロパティの[セキュリティページ]でロールを設定してゆくことになる。Business.CustomerコンポーネントのAddCustomerメソッドを呼び出すことができるロールは,営業部のユーザーを示すSalesロール,営業部上司を示すSalesManagerロール,営業部の管理者を示すSalesAdminロール,そしてすべての操作を許された管理者であるAllAdminロール,という4つである。

 しかし,Business.Customerコンポーネントには,顧客を登録するためのAddCustomerメソッドだけでなく,顧客を参照するためのメソッドや削除するためのメソッドなども,のちに実装してゆく予定である。特に顧客の情報は,営業部だけではなく製品管理部や経理部などからも参照できなければ困るだろう。Business.Customerコンポーネントに対して,Salesロール,SalesManagerロール,SalesAdminロール,AllAdminロールにしか利用権限を与えないように設定した場合,Salesロール,SalesManagerロール,SalesAdminロール,AllAdminロールに属さないユーザーは,Business.Customerコンポーネントに備わるすべてのメソッドを呼び出すことができなくなってしまう。これでは,あとからBusiness.Customerコンポーネントに顧客情報を参照するメソッドを追加したとしても,製品管理部のユーザーや経理部のユーザーはSalesロール,SalesManagerロール,SalesAdminロール,AllAdminロールに属していないため,顧客情報を参照するメソッドを呼び出すことができなくなってしまう。

 そこで,Business.Customerコンポーネントについては,コンポーネントに対してロールを設定するのではなく,個々のメソッドごとにロールを設定するようにする。

 メソッド単位でロールによるセキュリティを設定するには,Business.Customerコンポーネントのツリーを展開してゆき,セキュリティを設定したいメソッドを右クリックし,表示されたメニューから[プロパティ]を選択する。ここではAddCustomerメソッドに対してロールによるセキュリティを設定したいので,AddCustomerメソッドを右クリックしてプロパティを開く(Fig.6-33)。

Fig.6-33 AddCustomerメソッドのプロパティを開く
fig6_33

 そして,開いたプロパティの[セキュリティ]ページにおいて,SalesSalesManagerSalesAdminAllAdminロールにチェックを付ける(Fig.6-34)。これによって,Business.CustomerコンポーネントのAddCustomerメソッドは,SalesSalesManagerSalesAdminAllAdminロールに属する者しか呼び出せなくなる。

Fig.6-34 AddCustomerメソッドのプロパティの[セキュリティ]ページ
fig6_34


One Point! メソッドのセキュリティ設定は,コンポーネントのセキュリティ設定が継承される。すなわち,Business.Customerコンポーネントに対して設定したセキュリティ情報は,Business.Customerコンポーネントに備わるAddCustomerメソッドにも適用されるということになる。 たとえば,AllAdminロールは,このサンプルアプリケーションに対するすべての操作を許可されたロールとして利用される。しかし,Business.Customerコンポーネントに対してAllAdminロールの権限を設定すれば,その設定が各メソッドに継承されるので,個々のメソッドのセキュリティ設定にAllAdminロールを含めなくともよい。AllAdminロールに属するユーザーは,Business.Customerコンポーネントに備わるすべてのコンポーネントのメソッドを呼び出せることになる。
7)コンポーネントの環境設定
 最後に,コンポーネントの各種プロパティを設定する。設定すべき主なプロパティとしては,トランザクションの設定が挙げられる。しかしここでは,Visual Basic上でクラスモジュールのMTSTransactionModeプロパティでトランザクションのデフォルト値を設定しているため,設定し直さなければならないということはない。

 なお,DataObj.Customerコンポーネントでは,データベース接続文字列をコンストラクタ文字列として指定できるようにしたので,必要があればコンストラクタ文字列にデータベース接続文字列を設定しておく。

prevpg.gif Chapter 6 13/92 nextpg.gif