GridLab logo
Public
* About
* News
* Download
* Documents
* Collaborations
Internal
* Meetings
* Links
* Mailing List
* Management
* Yellow Pages
* Our Eyes Only
Information Society Technologies  
 
| Home | Products & Technologies | Support & Downloads | Contact us |  
GridLab WP-5

WP5: Guide to installing Apache AXIS

This guide describes how to install Apache AXIS server with GSI-secured access and how to write clients for it.

Please note, that older versions of Globus Toolkit 3 named Technology Preview used the Globus 2 model of securing communication on transport level (the same level as SSL). Newer versions of GT3, namely the Alpha releases, are moving in the direction of message level security, it means that communication is done over plain HTTP connection, but SOAP messages are themselves encrypted and digitaly signed using XML Encryption and XML Signature standards. This document describes only transport level security.

Contents:

Download Tomcat and OGSA

Apache AXIS is a pure Java implementation for clients and servers of WebServices. Support for GSI tranport-level security was added in Globus Toolkit 3, it uses Java CoG and java SSL implementation for creating GSI sockets. AXIS server needs Tomcat servlet container to run. All of them need Java to run.
So download Install JDK, it means run the installation script, set JAVA_HOME environment variable to the directory where JDK was extracted, and add "$JAVA_HOME/bin/java" to your PATH.

Install Tomcat and AXIS with GSI-plugin

Put downloaded files into some directory and issue following commands:
mkdir gsiws
cd gsiws
tar xzvf ../jakarta-tomcat-4.1.27.tar.gz
mv jakarta-tomcat-4.1.27 tomcat-4.1.27
tar xzvf ../gt3.0.2-core-bin.tar.gz ogsa-3.0.2/lib ogsa-3.0.2/tomcat ogsa-3.0.2/webapps
mkdir -p tomcat-4.1.27/webapps/axis/WEB-INF/lib
mkdir tomcat-4.1.27/webapps/axis/WEB-INF/classes
cp ogsa-3.0.2/tomcat/common/lib/* tomcat-4.1.27/common/lib/
cp ogsa-3.0.2/tomcat/server/lib/cog-tomcat.jar tomcat-4.1.27/server/lib/
cp ogsa-3.0.2/lib/ogsa.jar tomcat-4.1.27/webapps/axis/WEB-INF/lib/
cp ogsa-3.0.2/lib/cog-axis.jar tomcat-4.1.27/webapps/axis/WEB-INF/lib/
cp ogsa-3.0.2/lib/axis.jar tomcat-4.1.27/webapps/axis/WEB-INF/lib/
cp ogsa-3.0.2/lib/wsdl4j.jar tomcat-4.1.27/webapps/axis/WEB-INF/lib/
cp ogsa-3.0.2/lib/xmlsec.jar tomcat-4.1.27/webapps/axis/WEB-INF/lib/
cp ogsa-3.0.2/webapps/ogsa/WEB-INF/web.xml tomcat-4.1.27/webapps/axis/WEB-INF/
Now make changes described in Security Support in GT3-Alpha3 documentation:
Edit file tomcat-4.1.27/conf/server.xml and make this change (you can use patch to do it):
99a100,121
>     <!-- Define a GSI HTTP/1.1 Connector on port 8443
>              Supported parameters include:
>              proxy         // proxy file for server to use
>                or
>              cert          // server certificate file in PEM format
>              key           // server key file in PEM format
>  
>              cacertdir     // directory location containing trusted CA certs
>              gridMap       // grid map file used for authorization of users
>              debug         // "0" is off and "1" and greater for more info
>      -->
>     <Connector className="org.apache.catalina.connector.http.HttpConnector"
>                 port="8443" minProcessors="5" maxProcessors="75"
>                 enableLookups="true" authenticate="true"
>                 acceptCount="10" debug="1" scheme="httpg" secure="true">
>        <Factory className="org.globus.tomcat.catalina.net.GSIServerSocketFactory"
>                 proxy="/etc/grid-security/hostproxy.pem"
>                 cacertdir="/etc/grid-security/certificates"
>                 gridMap="/etc/grid-security/grid-mapfile"
>                 debug="3"/>
>      </Connector>
> 
164a187,188
> 
>       <Valve className="org.globus.tomcat.catalina.valves.CertificatesValve" debug="1" />
Change the line proxy="/etc/grid-security/hostproxy.pem" to a real location of your machine's proxy. By default there is none, but you can create it by joining files hostcert.pem and hostkey.pem in /etc/grid-security/ directory. The hostproxy.pem file should be owned by the user under which Tomcat will run and access rights should be set to 400. You will need root privileges on that system (or ask your administrator), and you can do it using following commands:
su - root
cd /etc/grid-security/
cat hostcert.pem hostkey.pem >hostproxy.pem
chown tomcatuser hostproxy.pem
chmod 400 hostproxy.pem
exit

Then change file tomcat-4.1.27/bin/catalina.sh by adding classes to CLASSPATH. Without this step the Java system classloader will not find classes needed to handle httpg protocol:

CLASSPATH="$CLASSPATH":"$CATALINA_HOME"/bin/bootstrap.jar
CLASSPATH="$CLASSPATH":"$CATALINA_HOME/common/lib/cog-jglobus.jar":"$CATALINA_HOME/common/lib/log4j-core.jar"
CLASSPATH="$CLASSPATH":"$CATALINA_HOME/common/endorsed/xercesImpl.jar":"$CATALINA_HOME/common/endorsed/xmlParserAPIs.jar"
CLASSPATH="$CLASSPATH":"$CATALINA_HOME/common/lib/puretls.jar":"$CATALINA_HOME/common/lib/jce-jdk13-117.jar"
CLASSPATH="$CLASSPATH":"$CATALINA_HOME/common/lib/cryptix32.jar":"$CATALINA_HOME/common/lib/cryptix-asn1.jar"
CLASSPATH="$CLASSPATH":"$CATALINA_HOME/common/lib/cryptix.jar"

Enable "Version" webservice

A standard Axis server has a default WebService called "Version" with method "String getVersion()" which we can use to test the installation. But because we used Axis packed in GT3, this webservice is not deployed by default, so we must make it available first (this was not necessary in Alpha versions of GT3).
Let's set up necessary classes first:
for i in $PWD/ogsa-3.0.2/lib/*.jar . ; do CLASSPATH=$CLASSPATH:$i ; done
export CLASSPATH
Now create a deployment file deploy.wsdd with following content:
<deployment
    xmlns="http://xml.apache.org/axis/wsdd/"
    xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
 <service name="Version" provider="java:RPC">
  <parameter name="allowedMethods" value="getVersion"/>
  <parameter name="className" value="org.apache.axis.Version"/>
 </service>
</deployment>
and deploy the service by doing:
cd tomcat-4.1.27/webapps/axis/WEB-INF/
java  org.apache.axis.utils.Admin server ../../../../deploy.wsdd
cd -
That should create a file server-config.wsdd which specifies available services.

Now you can run the Tomcat server:

 cd tomcat-4.1.27/bin
 ./startup.sh
 cd ../..
 mozilla http://localhost:8080/axis/servlet/AxisServlet &
The last command will display deployed services. You can try to call the Version.getVersion() operation by visiting http://localhost:8080/axis/services/Version?method=getVersion, it will return XML representing SOAP response of the operation.

Make GSI-enabled client

The running AXIS server is listening on two ports - on port 8080 without GSI and on port 8443 with GSI.
The WSDL description for this service is accesible on port 8080 on URL with ?wsdl appended.
We will use WSDL2Java tool to generate client classes. Run
java  -Djava.protocol.handler.pkgs=org.globus.net.protocol \
      org.apache.axis.wsdl.WSDL2Java -v \
      --NStoPkg http://localhost:8080/axis/services/Version=versionclient \
      http://localhost:8080/axis/services/Version?wsdl
It will use WSDL description of the Version service to generate connection classes in subdirectory versionclient. Create a client file CallVersion.java:
import versionclient.*;
import java.net.URL;
import java.rmi.Remote;
import org.apache.axis.EngineConfiguration;
import org.apache.axis.SimpleTargetedChain;
import org.apache.axis.client.Service;
import org.apache.axis.client.Stub;
import org.apache.axis.configuration.SimpleProvider;
import org.globus.axis.transport.GSIHTTPSender;
import org.globus.axis.transport.GSIHTTPTransport;
import org.globus.axis.util.Util;
import org.ietf.jgss.GSSCredential;
import org.globus.gsi.gssapi.auth.Authorization;

/**
 * Calls a Version webservice. 
 */
public class CallVersion
{
   static SimpleProvider p;
   /**
    * Prepares httpg handler.
    */
   static {
    p = new SimpleProvider();
    p.deployTransport("httpg", new SimpleTargetedChain(new GSIHTTPSender()));
    Util.registerTransport();
   }

   public static void main(String [] args) throws Exception {
    String url="httpg://your.machine.org:8443/axis/services/Version";
    VersionServiceLocator s = new VersionServiceLocator();
    s.setEngineConfiguration(p);
    Version v = s.getVersion(new URL(url));
    //preparePort(v,...);
    System.out.print("Version: "+v.getVersion());
  }

  /**
   * Sets properties of Call when default are not enough.
   */
  static void preparePort(Remote ws,GSSCredential proxy,Authorization auth) {
    Stub stub = (Stub) ws;
    stub._setProperty(GSIHTTPTransport.GSI_CREDENTIALS, proxy);
    stub._setProperty(GSIHTTPTransport.GSI_AUTHORIZATION, auth);
    stub._setProperty(GSIHTTPTransport.GSI_MODE, GSIHTTPTransport.GSI_MODE_NO_DELEG);
  }
}
Provide a real machine name in URL, as this is checked against the server's certificate. Beware, the name of the machine must map to IP address, which maps back to the same name ! Also, the name must be the same as used in the host certificate, so if your host certificate (contained in hostproxy.pem referenced from tomcat-4.1.27/conf/server.xml) has DN for example O=Grid,O=MyOrg,CN=host/your.machine.org, you must use the name your.machine.org in the URL, otherwise server authentication will fail.
Don't forget to have a valid user proxy certificate, which has its DN listed in /etc/grid-security/grid-mapfile on the server machine, otherwise user authentication will fail.

Now compile and run:
$javac CallVersion.java
$java CallVersion
Version: Apache Axis version: 1.1
Built on Jun 18, 2003 (03:41:59 CDT)
The CallVersion client registers httpg as a valid protocol, locates the service, sets connection properties and calls Version with GSI on port 8443.
It can happen that the client fails with exception
No client transport named 'httpg' found!
        at org.apache.axis.client.AxisClient.invoke(AxisClient.java:183)
        at org.apache.axis.client.Call.invokeEngine(Call.java:2564)
        at org.apache.axis.client.Call.invoke(Call.java:2553)
        at org.apache.axis.client.Call.invoke(Call.java:2248)
        at org.apache.axis.client.Call.invoke(Call.java:2171)
        at org.apache.axis.client.Call.invoke(Call.java:1691)
        at versionclient.VersionSoapBindingStub.getVersion(VersionSoapBindingStub.java:96)
        at CallVersion.main(CallVersion.java:31)
It was found that it is caused by having file wsif.jar in CLASSPATH on the beginning, before other GT3 jars. You can remove the file from your CLASSPATH or change order of the files in that case.

Writing clients for other WebServices is similar, run the WSDL2Java tool for generating client classes, then write a main class which registers httpg transport and specifies connection properties.

Deploy new services

Creating and deploying new services into GSI-enabled AXIS is the same as into non-GSI AXIS, so follow the AXIS User Guide. The only difference is that when using GSI for user credentials delegation, you can get the delegated proxy using:
MessageContext ctx = MessageContext.getCurrentContext();
GSSCredential cred = 
    (GSSCredential)ctx.getProperty(GSIConstants.GSI_CREDENTIALS);
inside methods of the deployed WebService.

A quick guide how to write a WebService

Create an interface for the WebService as Java interface:
 package mypackage;
 public interface MyService {
    public String getSomething(String s,int i,float f, double d);
 }
and compile it into mypackage/MyService.class.
To specify parameter names, create its implementation class:
package mypackage;
public class MyServiceImpl implements MyService {
    public String getSomething(String s,int i,float f, double d) {
        return s+i+f+d;
    }
}
and compile it with debuging enabled: javac -g mypackage/MyServiceImpl.java
Then generate a WSDL file for that interface by:
java org.apache.axis.wsdl.Java2WSDL \
        --output MyService.wsdl  \
        --location "httpg://acrab.ics.muni.cz:8443/axis/services/MyService" \
        --namespace  "urn:SomeMyURI" \
        --PkgtoNS "mypackage"="urn:SomeMyURI"  \
        --implClass mypackage.MyServiceImpl \
        mypackage.MyService
where "urn:SomeMyURI" is a unique namespace identifying this WebService and location value is the default service location. Then generate Java classes from that WSDL file by:
java  -Djava.protocol.handler.pkgs=org.globus.net.protocol \
      org.apache.axis.wsdl.WSDL2Java -v \
      --server-side \
      --deployScope Application \
      --NStoPkg urn:SomeMyURI=mypackage \
      --output classes \
      MyService.wsdl
it will create several files in the classes/mypackage directory.
Implement some actual behavior inside mypackage/MyServiceSoapBindingImpl.java.
package mypackage;
import org.apache.axis.MessageContext;
import org.ietf.jgss.GSSCredential;
import org.globus.axis.gsi.GSIConstants;
import java.rmi.RemoteException;

public class MyServiceSoapBindingImpl implements MyService{
    public String getSomething(String s, int i, float f, double d) throws RemoteException {
        MessageContext ctx = MessageContext.getCurrentContext();
        GSSCredential cred =
                (GSSCredential)ctx.getProperty(GSIConstants.GSI_CREDENTIALS);
        String userDN = (String)ctx.getProperty(GSIConstants.GSI_USER_DN);
        String userID = (String)ctx.getProperty(GSIConstants.GSI_AUTH_USERNAME);
        return "[s="+s+",i="+i+",f="+f+",d="+d+"]\n"+
            "GSI_CREDENTIALS="+cred+"\n"+
            "GSI_USER_DN="+userDN+"\n"+
            "GSI_AUTH_USERNAME="+userID+"\n";
    }
}

Compile and deploy:
cd classes
javac mypackage/*.java
cp -r mypackage ../tomcat-4.1.27/webapps/axis/WEB-INF/classes/
cd ../tomcat-4.1.27/webapps/axis/WEB-INF/
java org.apache.axis.utils.Admin server ../../../../classes/mypackage/deploy.wsdd
If you want to be able to extract delegated credentials, change tomcat-4.1.27/webapps/axis/WEB-INF/server-config.wsdd Add CredentialHandler handler in <requestFlow> section of <globalConfiguration> block:
<requestFlow>
<handler type="java:org.globus.axis.handler.CredentialHandler"/>
...
<requestFlow/>
Restart the TomCat server.

That's it. You can see the deployed service on URL
http://localhost:8080/axis/servlet/AxisServlet and call it using the same code as for Version, just change it to:
    MyServiceServiceLocator s = new MyServiceServiceLocator();
    s.setEngineConfiguration(p);
    MyService m = s.getMyService();
    System.out.print("MyService: "+m.getSomething("A",1,2.0f,3.0d));
Have fun with WebServices ;-)


Sent any comments to Martin Kuba.

Last updated: $Date: 2003/11/11 09:35:53 $



GridLab: Grid Application Toolkit and Testbed is co-funded by the European Commission under the Fifth Framework Programme (IST-2001-32133).
Web admin: Petr Holub, web design: Radoslaw Strugalski

Last update on Tuesday, 11-Nov-2003 10:36:45 CET.