Tuesday 28 July 2009

WLS: Nonsensical error message on web services HTTPS policy enforcement

Mostly a post to document something I keep on forgetting, hopefully useful to someone else.

Under WebLogic Server 10.3.1 (and maybe present in earlier versions of WLS?), on testing a deployed web service I occasionally get this HTTP response from WLS:
Error 500--Internal Server Error

javax.servlet.ServletException: unable to send error:
at weblogic.wsee.jaxws.HttpServletAdapter.sendAccessError(HttpServletAdapter.java:240)
at weblogic.wsee.jaxws.HttpServletAdapter.post(HttpServletAdapter.java:195)
at weblogic.wsee.jaxws.JAXWSServlet.doPost(JAXWSServlet.java:297)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
.. snip ..
Caused by: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: {http://www.w3.org/2003/05/soap-envelope}Client.Access is not a standard Code value
at com.sun.xml.internal.messaging.saaj.soap.ver1_2.Fault1_2Impl.checkIfStandardFaultCode(Fault1_2Impl.java:134)
at com.sun.xml.internal.messaging.saaj.soap.impl.FaultImpl.setFaultCode(FaultImpl.java:126)
at com.sun.xml.internal.messaging.saaj.soap.impl.FaultImpl.setFaultCode(FaultImpl.java:91)
.. snip ..
Note the message half way down the stack trace "Caused by". In turn in the WLS logs I receive the following error:
22/07/2009 12:15:46 PM com.sun.xml.internal.messaging.saaj.soap.ver1_2.Fault1_2Impl checkIfStandardFaultCode
SEVERE: SAAJ0435: {http://www.w3.org/2003/05/soap-envelope}Client.Access is not a standard Code value
<22/07/2009 12:15:46 PM WST> <[ServletContext@23322757[app:MyWebServices module:MyWebServices path:/MyWebServices spec-version:2.5], request: weblogic.servlet.internal.ServletRequestImpl@61061d[
POST /MyWebServices/My.Service HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: application/soap+xml;charset=UTF-8;action="http://acme.com/com/my.service"
User-Agent: Jakarta Commons-HttpClient/3.1
Content-Length: 4948

]] Root cause of ServletException.
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: {http://www.w3.org/2003/05/soap-envelope}Client.Access is not a standard Code value
at com.sun.xml.internal.messaging.saaj.soap.ver1_2.Fault1_2Impl.checkIfStandardFaultCode(Fault1_2Impl.java:134)
at com.sun.xml.internal.messaging.saaj.soap.impl.FaultImpl.setFaultCode(FaultImpl.java:126)
at com.sun.xml.internal.messaging.saaj.soap.impl.FaultImpl.setFaultCode(FaultImpl.java:91)
.. snip ..
You can see between the HTTP error and the WLS logs the same message:
com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: {http://www.w3.org/2003/05/soap-envelope}Client.Access is not a standard Code value
...followed by the SAAJ classes complaining about the SOAP Fault in the stack trace. In guessing what's occurring, the web service or WLS has thrown an error, but in transferring that error to a SOAP Fault response, the SAAJ classes don't think the SOAP fault itself is valid. In other words the real error is obscured because the error mechanism itself is bust.

So ignoring the error mechanism failure, what had I done wrong? After a lot of head scratching, I discovered my mistake.

I'd originally built a client to access my web service at the following URL:

http://MyWlsServer:7001/MyWebServices/My.Service

Subsequently I'd changed my web service to implement SSL via the WLS policy Wssp1.2-2007-Https.xml. To successfully access the web service thereafter I needed to access it at this new URL:

(Note the https delineator and port 7003, my configured WLS SSL port)

https://MyWlsServer:7003/MyWebServices/My.Service

...but in forgetting to change my client to the new URL, the error as above is thrown. Presumably the real error message would be "No such service" or "Service requires HTTPS" or "Chris, you've made another mistake!"

For reference I've tested this the other way around, where the web service isn't enforcing the WLS HTTPS policy, but the client access the https URL, and it works fine. This makes sense as the WLS policy is an enforcement of HTTPS traffic for that specific web service, not implementing HTTPS in general for WLS, that's left up to WLS which we've already preconfigured for WLS traffic. As such we can still use HTTPS for our web service even if the web service isn't enforcing HTTPS.

In addition note because of the generic error message returned here, readers should be careful to ascertain if what I describe in this post actually applies in their case. There's also the good chance this error will be for totally different reasons in different implementations of WLS.

And for the record I'll get around to logging an SR with Oracle Support soon. Anybody want to write the simple test case and steps to reproduce for me please? ;-)

No comments: