Tag Archives: Web Services

The Other One

As JAX-RS implementations go, I suppose Apache CXF is as good as any. But among all the conveniences, it certainly has its share of surprises. For example, although I follow a typical REST resource URI scheme, I had to write a custom ResourceComparator to get certain lookups to work across multiple service beans. I’m over that now, but today’s bug was really weird.

In this case, I’m handling basic authentication in an upstream inInterceptor, pulling credentials from the message. This has several benefits, including simpler service beans. If credentials are missing or invalid, I do the usual 401 / 403 thing, but if authenticated, I inject a SecurityPolicy containing my Principal, like so:

        message.put(SecurityContext.class, new BasicSecurityContext(userProfile));

.. with the hopes of my service bean having access via:

        @Context SecurityContext securityContext

Trouble is, that came out null. Turns out, this is a known issue with CXF, and the work-around (barring unwanted extra plumbing) is to use javax.ws.rs.core.SecurityContext, not org.apache.cxf.security.SecurityContext. So much for polymorphism.

Tight Spring

I still recall the wise advice of a friend while I was designing and building a set of application frameworks over two decades ago: “create as many hooks as possible and be quick to add new ones.”  So for each service flow I noted every interesting step and created extension points for each.  I didn’t think most of these would be be used but, over time, nearly all were.  And as users requested new hooks, I quickly added them.

The Spring frameworks, with their IoC underpinnings, are built for extensibility.  The application context is a software breadboard allowing all sorts of custom wirings and component swapping.  And namespace configuration elements make for much clearer and cleaner XML.  Where done right, the namespace configuration captures most core extension points, documents them well, and makes them easy to use. But shortcuts, inflexible designs, and atrophy can cause parts of Spring to be too tight. Here are just a couple of examples I encountered with this week.

Spring Security – Session Management Filter

A customer’s single sign-on (SSO) flow required tweaks to SessionManagementFilter, so I built my own: a subclass with just a simple override.  But swapping it in turned out to be quite clumsy, and basic things like setting the invalid-session-url in the namespace no longer work as documented.  Since I now have to specify the complete bean construction in the security context anyway, I decided to just replace the SimpleRedirectInvalidSessionStrategy.  Here again, I just needed one method override, but, alas, it’s a final class.  So, with some copy and paste re-use and ugly XML I finally got what I needed; here’s the gist:

 <http use-expressions="true" ...>
	...
    	<!-- Disable the default session mgt filter: /-->	
	<session-management session-fixation-protection="none" />
    	<!-- ... and use the one configured below: /-->		
	<custom-filter ref="sessionManagementFilter" position="SESSION_MANAGEMENT_FILTER" />
 </http>		
 
 <!-- Configure the session management filter with the custom invalid session re-direct. -->  
 <beans:bean id="sessionManagementFilter" 
		class="org.springframework.security.web.session.SessionManagementFilter">
	<beans:constructor-arg name="securityContextRepository" 
		ref="httpSessionSecurityContextRepository" />
	<beans:property name="invalidSessionStrategy" 
		ref="myInvalidSessionStrategy" />
 </beans:bean> 	
 <beans:bean id="httpSessionSecurityContextRepository"
	class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/>
 <beans:bean id="myInvalidSessionStrategy"
	class="com.writestreams.my.common.service.security.MyInvalidSessionStrategy">
  	<beans:constructor-arg name="invalidSessionUrl" value="/basic/authentication" />
	<beans:property name="myProperty" value="myvalue" />  		
 </beans:bean>

I wish JIRAs like SEC-1920 weren’t ignored.

Spring Web Services – HTTP Headers

I built web service calls (using Spring-WS) to a site that requires authentication fields in the SOAP header. It’s pretty pedestrian stuff except there are no direct Spring public methods to set header fields or namespaces. Instead I had to use the recommended WebServiceMessageCallback like so:

webServiceTemplate.sendSourceAndReceiveToResult(getUri(), source, 
        					getWebServiceMessageCallback(), result);
 
private WebServiceMessageCallback getWebServiceMessageCallback() {
 
   return new WebServiceMessageCallback() {
 
	   public void doWithMessage(WebServiceMessage message) {
		   try {
			SoapMessage soapMessage = (SoapMessage) message;
	           	SoapHeader header = soapMessage.getSoapHeader(); 
	           	StringSource headerSource = 
					new StringSource(getAuthenticationHeaderXml());
	           	Transformer transformer = 
					TransformerFactory.newInstance().newTransformer();
	           	transformer.transform(headerSource, header.getResult());
		   } catch (Exception e) {
			// handle exception
		   }
	   }
   };
}

That’s too verbose for what should have been one line of code.  I agree with JIRAs like SWS-479 that this should be simplified and extended.  Is an addHeader convenience method too much to ask?

BTW, when developing web service calls, I usually start with XMLSpy and soapUI to get the XML down first.  Once I switch over to coding, I typically set JVM system properties (proxySet, proxyHost, and proxyPort) to point to Fiddler2 so I can examine request and response packets.  It’s a nice arrangement, but I’m always looking for new ideas.  If you prefer a different approach, write me.

Use the Source

Spring’s online documentation is often quite helpful when getting started with most of their frameworks. That is, you walk through the examples, quickly hit something that doesn’t work, and then grab the source code and step through it, using the docs as a navigational aid.

Such was the case today when working through the Spring Web Services tutorial.  After fixing a few configuration issues, I got stuck on an exception thrown in MessageDispatcher.getEndpointAdapter:

java.lang.IllegalStateException: No adapter for endpoint […]: Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?

After attaching source and debugging, I found that the JDomPayloadMethodProcessor was not in the list of the DefaultMethodEndpointAdapter‘s methodArgumentResolvers.  It seems it should have been since initMethodArgumentResolvers adds it whenever org.jdom.Element is present (found by the classloader), and it was present.

Now I had never used JDOM before, but I thought I’d play along since the example used it.  Besides, he who dies with the most XML frameworks wins, right?  Since the example had org.jdom, I had Maven fetch it.

Upon further debugging, I found that initMethodArgumentResolvers wasn’t initializing because the list had already been set by AnnotationDrivenBeanDefinitionParser.registerEndpointAdapters.  And that class was looking for org.jdom2.Element.

Doh!  Those Spring developers should talk.  Meanwhile, I just grabbed jdom2 and converted to it.

This debugging stint was a small price to pay for a web services framework that definitely beats Axis, Axis2, and others I’ve used.  But I look forward to the day when I can use a Spring framework as a black box.  Until then, I’ll keep going to the Spring Source code.  And, of course, wish founder Rod all the best in his new endeavors.

No Charge for AWS-omeness

Until recently, I’ve only used Amazon Web Services (AWS) vicariously, such as S3 storage through Dropbox.  But since I’ve started pushing my “cloud” things beyond my hosting service’s limits, I couldn’t resist Amazon’s new one year free offer.

For my initial work, I needed only EC2 (Linux instances) and S3 (storage), so I navigated the obligatory sign-ups and confirmation emails and calls for these.  The services were activated after a short wait, and I could manage them through the AWS Management Console and Elasticfox.

For EC2, I started an Amazon AMI with SLES 11 (in spite of that Attachmate/Novell thing) and enabled ssh and http access in its security group.  I then ssh’ed in to install (zypper) and configure (chkconfig, etc.) apache2, mysql, php, mod-php, and a few other goodies.  Within just a few minutes, I had the entire stack running in the VM, ready to take on my stuff.

Compared with old-fashioned ways of building and publishing web servers, VMs, and VPSes, this is just too easy.  And it’s reassuring to know that this thing is hugely scalable.  But, best of all, it’s free.  At least for a year.

Microsoft SOAP – Lather, Restart, Repeat

A friend recently asked me to add web service wrappers around some C# .NET code I had written awhile back.  Since Microsoft invented SOAP/XML, it’s not surprising that it’s easy to do in .NET: just create the ASMX file and WebService subclass (with WebService and WebMethod attributes), and .NET handles the rest.  Visual Studio (in my case, VS 2008) even provides templates and wizards to create these for you: nice things like New Web Site – ASP .NET Web Service and Add New Item – Web Service.

I drank the .NET Kool-Aid back when I built this system and constructed with layers of assemblies.  So re-use was fairly straightforward: just add calls to methods (DLL entry points) in the appropriate layer.  Here again, with “Add Reference” and using clauses, Visual Studio makes it very easy.  That is, except for the bugs.

I occasionally got the familiar “type or namespace could not be found” error.  I assumed I had messed up a reference or using clause, or had a problem with the referenced assembly or one of its children.  But every possible cure for these yielded no joy.  Intellisense recognized the references just fine, but the compile/build didn’t.  The solution?  Restart Visual Studio.

This is a recurring bug which seems to move to new areas with each new VS release or fix.  In this case, it seems to be unique to web services referencing .NET assemblies, but it may pop up in other areas.  If I did regular .NET development (like maybe for my day job), I’d keep current on releases and fix levels.  But for this quick exercise, I stuck to the familiar Windoze-land solution: take one restart and call me in the morning.