ZK とスプリングセキュリティシステムで Lgin のAjax 化

From Documentation

Jump to: navigation, search
  • Author
    Henri Chen, Principal Engineer, Potix Corporation
  • Date
    October 13, 2008
  • Version
    Applicable to ZK Spring Integragion Library 1.0.0 (zkspring.jar) or later.
Applicable to ZK 3.0.9 and later.
Applicable to ZK 3.5.1 and later.
Applicable to Spring Security 2.0+


Contents

[hide]

イントロダクション

これは「如何にしてスプリングセキュリティ2.0を ZK Ajax フレームワークで動作させるか」シリーズの2番目の記事です。前回の記事では、従来のページ-ベースの Web アプリケーションを保護することだけを論じましたが、この記事では、如何にして Ajax の類のアプリケーションとして扱うことに焦点を置きます。
前回の記事と同様に、「とにかく動作させること 」のための手順に焦点を置きます。背景の事柄に興味がある場合は、ソースコードをチェックしてください。 :-).

デモ



このデモで見るように、別のログインページにチェンジするのではなく、ログインウィンドウが自動的にポップアップします。エンドユーザーは現在動作中の "Accounts" ページから離れることが無いので、より直感的で、インタラクティブになっています。

サンプル

これは前回の記事で使用されたのと同様のサンプルです。このオリジナルはスプリングセキュリティ2.0から供給されているチュートリアルサンプル(spring-security-2.0.3/dist/spring-security-samples-tutorial-2.0.x.war)です。基本的に私は /WEB-INF/jsp/listAccounts.zul を書き換えて、 -$20, -$5, +$5, と +$20 ボタンを onClick イベントでハンドルするようにしただけです。エンドユーザーがこれらのボタンを押したとき、何時でも関連する onClick イベントリスナーがコールされて、実行されます。そこで、ZK イベントプロセスインターセプターがこのようなイベントに介入して、必要なときにはログインウィンドウをポップアップさせます。

最小の <zk-event>構成

ZK はスプリングネームスペース構成メカニズムを採用していますので、必要なのは ZK イベントプロセスをイネーブルにすることだけで、セキュリティシステムの構築は以下のようにシンプルです。

/WEB-INF/applicationContext-security.xml
 
<!--
  - Spring namespace-based configuration
  -->
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:zksp="http://www.zkoss.org/2008/zkspring"
    xmlns:beans="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
        http://www.springframework.org/schema/security 
        http://www.springframework.org/schema/security/spring-security-2.0.1.xsd
        http://www.zkoss.org/2008/zkspring
        http://www.zkoss.org/2008/zkspring/zkspring.xsd">
 
    <http ...>
        ...
    </http>
    ...      
 
    <!--
      - Secure the ZK event processing per the event name and ZK component path pattern
      -->
    <zksp:zk-event login-template-close-delay="5">
        <zksp:intercept-event event="onClick" path="//**/btn_*" access="ROLE_TELLER"/>
        <zksp:intercept-event path="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    </zksp:zk-event>
 
</beans:beans>
  1. xmlns:zksp="http://www.zkoss.org/2008/zkspring" はスプリングセキュリティエンジンに我々が ZK ネームスペース構成を使用して、ネームスペースを zksp. に定義することを知らせます。
  2. http://www.zkoss.org/2008/zkspring http://www.zkoss.org/2008/zkspring/zkspring.xsd はスプリングセキュリティエンジンに ZK スプリングネームスペース構成スキーマを見つける位置を知らせます。
  3. <zksp:zk-event> これは、スプリングセキュリティエンジンに我々が ZK イベントプロセスをセキュアにしたいということを知らせます。このことにより、必要なフィルター、リスナーとスプリング゛ビーンを自動的に構成します。この例では login-template-close-delay="5"は ZK にログインが成功したとき、5秒で自動的にウィンドウを閉じることを指示します。ゼロの場合は直ちに閉じることを指示します。負の場合はユーザーのオペレーションを待ちます。
  4. <zksp:intercept-event event="onClick" path="//**/btn_*" access="ROLE_TELLER"/> はスプリングセキュリティエンジンにどの Zk イベントとコンポーネントをセキュアにしたいかを知らせます。この例では id が btn_ で始まる ZK コンポーネントで起動されたどの onClick イベントでも ROLE_TELLER 認証をチェックされることを意味します。
  5. <zksp:intercept-event path="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/> は全てのアノニマスユーザーが全てのイベントとコンポーネントにアクセスできることを意味します。
  6. 認証システムはスプリングセキュリティシステムの慣習に従います。ということは、 <zksp:intercept-event> ルールは1つずつ上から下へチェックさることを意味します。1つでもマッチするものがあれば、そこでストップして離れます。それ故、特殊な設定のルールは上で設定しておく必要があります。
  7. また、私たちは 以前の 記事でWEB-INF/zk.xml に ZK イベントスレッド問題をハンドルするための構成をすることを要請しました。 <zksp:zk-event> タグがこれらの構成を自動的にやってくれますので、この事について、知る必要はありません。
  8. WEB-INF/lib に ZK スプリング統合ライブラリー -- zkspring.jar を配備することを忘れないてください。全てのこれらのマジックはこの新規のライブラリーがやってくれるのです。

/WEB-INF/jsp/listAccounts.zul の書換え

これが私が、「如何にして ZK イベントプロセスをセキュアにするか」についてデモをするページです。これは主に全てのアカウントのリストを表示するもので、エンドユーザーは各アカウントのバランスをプラスしたり、マイナスする4つのボタンで変更できます。オリジナルの実装では、エンドユーザーがボタンを押すと、/post.html アクションページにリクエストがポストされ、 bankServer.post() メソッド( bigbank.BankService クラス内の)がコールされ、アカウントバランスを変更します。それから、これは再び全てのアカウントのリスト全体のページをリフレッシュします。

/WEB-INF/jsp/listAccounts.zul
Image:zkspringsec2-1.png

この場合、 bankServer.post() メソッドはスプリングセキュリティシステムによって保護されます。もし承認されていないユーザーがボタンを押すと、オリジナルの実装では、スプリングセキュリティシステムは別のログインページを表示し(そして、現在の Accounts ページから離れます。)、ユーザーにログインを促します。ログインが成功した後はセキュリティシステムはブラウザを元のページにリダイレクトします。
ここでは、このページの書換えをし、Ajax 化しました。エンドユーザーがボタンを押すと、onClick イベントリスナーがコールされ、変更されたアカウントバランスのみが変更されます。ここではページ全体がリフレッシュされる必要はありません。 それでは如何にして ZK はエンドユーザーに現在のページから離れずにログインさせることが出来るのでしょうか?ログインウィンドウをポップアップするので、ユーザーはデモビデオで見るようにこのポップアップされたログインウィンドウでログインすることが出来ます。

/WEB-INF/jsp/listAccounts.zul
 
<?variable-resolver class="org.zkoss.spring.DelegatingVariableResolver"?>
<zk>
<window title="Accouts" border="normal" width="500px">
    <zscript><![CDATA[
       void adjBalance(Button btn) {
           double bal = new Double((String)btn.getAttribute("bal")).doubleValue();
           //get the account object
           bigbank.Account a = bankService.readAccount(btn.getAttribute("aid"));
           //change the account balance
           bankService.post(a, bal);
           //update the account balance on the browser
           btn.getFellow("bal_"+a.getId()).setValue(""+a.getBalance());
       }
    ]]>
    </zscript>
    <grid>
        <rows>
            <row forEach="${accounts}">
                <label value="${each.id}"/>
                <label value="${each.holder}"/>
                <label id="bal_${each.id}" value="${each.balance}"/>
                <button id="btn_m20_${each.id}" label="-$20" onClick="adjBalance(self)">
                    <custom-attributes aid="${each.id}" bal="-20"/>
                </button> 
                <button id="btn_m5_${each.id}" label="-$5" onClick="adjBalance(self)"> 
                    <custom-attributes aid="${each.id}" bal="-5"/>
                </button> 
                <button id="btn_p5_${each.id}" label="+$5" onClick="adjBalance(self)"> 
                    <custom-attributes aid="${each.id}" bal="5"/>
                </button>  
                <button id="btn_p20_${each.id}" label="+$20" onClick="adjBalance(self)"> 
                    <custom-attributes aid="${each.id}" bal="+20"/>
                </button> 
            </row>
        </rows>
    </grid>
</window>
<button label="Home" href="/index.zul"/>
<button label="Logout" href="/j_spring_security_logout"/>

ここで、このユースケースのプロセスシーケンスについてちょっと簡単に説明します。
Here I brief a little bit the process sequence of this use case:

  1. エンドユーザーがボタンを押すと、onClick イベントが起動されます。
  2. ZK イベントプロセスセキュリティシステムがそのイベントが保護(<intercept-event>)されているか、上から下までチェックします。
  3. イベントが指定されたイベント("onClick")にマッチしていて、コンポーネントの id が指定されたパス(//**/btn_*, btn_でスタートする)にマッチしていれば、 ZK イベントプロセスは保護されなければなりません。
  4. ユーザーが承認されているかおよび承認されている権限をチェックします。 (ROLE_TELLER)
  5. ユーザーが承認されていなければ、ログインウィンドウをポップアップします。
  6. エンドユーザーはユーザー id とパスワードをキー入力し、ログインフォームを送信します。
  7. スプリングセキュリティシステムは承認手続きを実行し、成功します。
  8. ログインウィンドウはログイン成功ページを表示します。
  9. システムはログインの成功後 5 秒でログインウィンドウを閉じるように構成してあるので、カウントダウンが開始され、自動的に閉じます。
  10. エンドユーザーが再びボタンをクリックすると、今度は承認手続きをパスして adjBalance() メソッドに進みます。
  11. adjBalance メソッド内では、我々は bankService.post() メソッドをコールしてアカウントバランスを更新します。我々が bankService スプリングビーンに直接参照できることに注目してください。これはページ内でスプリングビーンレゾルバを使用するように設定しているからです。 (<?variable-resolver class="org.zkoss.spring.DelegatingVariableResolver"?>
  12. そうして我々はアカウント バランス ラベルを更新できるのです。(ページ全体のリフレッシュ無しに)


サマリー

我々は ZK イベントプロセスをセキュアにすることが如何に容易であるかをデモンストレーションしました。やらなければいけないことはスプリングセキュリティ構成ファイル内で、 <zk-event> 構成タグを宣言するだけです。 ZK イベントに不慣れであっても OK です。更にスプリングの @Secured アノテーションでサービスレイヤーのメソッドもセキュアにできます。メソッドが ZK イベントリスナー内で呼ばれている限り、 ZK イベントセキュリティシステムはこれらを自動的にハンドルします。
ZK とスプリングセキュリティ2.0 を一緒に動作させることは最初のステップで説明したとおりです。ZK チームは ZK とスプリングフレームワークとの統合をできるだけ容易なものにする努力を続けています。現在 ZK はバリアブルレゾルバーメカニズムによって容易にスプリングビーンを参照できますが、まだどうしてもスプリングビーンを ZK コンポーネント内に注入できないでいます。これからもこの問題に注力して解決の努力をします。ZK スプリング統合をより良いものにするために、皆さんからのフィードバックをお待ちしています。


ダウンロード

サンプル codes(.war file)のダウンロード。




Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.