ZappWeb a secured ZK web framework
Ramzi Maâlej
June 18, 2009
ZK 3.6.1
Introdution
This small talk is intended to provide you a web framework to start building secure web applications. The idea behind this is to provide something similar to Appfuse that uses Zkoss as front end/ presentation layer. It is also based on the two small talks writen by Henri Chen showing how to integrate Spring security with Zkoss: Making Spring Security Work with ZK and Ajax Based Login with ZK and Spring Security System. It's doesn't include yet appgen to generate the redundant stuffs.
Prerequisites
Spring framework version 3.0.0
Spring security 3.0.0
Zkoss 3.6.1
Example
The example consists of securing the access to the private section by configuring the authentication provider to use DaoAuthenticationProvider to load authentication's informations from database. For this reasons, you have to write two classes User which implements UserDetails interface and Role which implements GranthedAuthority. Theses classes are fit in the model package. Second, you need to develop the DAO layer (look at dao package). Finally, we write the service layer (look at service layer).
Configuration
First of all, as said in the previous small talks, we need to configure zk to work with spring. In zk.xml you should have the following lines
<?xml version="1.0" encoding="UTF-8"?>
<!--
Created by ZK Studio
-->
<zk>
<system-config>
<disable-event-thread/>
</system-config>
</zk>
After that, put in your web.xml the followings lines
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--
- Spring Security Filter Chains
-->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
In the next step we will configure a data connection to be used by JPA. Your applicationContext-jpa.xml should look like this one
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/lms" />
<property name="username" value="ramzi" />
<property name="password" value="kantoul" />
</bean>
<!-- JPA EntityManagerFactory -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="true" />
<property name="database" value="MYSQL" />
<property name="showSql" value="true" />
</bean>
</property>
<property name="loadTimeWeaver">
<bean
class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" />
</property>
</bean>
<!--
Transaction manager for a single JPA EntityManagerFactory (alternative
to JTA)
-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- post-processors for all standard config annotations -->
<bean
class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
<!--
Instruct Spring to perform declarative transaction management
automatically on annotated classes.
-->
<tx:annotation-driven transaction-manager="transactionManager" />
<!--
Activates various annotations to be detected in bean classes: Spring's
@Required and @Autowired, as well as JSR 250's @PostConstruct,
@PreDestroy and @Resource (if available) and JPA's @PersistenceContext
and @PersistenceUnit (if available).
-->
<context:annotation-config />
We define a datasource bean to connect to the database and then we define the EntityManagerFactory to use this datasource with the JPAVendor.
Finally, we need to add some stuffs to applicationContext-security.xml.
<security:http>
<security:intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
<security:intercept-url pattern="/login.zul" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<security:intercept-url pattern="/admin/**" access="ROLE_ADMIN" />
<security:intercept-url pattern="/privatesection.zul" access="ROLE_ADMIN" />
<security:form-login login-page="/login.zul" default-target-url="/privatesection.zul" authentication-failure-url="/accessDenied.zul"/>
<security:concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true"/>
<security:remember-me/>
<security:logout logout-success-url="/login.zul"/>
</security:http>
<beans:bean id="passwordEncoder"
class="org.springframework.security.authentication.encoding.Md5PasswordEncoder" />
<security:authentication-provider user-service-ref="myUserDao">
<security:password-encoder ref="passwordEncoder"/>
</security:authentication-provider>
First, we define the access roles to the various sections. As we see, /admin folder and privatesection.zul are protected and need ROLE_ADMIN role to be accessible, otherwise an exception will be generated and the user will be redirected to accessDenied.zul. We define the authentication-provider that refers to myUserDao. This bean must implements UserDetails interface. Finally, we define the passwordEncoder since the passwords are encoded with md5 algorithm.
Source files
The project can be downloaded from here. It's an Eclipse project, you can import it directly into your workspace. All jar files was removed for faster download
Conclusion
This small talk aims to provide you a basic framework which regroup the most powerful web framework to start building Ajax based web applications. It still need improvements but I believe that it's a good start point. Your comment and suggestions are welcome at ramzi.maalej@gmail.com.
Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License. |