Customize Your ZK Pages Per Spring Security Authority Roles

From Documentation
DocumentationSmall Talks2010AprilCustomize Your ZK Pages Per Spring Security Authority Roles
Customize Your ZK Pages Per Spring Security Authority Roles

Author
Henri Chen, Principal Engineer, Potix Corporation
  • Ashish Dasnurkar, Engineer, Potix Corporation
Date
Updated February 5, 2010
  • Updated April 20, 2010 to make it work with ZK Spring integration library 3.0RC
Version
Applicable to ZK Spring Integragion Library 3.0RC or later.
Applicable to ZK 3.0.9 and later.
Applicable to ZK 3.6.2 and later.
Applicable to ZK 5.0 and later.
Applicable to Spring Security 3.0 and later

Introduction

This is the third articles in a series regarding how to make Spring Security 2.0.x work with ZK Ajax framework. In the previous two articles ( this and this ), we have discussed how to protect a web page and how to deal with Ajax kind of requests, respectively. In this article, we will tell you how to customize a ZK page per the login user by hiding/disabling some components. For example, you might want to hide/disable a button that only an administrator is allowed to see when a common user is logged in.

demo

The Example

We still use the same example as used in the previous two artices. It is origined from the tutorial sample(spring-security-2.0.3/dist/spring-security-samples-tutorial-2.0.x.war) provided by Spring Security 2.0. We mainly rewrite all .jsp pages into .zul page. Change some "form-action" links to corresponding ZK event triggered button, etc... And we introduced the ZK Spring Security Tag Libraries this time so we can show/hide/enable/disable some parts of the .zul page per the login user.

The Implicit "authentication" Object

We introduce a new ZK Spring Security implicit object, "authentication". When any user login(including anonymous login) and you can access to the associated Spring Security Authentication object in EL expression, zscript, or ZK annotate data binding expression.

WebContent/secure/index.zul

<?page title="Secure Page"?>
...
<?variable-resolver class="org.zkoss.spring.DelegatingVariableResolver"?>
<window title="Secure Page" border="normal" width="500px" xmlns:n="http://www.zkoss.org/2005/zk/native">

...

<n:h4>Properties obtained using implicit Object <n:b>"authentication"</n:b>.</n:h4>
<grid>
	<columns>
		<column label="Expression"/>
		<column label="Value" width="50px"/>
	</columns>
	<rows>
		<row><label value="authentication.name"/>${authentication.name}</row>
		<row><label value="authentication.principal.username"/>${authentication.principal.username}</row>
		<row><label value="authentication.principal.enabled"/>${authentication.principal.enabled}</row>
		<row><label value="authentication.principal.accountNonLocked"/>${authentication.principal.accountNonLocked}</row>
	</rows>
</grid>

...

</window>

As you can see in the example code. Provides the variable resolver then we can access the "authentication" implicit object.

<?variable-resolver class="org.zkoss.spring.DelegatingVariableResolver"?>

You can use the intuitive "a.b.c" form to access properties of the Authentication object in EL expression.

${authentication.principal.username}

The ZK Spring Secuirty Utility Library

Besides that, we also provide a security utility library that you can use with ZK component's "if", "unless", etc. to show/hide/enable/disable some specific ZK components.

WebContent/secure/index.zul

<?page title="Secure Page"?>
<?taglib uri="http://www.zkoss.org/zkspring/security" prefix="sec"?>
...
<window title="Secure Page" border="normal" width="500px" xmlns:n="http://www.zkoss.org/2005/zk/native">

...

<zk if="${sec:isAllGranted('ROLE_SUPERVISOR')}">
	You are a supervisor! You can therefore see the <n:a href="extreme/index.zul">extremely secure page</n:a>.
</zk>

<zk unless="${sec:isAllGranted('ROLE_SUPERVISOR')}">
	You are NOT a supervisor! You can NOT see the <n:a href="extreme/index.zul">extremely secure page</n:a>.
</zk>

...

</window>

Specify the security utility library then use functions defined.

<?taglib prefix="sec" uri="http://www.zkoss.org/zkspring/security"?>

There are now total five functions that you can use in EL expression.

<zk if="${sec:isAllGranted('ROLE_SUPERVISOR')}">
	You are a supervisor! You can therefore see the <n:a href="extreme/index.zul">extremely secure page</n:a>.
</zk>
<zk unless="${sec:isAllGranted('ROLE_SUPERVISOR')}">
	You are NOT a supervisor! You can NOT see the <n:a href="extreme/index.zul">extremely secure page</n:a>.
</zk>

The expression "sec:isAllGranted('role1,role2, ...')" will check whether the currently authenticated user has ALL roles specified in the isAllGranted() function and return true or false. Then according to the if/unless condition statement, the corresponding part of the page is thus rendered. You can also provide such expression to other ZK components. e.g. if a button shall only show to a supervisor user:

<button label="Transfer Money" if="${sec:isAllGranted('ROLE_SUPERVISOR')}" .../>

Or if you just want to disable the button but still visible to non-supervisor user.

<button label="Transfer Money" disabled="${sec:isNoneGranted('ROLE_SUPERVISOR')}" .../>

What If I Want to Do it With Pure Java

The example we have shown are all .zul pages. "What if I would like to construct my pages with pure Java?" you might ask. We actually provide a org.zkoss.spring.security.SecurityUtil class that you can call static methods to access all functions. e.g.

if (SecurityUtil.isAllGranted("ROLE_SUPERVISOR")) {
	Button btn = new Button();
	...
	btn.setParent(win);
}

Functions of ZK Spring Security Utitlity Library (org.zkoss.spring.security.SecurityUtil):

  • boolean isNoneGranted(String authorities): Return true if the authenticated principal is granted NONE of the roles in the specified authorities.
  • boolean isAllGranted(String authorities): Return true if the authenticated principal is granted ALL of the roles in the specified authorities.
  • boolean isAnyGranted(String authorities): Return true if the authenticated principal is granted ANY of the roles in the specified authorities.
  • boolean isAccessible(String hasPermission, Object domainObject): Return true if the current Authentication has one of the specified permissions to the presented domain object instance.
  • Authentication getAuthentication(): Return currently login Authentication (similar to implicit "authentication" object).

Summary

We have demonstrated how easy it is to customize your ZK page per the login user role. All you have to do is to use the variable resolver and security utility library. Then it is your imagination to design your page. Note that handling view page doesn't mean that you don't have to take care the business logic security accordingly; especially in the Web programming environment. In your server side action method, it is a good practice to always check the security authority against the current login user.

We will continue on making integrating ZK and Spring Framework as easy as possible. Now the ZK team is investigating easy ways to write View in ZK, Controller in Spring, and Model in Hibernate/JPA as in MVC design pattern. I will expect Java annotation and variable injection(auto-wiring) to be used widely. Then programmer can focus more on the business logic than on time-wasting boilerplate codes.

We welcome your feedback and suggestions so we can make ZK Spring Integration better.

Download




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