From Documentation

Jump to: navigation, search




  • Author
    Robbie Cheng, Engineer, Potix Corporation
  • Date
    June 12, 2007
  • Version
    Applicable to ZK 2.4 and later.


Contents

Introduction

Nowadays,there is no difference between traveling in a jungle and using the Internet. Both of them are filled with danger and un-seeing threats. Thus,the importance of data security is never been neglected. Today, I am going to show you how to secure your data under the mechanism of Ajax with an demonstration of password encryption since password is always the most sensitive data and also always the target of hacker.


Problem

The ZK component being chosen to carry user's password is Textbox. Textbox is always suitable for user's input data, and it supports data-validation from both of the server-side and client-side. No doubt, in this case, we had better use client-side validation for avoiding user's password transmitted frequently in the internet between server and client. Besides, after validation, we have to encrypt user's password ,then transmit it back the server. But, how? What kind of event are you going to use? Most of your answer should be onChange event which is also the first answer fly into my mind. But, try to think about the behavior of onChange event which not only updates data in the server but also updates data at the client-side. And consider about this senario, if the user type his/her password, and press "submit" button, and all of sudden, his/her password is replaced with an encrypted data. Thus, we have to avoid the server from updating data in the client.


Solution

To secure user's password for avoiding sniffering, we have to deal with the above problems including client-side validation with Regular Expression and encryption, sending user's password back to server without updating data in the client by manually created Command which handles Ajax request of ZK.


Client-side Validation with Regular Expression

Though client-side validation had been supported by ZK for a long time, but there isn't a convinient mechanism for transforming more data to the Javascript funtion in the client. It's a relief that we can pass any number of parameter as we want to Javascript function since ZK 2.4. And, of course, we have to create one corresponding Javascript funtion.


1. create a customized constraint which implements both Constraint and ClientConstraint Interface

The first task is to implement an ClientSide Constraint as follows,


  • MyConstraint.java
public class MyConstraint implements Constraint,ClientConstraint{ 
	 //specity the name of Javascript funtion and pass required parameters
	 public String getClientValidation() {
		return "myvd(#{self},'^[\\\\w|\\\\W]{8,20}$')";
	  }      
	 // not necessay, it's ok to define error message in JavaScript function.
	 public String getErrorMessage(Component arg0) {
		return null;
	  }
//must return true, or user's data will be send back to server without encryption
public boolean isClientComplete() {
	return true;
}
//not necessay, it's for server-side validation
public void validate(Component arg0, Object arg1) throws WrongValueException {		
}
}

In MyConstraint.java, it invokes myvd function for client-side validation, and avoid server-side validation by returning true of isClientComplete method.


2. Create a corresponding JavaScript for validation

In above MyConstraint.java, it invokes myvd function, and pass two parameters. One is uuid of the textbox ,and the other is regular expression for validation. Thus, we should create an corresponding function as follows,


  • myvd.js
function myvd(comp,reg){ 
var reg = new RegExp(reg); 
var comp = $e(comp);
if (comp.value.match(reg))
   encryption(comp);			
else 
   return "password format is not correct!"; 
}

Client Side Encryption

In this example, user's password is encrypted with a md5 algorithm which is implemented by Henri Torgemane. Then, use zkau.send command to send data back to server with component's uuid, command name(or event name), and data. encryption.js

function encryption(comp){
    var data = MD5(comp.value);
    zkau.send({uuid: comp.id, cmd: "onEncryption", data: [data]},10);
}

onEncryption command is going to be implemeted in the following section for catching data at the server.


Update Data at Server Only

As mentioned in previous paragraph, we have to avoid the server to update data at the client after receiving user's encrypted password. First of all, we need to customize a command class which is responsible for dealing with event send from the client.


1. Create onEncryption Command

Thus, we are required to implement a command class as follows,


  • EncryptionCommand.java
public class EncryptionCommand extends Command {

protected EncryptionCommand(String evtnm, int flags) {
	super(evtnm, flags);
}

protected void process(AuRequest request) {
	final Component comp = request.getComponent();
	final String[] data = request.getData();

	// update value of Textbox at the server only
	final Textbox tb = (Textbox) comp;
	final String en = data[0];
	final Object xc = ((ComponentCtrl)tb).getExtraCtrl();
	if (xc instanceof Inputable)
		((Inputable)xc).setTextByClient(en);

	// post onEncryption event to ZK event queue
	Events.postEvent(new Event(getId(), comp));
}

}


2. Register onEncryption command in a Customized Textbox

After creating Encryption command, the second step is to register it in Textbox. Create a customized Textbox as follows,


  • MyTextbox.java
public class MyTextbox extends Textbox{

//register onEncryption command handler.
static{
	new EncryptionCommand("onEncryption",Command.IGNORE_OLD_EQUIV);
}

}

In MyTextbox.java, it declares a EncryptionCommand so ZK Update Engine will invoke EncryptionCommand to handle onEncryption command send from the client.

Demo

OK!It's time to enjoy grains of our hard-working. Let's write a small application to see if the result is what we desired.


  • pwd.zul
<zk>
<script type="text/javascript" src="md5.js"/>
<script type="text/javascript" src="myvd.js"/>
<script type="text/javascript" src="encryption.js"/>
<zscript>
  import org.zkoss.MyConstraint;
  
  MyConstraint myct = new MyConstraint();
</zscript>
<vbox>
username:<textbox/>
password:
<textbox use="org.zkoss.MyTextbox" '''constraint="${myct}"''' type="password"
'''onEncryption="alert(self.getValue())"'''/>
</vbox>
</zk>

If user's password doesn't pass the validation, it shows an error-message as Figure 1.

Error.jpg

Figure 1: error message

If user's password pass the validation, server will return an message with user's encrypted password as shown in Figure 2.


Encryption.jpg

Figure 2: encrypted password


Example Code

Download the example code here.

Summary

Thought as you might know that the most secure way to transfer data is through https protocol. However, it is also an interesting experience to do this encryption by yourslef for better understanding the mechanism of ZK. Have Fun!




Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.
You got stuck here?
Let us know how we can improve this page
For specific questions please use the forum