Secure ZK Component Events

From Documentation


Icon info.png Note: The content of this page has been deprecated/removed in the latest version.

Starting from ZK Spring 4.0.0 this feature has been removed. We recommend securing Spring Service Methods instead e.g. using Spring AOP.

Purpose

Secure certain ZK component event such as Button onClick event.


Example

This example is borrowed from the standard Spring Security tutorial sample and has been modified to work with ZK using ZK Spring Security. You can download the example codes from ZK Spring Essentials Google Code source repository here. You can see this example in action by deploying ZK Spring Essentials web archive and hitting example home page at http://localhost:8080/zkspringessentials/home.zul and you will see the following screen. home.zul page is configured to be accessible to anyone.

ZKSpringEssentials SecurityExampleHome.jpg

This table lists links to different pages that users can visit. The first row provides a way to access Account Listings page. On the account listings page there are buttons to credit or debit certain amount from the user accounts. But not all users should be allowed to credit/debit amounts form others accounts, right? So we need some way to secure these buttons in order to only certain users that have ROLE_TELLER to perform those operations. We will see how to achieve just that below. Once secured clicking any of the +$5,-$5,+$20 or -$20 buttons on account listings page should do two things. If users of this application are not logged in then it should request users to logon by showing an Ajax login popup. On successful login it should also check if user has certain role such as ROLE_TELLER to execute those credit/debit actions as identified by button click events. If not they should be shown a standard access denied page.

Let's take a look at an account listings page screen.

ZKSpringEssentials SecurityExampleListAccounts2.jpg


Click a button, and default login dialog shows up.

ZKSpringEssentials SecurityExampleSecureComponentEvents.jpg


Configuration

Now to make Ajax login popup work you need to configure certain ZK Spring Security custom filters in your Spring Configuration as shown below

    <http auto-config="true">
        <!-- Following is list of ZK Spring Security custom filters. 
            They needs to be exactly in the same order as shown below in order to work.  -->
        <custom-filter ref="zkDesktopReuseFilter" position="FIRST" />
        <custom-filter ref="zkDisableSessionInvalidateFilter" before="FORM_LOGIN_FILTER"/>
        <custom-filter ref="zkEnableSessionInvalidateFilter" before="FILTER_SECURITY_INTERCEPTOR"/>
        <custom-filter ref="zkLoginOKFilter" after="FILTER_SECURITY_INTERCEPTOR"/>
        <custom-filter ref="zkError403Filter" after="LOGOUT_FILTER"/>
    </http>

Let's take a look at account listings page first to better understand what componets and evetns we need to secure.

<?page id="testZul" title="Accounts" ?>
<?variable-resolver class="org.zkoss.spring.DelegatingVariableResolver"?>
<zk>
<window title="Accouts (Ajax popup login)" border="normal" width="500px">
    <zscript><![CDATA[
       void adjBalance(Button btn) {
           double bal = new Double((String)btn.getAttribute("bal")).doubleValue();
           bigbank.Account a = bankServiceScenario2.readAccount(btn.getAttribute("aid"));
           bankServiceScenario2.post(a, bal);
           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="/home.zul"/>
<button label="Logout" href="/j_spring_security_logout"/>
</zk>

As described earlier we need to secure credit/debit button onClick events in order to only allow users with ROLE_TELLER to perform actual credit/debit amount action. Note that how we have defined all credit/debit amount buttons with certain pattern. This is useful while configuring the security of onClick events of these button components as described below.

Moving onto configuration required to secure ZK component events, first we need to declare ZK Spring Security namespace at the top of the configuration file as shown below

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:zkc="http://www.zkoss.org/2008/zkspring/core"
    xmlns:zksp="http://www.zkoss.org/2008/zkspring/security"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
        http://www.zkoss.org/2008/zkspring/core http://www.zkoss.org/2008/zkspring/core/zkspring-core.xsd 
        http://www.zkoss.org/2008/zkspring/security http://www.zkoss.org/2008/zkspring/security/zkspring-security.xsd">
...
</beans:beans>

Next we will use ZK Spring Security configuration namespace element <zk-event /> and its sub element <intercept-event /> to define which components and events need to be secured. This works the same way as securing pages in standard Spring Security i.e. certain page url patterns are intercepted by Spring Security and checked againest logged in user's assigned authorities. Here too ZK Spring Security will intercept certain components events as identified by combination of "path" and "event" attributes of <intercept-event /> element.

     <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>

Here the path attribute value is identified ZK components by their id. As you can see it can be either a definitive component id or a pattern identifying a group of components. In our example account listings page all credit/debit amount buttons are declared with "btn" prefix so setting "path" to a patterns such as "//**/btn*" allows onClick event of any of these buttons to be intercepted by ZK Spring Security. Next we have set "access" attribute to "ROLE_TELLER" role which configures ZK Spring Security to allow onClick events of these buttons to proceed only if current logged in user has ROLE_TELLER role assigned to him.

Note that ZK Spring Security Ajax login popup window uses default Spring Security login page in the popup window. If you have declared a custom login page as described in the previous section then Ajax login popup can auto detect it from your <form-login /> login-page configuration.


Version History

Last Update : 2022/01/19


Version Date Content
4.0.0 2019/01 Feature removed



Last Update : 2022/01/19

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