2020年7月3日金曜日

特定のページへの直リンクによるアクセス(3) - 直リンクの少し凝った設定

ひとつ前の記事でページを保護するためにOracle APEXが提供している機能について説明しました。この記事では、直リンクの少し凝った設定について説明します。

直リンクのURL形式


説明では以下の直リンクを使うことにしていました。
https://apex.oracle.com/pls/apex/f?p=demo-tasks:task:::::P3_ID:1
https://apex.oracle.com/pls/apex/f?p=アプリケーション名(またはID):ページ別名(またはID):::::アイテム名(複数):値(複数)
実際のところ、上記の形式はURLとして一般的ではありません。Oracle APEX 20.1では簡易URL(Friendly URLs)という設定が導入され、Oracle APEXのアプリケーションへのアクセスを、より一般的な形式のURLにて行えるようになっています。
https://apex.oracle.com/pls/apex/japancommunity/r/demo-tasks/task?p3_id=1
https://apex.oracle.com/pls/apex/ワークスペース名/r/アプリケーション名/ページ別名?アイテム名=値
設定箇所はアプリケーション定義プロパティです。


今回のケースもそうですが、通常、ページ・アイテムにはPページ番号_というプリフィックスを付ける慣習があります。ですので、直リンクのURLに含まれるページ・アイテムはP3_IDととなっています。しかし、直リンクは変更せずに宛先のページだけ置き換えようとすると、ページ自体は別名を新たなページに付け替えることで対応できますが、ページ・アイテム名は(ページ番号が変わるため)変更せざるを得ません。

直リンクではP3_IDではなく、IDとして指定できるとURLがすっきりします。
https://apex.oracle.com/pls/apex/japancommunity/r/demo-tasks/task?id=1
ページ・アイテムにページ番号がプリフィックスとして付けられるのは必須ではないので、P3_IDをIDに変更することはできます。しかし、そうするとページ・ウィザードによって作成されたあらゆる部分をレビューして、P3_IDをIDに変更する必要が出てきます。これは大変な作業になりますし、変更した後はどのページのページ・アイテムか分からなくなるため、それ以降の開発に悪い影響を与えます。

アプリケーション・アイテムを使った直リンクの実装


アプリケーション・アイテムとしてIDを作成することで、上記の問題を回避することができます。

共有コンポーネントアプリケーション・アイテムを開きます。


登録済みのアプリケーション・アイテムがリストされます。新規にアプリケーション・アイテムを作成するには、作成をクリックします。


名前IDとします。有効範囲は、アプリケーションとグローバルの2種類から選択できます。複数のアプリケーションでセッションを共有していないので、アプリケーションを選択します。セッション・ステート保護制限なしを選びます。アプリケーション・アイテムの作成をクリックすれば、作成完了です。


次に宛先となるページをページ・デザイナで開きます。フォームが初期化される前に、IDとして受け取った値をページ・アイテムP3_IDへ代入するプロセスを登録します。

初期化フォームタスク詳細(タスク詳細というリージョン名のフォームを初期化するプロセス)より先に実行されるようにプロセスを作成します。

名前直リンク対応とし、タイプPL/SQLコードソースとして以下のPL/SQLコードを指定します。
:P3_ID := :ID;
最後にサーバー側の条件として、IDに値が設定されている(URLにIDが含まれている)ときに実行されるよう、タイプアイテムはNULLではないアイテムIDと設定します。


これで、直リンクのURLで、P3_IDの代わりにIDを使用することができます。また、P3_IDのセッション・ステート保護チェックサムが必要 - セッション・レベルに維持することが可能です。ページ・アクセス保護制限なしです。

宛先ページの新設による実装


直リンクの宛先となるページを別に作成して、そのページからブランチを経由して実際のページを表示させるという実装も可能です。(以下の実装はアプリケーション・アイテムIDとそれを使うプロセスの設定がされていない状態から始めます)。

直リンクの宛先とする全く空のページを作成します。ページの作成をクリックします。


空白ページをクリックします。


名前targetとし、作成されるページに静的リージョンをひとつ含めます。をクリックします。


ナビゲーションのプリファレンスは、このページとナビゲーション・メニュー・エントリを関連付けないを選びます。をクリックします。


確認をして終了をクリックします。


空白のページができたので、ページ・アイテムを作成します。名前IDとします。タイプテキスト・フィールドです。静的リージョンとページ・アイテムではなく、先ほどと同様に、アプリケーション・アイテムを使用することもできます。用途が特別なページなので、ページ・アイテムにページ番号のプリフィックスが無くても、混乱することはありません。


ヘッダーの前にブランチを作成します。ヘッダーの前でコンテキスト・メニューを表示させ、ブランチの作成を実行します。


作成したブランチは名前直リンク対応とし、動作タイプページまたはURL(リダイレクト)を指定します。


ターゲットとして、実際に表示されるページ3アイテムの設定として、P3_IDIDを渡すように設定します。


最後にページのセキュリティ設定を調整します。ページの別名を確認したのち(この場合target)、認証パブリック・ページにするか、もしくは、ディープ・リンク有効にして、ページ・アクセス保護制限なしにします。


認証パブリック・ページの場合は、認証なしで上記のページの処理が始まります。そして、すぐにブランチが呼び出され、そこで認証が要求されます。認証認証が必要なページディープ・リンク有効な場合は、認証が行われてから上記のページに戻ります。すでに認証されているので、ブランチが呼び出されても追加の認証は発生しません。アプリケーションにパブリック・ページを含めたくない場合は、後者の設定になるでしょう。

こうして作成したページを宛先にした直リンクのURLは以下になります。
https://apex.oracle.com/pls/apex/japancommunity/r/demo-tasks/target?id=1
新たにページを作り、ブランチ経由で本来の宛先ページにアクセスするため、本来のターゲットであるページの、ページ・アクセス保護引数にチェクサムが必要に戻すことが可能です。


まとめ


前回はページを保護する機能について説明し、その保護を外していくことで直リンクを有効にしました。今回は保護を外していくだけではセキュリティ上の懸念が増すため、できるだけ保護を外さずに、追加の実装で直リンクを有効にする方法を紹介しました。特に宛先ページを新規作成し、そこからブランチさせる実装は、ブランチが呼び出される前に色々な検証コードを追加できるため、より安全なアプリケーションを作成することが可能になります。