Axis of Cookies
  Posted May 05, 2003    PermaLink    Comments (7)  

I swear, some times it feels like I spend more time reading third pary code to see what it's really doing than writing code of my own. Today's subject of abuse will be Apache Axis. Here's the use case: Using a java plug-in applet inside a web-app that uses form based authentication access a soap service behind that authentication. You don't have the password available (there are tricks to get the username, but you really have to think outside the box to intercept the password, and forget about C3 certification at that point!)

My first line of thought was that Cookies are magically added to URL requests in the plug in so it must work in axis. That is a cool and very real feature of the plug in, but it only works when using a java.net.URL, but Axis dosen't use it, it uses some custom HTTP sender with support for the Jakarta Commons HTTP Sender. Thank you for plauing try again.

What worked for a while was the URL re-writing method form the servlet spec, basically using http://shemnon.com/speling/;jsessionid=<sessionID>. That works fine on some servers, but not others. The hitch is that in the spec URL re-writing is only meant to be used when the client rejects the cookies. One app server accepts the session id in both the cookie or the url re-writing, but anohter one we need to support doesn't. And you know what sucks? It's the second app server that is probobly properly implementing that part of the servlet spec! We're not playing horseshoes here so I need to keep going.

So as little as I want to I have to dive into the JAXRPC spec. The truth is that Axis's WSDL2Java is so easy to use from a coding perspective you rarely need to use the standard APIs that it implements. It just looks like another RMI-style interface that maigcally works. Believe me, I like stuff that magically works, it allows me to go home after my 8 hours are in.

It turns out that the classes you get from the ServiceLocaters are also javax.xml.rpc.Stub classes. These provice access to some standard properites, like if I needed HTTP Basic authentication I'de be in luck, but alas no dice, I need to use the currently bound user. There is also another standard property that will maintain the http session but it maintains only new sessions! And it suckes when all you get is "302 Found" messages to the login form when you don't know the password. And apparently the session is only maintained on a per-service basis as well (per instance of the serivce to make things worse).

This is where open source and source available software comes in handy. After diving into the setMaintainSession(boolean) code deep inside of the transport handlers I came to the conclusion that the cookie was stored in a property set that inhereited ultimatly from the same properties that the service uses to read the standard JAXRPC properties. So all I need to do is set the cookie in the service session when I get it from the service...

import org.apache.axis.transport.http.HTTPConstants;

/* ... */

MyServiceLocator locator = new MyServiceLocator();
MyService serivce = locator.getMyService();
((javax.xml.rpc.Stub)service)._setProperty(
    "javax.xml.rpc.session.maintain"),
    Boolean.TRUE);
((javax.xml.rpc.Stub)service)._setProperty(
    HTTPConstants.HEADER_COOKIE,
    "JSESSIONID=" + sessionID);

and those last two statements only cost me one afternoon of lost time....

Trackback URL
  TrackBack URL for this entry:
http://shemnon.com/cgi-bin/mt/mt-tb.cgi/89
 
Comment
 
Name:Bob Dunbar
Date:January 2, 2004 12:05 PM

This code is working great. Thank you.

Any tricks for getting the sessionID from the HTTP Header response? For Example, using Axis to get the 'Set-Cookie' value from the following HTTP response header:

HTTP/1.1 200 OK
Server: Microsoft-IIS/5.1
Date: Wed, 31 Dec 2003 03:24:54 GMT
X-Powered-By: ASP.NET
X-AspNet-Version: 1.1.4322
Set-Cookie: ASP.NET_SessionId=3kgjohv50iaskl3xnxgyifzc; path=/
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 292

Thanks in advance,

Bob

 
Comment
 
Name:Danno Ferrin
Date:January 5, 2004 10:30 AM

The trick I used was to put the cookie in the applet/object tag as a paraemeter, including the title and everything. This works good when the needed cookie is not JSESSIONID, so the code looked something like...
<% String sessionName = request.getHeader("cookie");%>
<OBJECT classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"
codebase="local jre">
<!-- other params -->
<PARAM NAME="SESSION" VALUE="<%=sessionName%>"/>
</OBJECT>

I would then use the SESSION parameter to populate the axis cookie. Of course this is JSP code and not ASP code, so I am sure the details are different on IIS.

 
Comment
 
Name:Gunter Blache
Date:January 19, 2004 08:35 AM

Hello Permalink,

thanks for that posting, it was what I needed to get HTTP basic authentication running with Axis. For completeness, my code looks like:

import org.apache.axis.client.Stub;
...
ServiceLocator sl = new ServiceLocator();
Service c = sl.getService(new URL("http://...service/soap/1.0/"));
Stub s = (Stub)c;
s.setUsername("user");
s.setPassword("password");
String return = c.getString();

and works great. Thank you

Gunter

 
Comment
 
Name:ddd_80
Date:August 1, 2005 12:10 PM

Hello,
I was trying to add a cookie to session using the code you provided. By I get a ClassCastException.

org.apache.axis.client.Service.Service service = new org.apache.axis.client.Service.Service();

Call call = (Call) service.createCall();
(javax.xml.rpc.Stub)service)._setProperty("javax.xml.rpc.session.maintain", Boolean.TRUE);

((javax.xml.rpc.Stub)service)._setProperty( HTTPConstants.HEADER_COOKIE,"cookieName=" + sid);

I get the following exception:
Exception in thread "main" java.lang.ClassCastException: org.apache.axis.client.Service

Thanks in advance.
Deval

 
Comment
 
Name:Danno Ferrin
Date:August 1, 2005 12:44 PM

You are not using the axis service locator to find the stub object. Use the ServiceLocator or the JNDI finders to get at the stub for your service.

Generally speaking, don't directly instantiate a org.apache.axis.client.Service object, specific instances of those are used to build and return specific stubs. The MyServiceLocator is the specific instance of org.apache.axis.client.Service you want to play with. Then using the ServiceLocator you get the Stub object, which implements the interfaces your soap service defines.

I you are doing a dynamic soap call, set the properties on the Call object you create from the generic service object.

There is some real confusing and unfortionalte choice to terminiology there, but them's the facts!

 
Comment
 
Name:ddd_80
Date:August 1, 2005 04:28 PM

Hello,
Thank you Danno for the previous post. I can set the cookie now.

I wanted to ask if it possible to create a Axis handler on the client side and set a cookie there. If yes which handler to create and how to set the cookie.

I want the client to pass a session Id on every call to the server. Can this be done in a Axis handler ?


Thank you
Deval

 
Comment
 
Name:Danno Ferrin
Date:August 1, 2005 04:43 PM

This is not a support forum. Try the apache axis users mailing lsit at axis-user@ws.apache.org.

 
Post Comment
 

Thanks for signing in, . Now you can comment. (sign out)

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)


Remember me?


Name:
Email Address:
URL: