Sunday, May 30, 2010

Client Request, Thread, and Java EE Container

For each web request, in general, the web container will not create a new servlet instance. Actually only one servelet instance object is needed for each type. But the web container will create a new thread to handle each request. The following link explains well how the web container creates threads and use the servlet instance to serve the new client request.
http://www.datadisk.co.uk/html_docs/jsp/jsp_web_app_architecture.htm

Similarly, for each new remote client request to the EJB container, the container will create a new EJB object ( and a new thread to handle the request, I think). The EJB object will use a bean instance. But the bean instance does not need to be created everytime. EJB container uses instance pooling for the bean classes.
The following is an article that explains java RMI internal details:
http://www.developer.com/java/other/article.php/10936_3455311_1/Understanding-Java-RMI-Internals.htm

Thursday, May 27, 2010

Private Keys, Digital Certificate, and Trusted Certificate Authorities Concept

Concepts

Servers need a private key, a digital certificate containing the matching public key, and a certificate for at least one trusted certificate authority. We use CA to denote Certificate Authority.

A private key and digital certificate provide identity for the server.

The digital certificate for identiy and the trusted CA certificate are both certificates. But they serve for very different purposes for the server. Basically what these two things are saying are the following:
  1. I have a digital certificate.
  2. I would like to talk with the following CAs (the trusted CAs).
So the digital certificate is for my own identity. The trusted CA certificates are for others. They are what I would like to talk to.

The two words CA and CA certificate are often used as the same thing. This is because CA is just a concept while the CA certificate is the actual material used for the identity of a CA.

My digital certificate itself needs to be digitally signed with a CA's digital certificate. This CA can be different from my trusted CAs. You can even sign your digital certificate by yourself (self-signed digital certificate). As in the web browser, you can add new trusted CAs to the existing trusted CA list for the browser. The digital certificate itself does not have any information about what others I would like to talk to. There must be a separate security process that can make decision using my digital certificate and the trusted CA certificates.

What Does a Digital Certificate Contain?

A digital certificate contains the owner(or subject)'s DN(name, address, company, etc), the public key, the issuer(or signer)'s DN, the signature of the issuer, etc. The issuer is the CA for this certificate.

How the Parties Communicate?

Data encrypted with the public key can only be decrypted using the corresponding private key, and the data encrypted with the private key can only be decrypted using the corresponding public key.

I think it may work this way. When A talks to B, A will receive the digital certificate of B. The digital certificate of B contains the CA who signs it for B. If this CA is in the trusted CA list of A, A will talk to B. Otherwise, A can refuse to talk to B. In the case that it is a trusted CA, A will use the public key embedded in B's digital certificate and encrypt the data and then send the data to B. B will use its own private key to decrypt the data. Note that only B can decrypt the data. Even A itself won't be able to decrypt the data it sent because A does not know B's private key. On the reverse direction, once A acknowledges B as trusted, A can send its degital certificate to B and B can check to see if A is in its trusted CA list and do the data encryption and sending. For details about SSL handshake protocol, see [2].

Create, Store and View the Keys And Certificates

1. You can obtain digital certificates, private keys, and trusted CA certificates from the CertGen utility, Sun Microsystem's keytool utility, or a reputable vendor such as Entrust or Verision. You can also use the command "keytool -genkeypair ". Note that this command will generate only one file, which is a keystore. But this file contains both the private key and the self-signed certificate.
2. Store the private keys, digital certificates, and trusted CA certificates in a keystore.
3. The command "keytool -list -v -keystore yourKeyStore -storepass yourKeyStorePassword" can be used to print out all the certificates in your key store.

Personal Information Exchange File

The file with the extension .p12 is a special type of certificate file. It is called the Personal Information Exchange file. The certificate contains both the public key and the private key.

Certificate Chain, Certificate Verification

Reference [5] shows a good diagram about how the certificate chain works. I think the procedure works in the following way according to the diagram.
  1. You receive someone's certificate C_1.
  2. Since every certificate contains the CA who signed the certificate, you can get the information of that CA ( say CA_2). But how do you know that this is truly the CA as it claimes? CA_2 can say it is Verisign even thouhg it is actually not. So the issue here is to check if the CA is really who it claims to be.
  3. So from C_1, you can get the DN(Distinguished Name ) of CA_2. From this DN you can get the public key of CA_2.
  4. Use the public key in step 3 and the signature of CA_2 ( which is contained in C_1) to check if they agree. If not, it is fake. This is the essential part of this whole procedure. How can you verify the signature? Reference[6] says that
    "The CA then signs the certificate using its private key, which is used to verify the certificate."
    "To verify a certificate, all that is necessary is the public key of the CA and a check against the CRL(certificate revocation lists) published by that CA."
    Reference[7] has more information about how the certificate is verified. Note that C_1 does not contain the private key of CA_2. It just contains the data ( signature ) that CA_2 uses its private key to generate. This data (signature) can be decrypted with the public key of CA_2.
  5. If step 4 is good, continue the same verification for C_2.

The above is roughly the idea. Note that step 5 and 6 may be not exactly that if the algorithm to vefify the CA's is a recursive one.

Various standards and implementations

It seems that there are many implementations in the java security area. For example, the way to validate a certificate is not fixed. Weblogic server SSL has two certificate lookup and validation providers. And you can even write a custom CertPath Validator to provide additional validation on the certificate chain. So a certificate may or may not pass the validation depending on the validation providers used.

References

  1. Weblogic Document "Securing WebLogic Server"
  2. http://docs.sun.com/source/816-6156-10/contents.htm#1041640
  3. http://download.oracle.com/javase/1.5.0/docs/tooldocs/windows/keytool.html
  4. http://www.flatmtn.com/article/creating-pkcs12-certificates
  5. http://publib.boulder.ibm.com/infocenter/wmqv6/v6r0/index.jsp?topic=/com.ibm.mq.csqzas.doc/sy10600_.htm
  6. http://support.microsoft.com/kb/195724
  7. http://en.wikipedia.org/wiki/X.509
  8. http://tools.ietf.org/html/rfc2459#page-18
  9. http://docs.oracle.com/javase/6/docs/technotes/tools/windows/keytool.html

Tuesday, May 4, 2010

Integrate Spring Webflow, IceFaces and Facelets

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:j2ee="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"
 version="2.4">

 <!-- other stuff -->

 <!-- Facelets -->
 <context-param>
  <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
  <param-value>.xhtml</param-value>
 </context-param>

 <context-param>
  <param-name>facelets.DEVELOPMENT</param-name>
  <param-value>true</param-value>
 </context-param>

 <context-param>
  <param-name>com.sun.faces.validateXml</param-name>
  <param-value>true</param-value>
 </context-param>

 <context-param>
  <param-name>facelets.LIBRARIES</param-name>
  <param-value>/WEB-INF/tld/myTaglib.xml</param-value>
 </context-param>

 <servlet>
  <servlet-name>xyz</servlet-name>
  <servlet-class>
   org.springframework.web.servlet.DispatcherServlet
  </servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet>
  <servlet-name>Faces Servlet</servlet-name>
  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
  <init-param>
   <param-name>debug</param-name>
   <param-value>true</param-value>
  </init-param>
  <init-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>
    /WEB-INF/xyz-servlet.xml /WEB-INF/xyz-webflow-config.xml
   </param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <!-- Persistent Faces Servlet -->
 <servlet>
  <servlet-name>Persistent Faces Servlet</servlet-name>
  <servlet-class>
   com.icesoft.faces.webapp.xmlhttp.PersistentFacesServlet
  </servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <!-- Blocking Servlet -->
 <servlet>
  <servlet-name>Blocking Servlet</servlet-name>
  <servlet-class>
   com.icesoft.faces.webapp.xmlhttp.BlockingServlet
  </servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>xyz</servlet-name>
  <url-pattern>*.htm</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
  <servlet-name>xyz</servlet-name>
  <url-pattern>*.info</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
  <servlet-name>Faces Servlet</servlet-name>
  <url-pattern>/faces/*</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
  <servlet-name>Faces Servlet</servlet-name>
  <url-pattern>*.faces</url-pattern>
 </servlet-mapping>

 <!-- Persistent Faces Servlet Mappings -->
 <!--
  the following mapping will load stylesheet and other resources out of
  the icefaces jar by default
 -->
 <servlet-mapping>
  <servlet-name>Persistent Faces Servlet</servlet-name>
  <url-pattern>/xmlhttp/*</url-pattern>
 </servlet-mapping>

 <servlet-mapping>
  <servlet-name>Persistent Faces Servlet</servlet-name>
  <url-pattern>*.iface</url-pattern>
 </servlet-mapping>

 <!-- Blocking Servlet Mapping -->
 <servlet-mapping>
  <servlet-name>Blocking Servlet</servlet-name>
  <url-pattern>/block/*</url-pattern>
 </servlet-mapping>

 <!-- other stuff -->


</web-app>


faces-config.xml

<?xml version="1.0"?>

<!DOCTYPE faces-config PUBLIC "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN" "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

<faces-config>

 <application>
  <navigation-handler>
   org.springframework.webflow.executor.jsf.FlowNavigationHandler
  </navigation-handler>
  <variable-resolver>
   org.springframework.webflow.executor.jsf.DelegatingFlowVariableResolver
  </variable-resolver>

  <view-handler>com.xyz.MyViewHandler</view-handler>


 </application>

 <lifecycle>
  <phase-listener>
   org.springframework.webflow.executor.jsf.FlowPhaseListener
  </phase-listener>
 </lifecycle>

 <!-- other stuff -->

</faces-config>

The view handler class MyViewHandler.java:
package com.xyz;

import javax.faces.FacesException;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;

import com.icesoft.faces.facelets.D2DFaceletViewHandler;
import com.icesoft.faces.webapp.http.core.ResourceServer;
import com.icesoft.faces.webapp.http.core.ServeCSSResource;

public class MyViewHandler extends ViewHandler
  {
    ViewHandler defaultHandler;
    ViewHandler faceletViewHandler;

    public MyViewHandler(ViewHandler defaultHandler)
    {
      this.defaultHandler = defaultHandler;
      this.faceletViewHandler = new D2DFaceletViewHandler(defaultHandler);
    }

    private ViewHandler getViewHandler(String viewId)
    {
      if (viewId.endsWith(".xhtml"))
      {
        return faceletViewHandler;
      }
      return defaultHandler;
    }

    public UIViewRoot createView(FacesContext context, String viewId)
    {
      ViewHandler viewHandler = getViewHandler(viewId);
      return viewHandler.createView(context, viewId);
    }

    public void renderView(FacesContext context, UIViewRoot viewToRender)
        throws IOException, FacesException
    {
      ViewHandler viewHandler = getViewHandler(viewToRender.getViewId());
      viewHandler.renderView(context, viewToRender);
    }

    public UIViewRoot restoreView(FacesContext context, String viewId)
    {
      ViewHandler viewHandler = getViewHandler(viewId);
      return viewHandler.restoreView(context, viewId);
    }
    
    // other methods
  }
Notes:
  1. MyViewHandler acts as a delegator. By default, it will delegate to the default JSF ViewHandler. But for .xhtml files, it will delegate to D2DFaceletViewHandler, which is an implementation from IceFaces for facelet. This is the glue of Icefaces and Facelets.
  2. The NavigationHandler is the Spring FlowNavigationHandler. This is the glue of Spring webflow and JSF or Icefaces because we are using Icefaces for JSF here.

xyz-webflow-config.xml

This file is linked in the web.xml file.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:flow="http://www.springframework.org/schema/webflow-config"
       xsi:schemaLocation="
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/webflow-config
           http://www.springframework.org/schema/webflow-config/spring-webflow-config-1.0.xsd">
 <flow:executor id="flowExecutor" registry-ref="flowRegistry">
  <flow:execution-attributes>
   <flow:alwaysRedirectOnPause value="false"/>
  </flow:execution-attributes>
 </flow:executor>
    </flow:executor>
 <flow:registry id="flowRegistry"> 
       <flow:location path="/WEB-INF/flows/mytask-flow.xml" />
 </flow:registry>
</beans>

The href link in the jsp page to invoke the webflow

The following link can be put in some menu jsp file. Clicking this will invoke the Spring webflow:

<a href="mytask.iface?_flowId=mytask-flow">My Task</a>

Note that the URL has .iface in it. Because of this, the IceFaces servlet "Persistent Faces Servlet" will be used to process this request as configured in web.xml. And it will invoke Spring webflow because of "_flowId=mytask-flow".

Facelet Template

The real advantage of Facelets is its use of template. You can base all of our concrete xhtml files on the same template so they all have the same look and feel. You can even do sub-template. The following is an example template file (mainTemplate.xhtml):
<f:view  xmlns:f="http://java.sun.com/jsf/core"
         xmlns:h="http://java.sun.com/jsf/html"
         xmlns:ice="http://www.icesoft.com/icefaces/component" 
         xmlns:ui="http://java.sun.com/jsf/facelets">

<html xml:lang="en" lang="en">
<head>
<title>My APP</title>

    <meta http-equiv="Expires" content="-1" />
    <meta http-equiv="Pragma" content="no-cache" />
    <meta http-equiv="Cache-Control" content="no-cache" />

 <link rel="stylesheet" type="text/css" media="screen" href="/xyz/css/xp.css" />
 <script type="text/javascript" src="/xyz/js/xyzcommon.js"></script>
 <ui:insert name="otherSettings"/>
 
</head>

<body id="page-home">
<div id="page">
    <div id="header" class="foo">  
       <div id="branding">
          <img height='80' src="images/xyz-web-banner.jpg" />
       </div>
    </div>
 <hr />
 
 <div>
     <ui:insert name="content">
            Default Content
     </ui:insert>
 </div>
 
</div>


<div id="footer">
   <p>&copy; Copyright </p>
</div>
</div>

</body>
</html>

</f:view>

Note that it defines two components that that need to be filled out by its sub-tempaltes or the actual concrete xhtml files.
<ui:insert name="otherSettings"/>
and
<ui:insert name="content">
            Default Content
     </ui:insert>
The following is an example sub-template(myTaskTemplate.xhtml):
<ui:composition template="/WEB-INF/jsp/shared/mainTemplate.xhtml"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
               >
   
<ui:define name="otherSettings">
    <link rel="stylesheet" type="text/css" media="screen" href="/xyz/css/listmenu_o.css" />
    <script type="text/javascript" src="/xyz/js/fsmenu.js"></script>  
    <ui:include src="/WEB-INF/jsp/shared/menuheader.jsp"/>
</ui:define>

</ui:composition>
Note that this sub-template fills out the "otherSettings" part in the main template. But it still leaves the "content" to be filled out. Or in terms of the programming language, it is still an "abstract" class.

The following is an example xhtml file that uses the sub-template:
<ui:composition template="myTaskTemplate.xhtml"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:ice="http://www.icesoft.com/icefaces/component">
   
<ui:define name="content">
          
<h:form >
  ..................
</h:form>
        
</ui:define>
    
</ui:composition>

Use <ui:include> Tag in Facelet File

Often times there are some common part in an xhtml file that can be shared by multiple xhtml files. The tag <ui:include> can be used to factor out that common part.

The following is an example. Note that this xhtml file(sharedComponent.xhtml) does not use any template because it is an independent component. Also note that it accepts variables:
<ui:component  xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:ice="http://www.icesoft.com/icefaces/component"
                xmlns:c="http://java.sun.com/jstl/core">
               
<ice:panelGroup>
<ice:outputLabel  value="#{myVar.eventType} Name: " />
<ice:outputText value="#{myVar.name} " />
</ice:panelGroup>

</ui:component>

To use this component, one can use the <ui:include> tag and also pass the value to the variabes defined in the component file sharedComponent.xhtml. The following is an example file sample.xhtml
<ui:composition template="myTaskTemplate.xhtml"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:ice="http://www.icesoft.com/icefaces/component"
               >
   
<ui:define name="content">
<ice:outputText styleClass="pageHeading" value="Hello World" />
<ui:include src="sharedComponent.xhtml">
  <ui:param name="myVar" value="#{myForm.aValue}"/>
</ui:include>
<ice:form> 
 .....
</ice:form>
 
</ui:define>
    
</ui:composition>