« December 2007 | Main | February 2008 »

January 2008 Archives

January 4, 2008

Granite Data Services 1.0.0 RC1

Granite Data Services (GDS) is a open source alternative to Adobe® LiveCycle® Data Services for J2EE application servers that provides a framework for Flex 2/EJB3/Spring/Pojo application development over AMF3. Recently GDS has been released in version 1.0.0 RC1, with major improvements since the last version. This release candidate introduces data push for Granite, based on Comet, and also enhances Granite's integration with Spring and Seam.

One of the new features in GraniteDS is the use of data push, code name Gravity, which has been implemented using the Comet architecture (http://en.wikipedia.org/wiki/Comet_%28programming%29) and is working on Tomcat6 and Jetty6 containers. The data push uses Tomcat's CometProcessor (http://wiki.apache.org/tomcat/WhatIsComet) and Jetty's Continuation (http://docs.codehaus.org/display/JETTY/Continuations), which are experimental implementations as currently is Granite's approach. Nevertheless the feature has a good potential as it uses AMF3 over HTTP to transfer data.
The Flex client uses its own implementations of a Producer and Consumer, org.granite.gravity.Consumer and org.granite.gravity.Producer, but their functionality is similar to LiveCycle Data Services Consumer and Producer: they allow the producer to connect to a destination and the consumer to subscribe to a topic on a destination. Destinations as usual are configured in services-config.xml and, for a messaging destination, a GravityChannel over AMF3 must be configured to enable data push functionalities. More information on the implementation can be gathered from the source code and from the Granite community, before a version 1 documentation is released.

The Granite community also completed Granite's integration with the Spring framework and now supports security issues; Granite integrates with JBoss Seam too (http://www.jboss.com/products/seam), providing a good coverage on the major frameworks in the JavaEE development world. They also announce that their GAS3 java to actionscript code generator also brings extended support for Java Enum.
This release is not final, anyway, but it is possible to try out their samples from http://www.graniteds.org while waiting for the final version to be released.
GraniteDS brings data push to the open source community, but in a different manner than Adobe BlazeDS, which relies on HTTP streaming; we will be able to know more when BlazeDS will release the sourcecode (http://labs.adobe.com/technologies/blazeds/).

January 13, 2008

Flash and cross-domain AJAX security

Ajax applications using the standard XMLHttpRequest object can only make requests to the same domain where they are located. This is due to the same-domain security policy of the JavaScript sandbox and it is useful to avoid dangerous cross-site scripting vulnerabilities. This restriction can be easily circumvented using some solutions: the most commonly used one is to install or create a proxy on your web server. Instead of making your Ajax calls to an other domain you make calls to your proxy, that passes the call to the external domain and in return passes the data back to your client application. The connection is made to your server so there's no security concern.
An other powerful solution, but less commonly used, is to exploit the cross-domain communication capabilities that Flash can offer. Like JavaScript, Flash only allows requests to the same domain by default, but it also allows requests to third party domains that explicitly allow it using a crossdomain.xml file.
There are a couple of utilities that you can use to make XMLHttpRequest-like requests using this Flash capabilities, such as Julien Couvreur's FlashXMLHttpRequest and Jimbojw.com SWFHttpRequest Flash/Ajax Utility.
The crossdomain.xml file is a simple XML policy file that gives the Flash Player permission to access data from a given domain without displaying a security dialog. When placed on a server, it tells the Flash Player to allow direct access to data on that server, without prompting the user grant access. Cross-domain policy files are placed at the root level of a server. When using a policy file you can use a wildcard character (*) in a domain name.
If you have two domains, myFirstDomain.com and mySecondDomain.com, and you want your Ajax application on the first domain to call an API service on your second domain, you have to simply create a crossdomain file and put it at http://mySecondDomain.com/crossdomain.xml . This xml file will look like this:


<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
   <allow-access-from domain="*.myFirstDomain.com" />
</cross-domain-policy>

But if you have a public service and you want to allow cross-domain Ajax requests initiated from anywhere, you have to write into your cross-domain file <allow-access-from domain="*" /> such as many big API service provider over the internet (Yahoo, Flickr, Amazon, etc.). This could make your web site vulnerable to attacks "Cross-Site Request Forgeries" (CSRF) as discussed in this Chris Shiflett blog entry.

Chris Shiflett also suggests:
"If you have a public API and want to allow cross-domain Ajax requests with Flash, be sure to use a separate domain. If the user interface and API operate in the same domain, there's almost no limit to what an attacker can do."

January 21, 2008

Better PHP code: some improvements, resources and tips

In this post I want to show some resource and tips to improve, validate and document your PHP code, and also if you want how to be compatible when PHP 6 when will be available.

PHPLint
A validator and a documentator of PHP programs. The programmer
can add to the source the PHPLint meta-code, that enhance the syntax of
the PHP language toward the paradigm of a strong-typed language and safe
programming.


Enablig the Enterprise with Zend
Zend Platform is the only application server for PHP that supports the performance, management, integration, and enterprise scalability requirements of organizations using PHP for their business-critical applications. By providing capabilities that streamline development and deployment, Zend Platform improves the user experience, application responsiveness, integration to your existing infrastructure, and increases application reliability and scalability.


Java technologies:
● PHP has an extension to interact with Java.
● This extension gives access to all Java APIs (calls are only by values).
● Another bridge is hosted at SF.net
● Java APIs related to distributed programming are RMI and JMS.
● The protocol is binary thus giving performance advantage.

RMI - architecture:

Things to know when working with Java
● Classes are instantiated with Java class:
$string = new Java('java.lang.String');
●When the class has no public constructor the PHP variable is an object of class java.lang.Class.
● Calling static method is no different than calling normal methods.
● Java exceptions are PHP errors. A E_WARNING will be generated on exception.
● java_last_exception_get() tell you if there was an exception. Use java_last_exception_clear() to clear it.
●One can define his own error handler.

Accessing remote service over RMI:


<?php
function gettime() {
return array_sum(explode(' ', microtime()));
}

function err_handler($errno, $errstr, $errfile, $errline) {
if ($ex = java_last_exception_get()) echo $ex->toString()."\n";
java_last_exception_clear();
}

set_error_handler("err_handler");

$class = new Java("java.rmi.Naming");
$calculator = $class->lookup("rmi://localhost/CalculatorService");
var_dump($calculator->sub(14,3));
$i = 0;
$start = gettime();
while ($i++ < 500) $calculator-> sub($i, 20);
$end = gettime();
printf("Finished %d calls in %2.5f\n", $i1, $end-$start);

//now let's generate an exception
var_dump($calculator->fakeMethod());
echo "\nOK\n";
?>


Tips that improve your PHP code:

● echo is faster than print
● $row[’id’] is 7 times faster than $row[id]
● Do not use functions inside of for loop, such as for ($x=0; $x < count($array); $x) The count() function gets called each time.
● Close your database connections when you're done with them
● Error suppression with @ is very slow.

Also if you want to be compatible with PHP6:

● Do not use register_globals. In PHP6 will not exists any option to access it.You'll can use this vatiable:
$_GET['input'];
$_POST['input'];
$_REQUEST['input'];
● Don't use magic_quotes
● use preg instead ereg.
● Don't initiate objects with the reference operator. If you're initiating objects using the reference operator, you should stop now. It will generate an E_STRICT error.
$a = & new object(); // No
$a = new object(); // Yes

January 28, 2008

How to avoid multiple per-user sessions in Tomcat/JBoss

Usually, in our rich internet application, a user with a registered account can do two different logins from two different workstations and can maintain two concurrent sessions opened. In some applications we want to limit the users to one session per account, so we have to take countermeasures.
A simple method to check if a user is logged is to set a property in the current HttpSession; in this example in our login function we set

session.setAttribute("username", username);

If there is no username attribute, we will return an error to the user.
When someone starts a session with his account we have to check if there is already a session opened with that account. We can use an HashMap using the username as key and the session as value; obviously we have to use the same hashmap across multiple logins. A very fast and simple solution is to create a singleton that exposes operations on our hashmap:



public class MySessionManager {

  private HashMap hashMap;

  public boolean exist(String username) {
   if(hashMap.containsKey(username)) {
     return true;
   }

   return false;
  }

  public boolean addSession(HttpSession session) {
   if(hashMap.containsKey(session.getAttribute("username"))) {
   return false;
   }

   hashMap.put((YouthruCorpPrincipal)session.getAttribute("username"), session);
   return true;
  }

  public HttpSession getSession(String username) {
   return hashMap.get(username);
  }

  public boolean removeSession(String username) {
    if(!hashMap.containsKey(username)) {
     return false;
    }

    hashMap.remove(username);
   return true;
  }

  private static MySessionManager instance;


  public static MySessionManager getInstance() {
    if(instance == null)
     instance = new MySessionManager();

   return instance;
  }

  public MySessionManager() {
    hashMap = new HashMap();
  }

}

In our login function we have to check the existence of a previously created session with the same username, in that case we can logout the user associated with that session:

if(MySessionManager.getInstance.exist(username)) {
logout(MySessionManager.getInstance.getSession(username));
MySessionManager.getInstance.removeSession(username);
}

In this case the logout function takes as argument a session and log out from our application the user associated with that session, then we can do our login routine and at add the current session to the hashmap.

In this example we are checking only for sessions with a username attached, if we want to do some operation every time a session is created/destroyed, we can implement the HttpSessionListener interface:

http://tomcat.apache.org/.../http/HttpSessionListener.html

Classes that implement this interface will be notified of session creation and destruction using the respective functions:

void sessionCreated(HttpSessionEvent se)
void sessionDestroyed(HttpSessionEvent se)

To receive notification events, the implementation class must be configured in the deployment descriptor for the web application; for example:



<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <listener>
    <listener-class>
      myapp.security.MySessionListener
     </listener-class>
  </listener>
</web-app>

About January 2008

This page contains all entries posted to Comtaste Consulting | Enterprise RIA consulting and development in January 2008. They are listed from oldest to newest.

December 2007 is the previous archive.

February 2008 is the next archive.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.33