チュートリアル5(Gate)

例えばカード決済処理の決済ボタンがあるとします。
ブラウザには「戻る」機能があるため、決済後に「戻る」をし、再度決済ボタンを押す事が可能です。
もし不適切な内部実装であれば、2重に決済してしまう可能性があります。

今回は、ログイン後の Hello 画面から「戻る」を行ってログインしようとした場合に限り、403 Forbidden を返してみます。
Gate クラスには次のメソッドが準備されています。

tutorial1/Gate.java①
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
    /**
     * 不正呼び出しの検出通知。
     * @param ir 検出内容。
     * @param req リクエスト。
     * @param from 遷移元ページ。
     * @param to 遷移先ページ。
     * @return 処理の変更指示。nullなら、通常通りに動作します。
     */
    public Forward onIllegalRequest( IllegalRequest ir, RequestParameter req, Page from, Page to ){
        // nullを返せば、通常と同じ処理がなされます。
        // fromやtoの内容により、処理の中断が必要であれば、null以外の
        // 遷移先を返して下さい。
        // 遷移先ページを指定すると、input()は呼ばれず、output()を
        // コールします。
        return null;
    }

irには何が発生したかが設定されています。

1 REPEAT_SAME_REQUEST 今回の「戻る」の後の再押下のようなケースです。
ただし検出には、Page#isCheckRepeatSameRequest()でtrueを返す必要があります。
処理済みリクエストの再呼び出し。
2 NOT_FOUND_HISTORY ブラウザにURLを入力して
http://localhost:8080/tutorial1/lu.tmzfgi.mo.i8qot9.on.ex257q.na
を直接開いたとします(ログイン画面→Hello画面 を表すURL)。
この時、ログイン画面は履歴に存在しません。
不正アクセスが想定されます。
呼び出し元ページが履歴に存在しない。
3 SESSION_ERROR セッション自体が存在しない場合です。
しばらく操作しないでタイムアウトとなってしまったか、不正アクセスが想定されます。
セッションが存在しないかタイムアウト。

次のような実装になります。

tutorial1/Gate.java②
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
    public Forward onIllegalRequest( IllegalRequest ir, RequestParameter req, Page from, Page to ){
        // nullを返せば、通常と同じ処理がなされます。
        // fromやtoの内容により、処理の中断が必要であれば、null以外の
        // 遷移先を返して下さい。
        // 遷移先ページを指定すると、input()は呼ばれず、output()を
        // コールします。
        switch( ir ) {
        case REPEAT_SAME_REQUEST:
            if ( from.getID() == PageType.LOGIN_HTML ) {
                return new Forward( 403 );
            }
            break;
        }
        return null;
    }

今回はこのようにしましたが、通常では ir が REPEAT_SAME_REQUEST かどうかはクリティカルな画面のみで確認するようにし、あらゆる不正アクセスに対してはエラーページ(「時間が過ぎたためログアウトしました」等)へ Forward させる実装が自然でしょう。
特にそこまでのセキュリティを要求しなければ無視して常に null を返しても良いでしょう。
ただしその場合(NOT_FOUND_HISTORY や SESSION_ERROR)は履歴に過去のページが存在しないため、新規インスタンスを使って処理されます。

チュートリアル6(SuperPage)