※ 本記事は2017年3月16日に公開されたものです。
かなり前置きが長くなりましたが、いよいよ仮想プライベートデータベースでWEBアプリケーションごとのアクセス制御を実施してみます。今回はWebLogic Serverを利用しますので、第14回の「実際の利用者をデータベースに伝播する ~ セッション情報」でも紹介した「接続時にクライアントIDを設定」機能を利用することで、特別なコーディングなく実現できます。
それでは実際にWEBアプリケーションの実行結果から見てみましょう。
satoでログイン
itoでログイン
アプリ実行画面右上ヘッダ部分ににアプリケーションユーザー名が表示されています。これはrequest.getRemoteUser()メソッドで取得したWeblogic Serverで認証されたユーザーの名前です。
アプリ本文の上から3行はデータベースのセッション情報です。上から順番にsys_context(‘userenv’,’session_user’)で取得した接続データベースユーザー名、sys_context(‘userenv’,’client_identifier’)で取得したクライアント識別子、sys_context(‘userenv’,’client_program_name’)で取得したプログラム名を表示しています。
その下にAPP1.TESTTAB表への絞り込み条件を指定しないSQL文(select name from app1.testtab)で取得した結果を表形式で表示しています。
このアクセス制御を実現するためのファイングレインアクセスコントロールのポリシーファンクションは第30回の「仮想プライベートデータベース (4) ~ アプリケーションユーザーごとのアクセス制御の実装方法」で作成したものをそのまま利用しています。データベースには手を加えずに、WEBアプリケーションを開発してWebLogic Serverにデプロイしただけです。WebLogic Server側のユーザー認証の設定に関する詳しい説明はこのブログでは省略しますが、今回WebLogic Serverで実施した作業は以下の通りです。
- ユーザーとグループの追加
satoとitoのふたりのユーザーを追加して、新しく作成したvalid_userというグループのメンバーに登録しました。


- データソースの追加
JNDI名が「jdbc/dbsecnavi」というデータソースを作成しました。データベースにはAPP1USERで接続し、プログラム名は「dbsecnavi sample application」とし、「接続時にクライアントIDを設定」機能を利用するための設定をおこないました。



- アプリケーションのデプロイ
参考までにJDevelopperで作成したアプリケーションのソースを公開します。私はプログラミングは得意ではない(どこかからサンプルプログラムを探して、コピペ・編集してアプリを作るレベル)なので、ソースコードが読みづらい部分もあるとは思いますがご了承ください。
アプリケーションのデプロイ後、デプロイしたサーバーの/dbsecnaviにアクセスするとメニューページが表示され、「vpd sample application」をクリックすると、ログイン画面を経て、最初に紹介したアプリケーションのページが表示されます。
メニューページ
さて、ここまでの手順でアプリケーションユーザーごとのアクセス制御は実現できたのですが、このままではアプリケーション用のAPP1USERでSQL*Plusを利用してデータベースに接続されてしまうと、DBMS_SESSION.SET_IDENTIFIERプロシージャで自由にユーザー名を設定されて、結局すべてのユーザーになりすまされてデータを見られてしまいます。最後にアプリケーションユーザーであっても、今回作成したアプリケーション以外にはデータを戻さないように制限をかけるようにファイングレインアクセスコントロールのポリシーファンクションを変更します。追加したコードは赤字で示した部分です。
create or replace function app1.vpdfunc (v_schema varchar2, v_objname varchar2) return varchar2 is begin if upper(sys_context('userenv','session_user')) = 'PUKU' then if sys_context('userenv','ip_address') = '10.185.155.180' and sys_context('userenv','client_program_name') like 'sqlplus%' then return '1=1'; else return '0=1'; end if; elsif upper(sys_context('userenv','session_user')) = 'APP1USER' then if sys_context('userenv','client_program_name') = 'dbsecnavi sample application' then return 'name = upper(sys_context(''userenv'',''client_identifier''))'; else return '0=1'; end if; else return 'name = upper(sys_context(''userenv'',''session_user''))'; end if; end; /
上記の設定でSQL*PlusからAPP1USERで接続されても、アプリのデータは見れなくなりました。
たとえば、マイナンバーの運用が始まった時にマイナンバーは限定された人しか見れないようにしなければならないというルールができました。ひとつの表のなかに様々な個人情報とともにマイナンバーも格納されている場合、マイナンバー列だけは限られた人しか見れないようにしなければなりません。
たとえば、個人情報保護法改正で何が個人情報にあたるかが厳密に定義され、「特定の個人を識別できるメールアドレス」も個人情報であり保護する必要があることになっています。今後はメールアドレスも業務上必要な時以外は見れないように保護する必要があります。
次回はこのようなケースに対応するための、仮想プライベートデータベースの列レベルのアクセス制御について説明します。



