Tracing capablities in WSE2
WSE 2.0 was released at TechEd today. Congratulations to the WSE team with Rebecca Dias, Keith Ballinger and the rest of the WSE Team. Version 2 comes with support for WS-Addressing, WS-Security, WS-Policy and a few other WS-* standards.
WS-Addressing moves the destination URL of the message into the message to enable routing and scenarios where messages are delivered over multiple protocols. Before WS-Addressing the URL of the destination was only available in the protocol part of the message. Is you were sending a SOAP message over HTTP, the URL was stored in the HTTP part of the message. You had no access to the URL from within your SOAP processor – unless your Web server vendor chose to give you access to the HTTP headers.
Now with WS-Addressing built into WSE, the Web service platform can actually determine if a message was indeed intended for the service that received it because WSE adds the <to> element to the header of the SOAP message:
<wsa:To xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
http://MyServer/MyService/Service.asmx</wsa:To>
WSE is actually being smart about the header and rejects messages where the destination in the <wsa:To> header and the URL in the HTTP header do not match.
One unfortunate consequence of this behavior is that you cannot use transparent tracing tools like tcpTrace and MSSoapT for message debugging. These tools act like an intermediary receiver and they do cause the URLs in the <To> header and in the HTTP header to not match. If you tried, the WSE web service returns a nice, descriptive fault telling you exactly what’s going on:
Microsoft.Web.Services2.Addressing.AddressingFault: Destination Unreachable ---> System.Exception:
WSE816:
The <To> header must match the value of an incoming message's HTTP Request Url if the soap receiver does not have an actor name.
The <To> header received contained "http://localhost:8080/WSEWebService/Service1.asmx"
while the HTTP Request Url was "http://localhost/WSEWebService/Service1.asmx".
You could fix the problem by modifing the WSE server code that is sending the message to tell the receiver about the URL of the tracing tool by adding a SoapActor attribute to the service.
<System.Web.Services.WebService(Namespace:="http://tempuri.org/WSEWebService/Service1"), _
SoapActor("http://localhost:8080/WSEWebService/Service1.asmx")> _
Public Class Service1
But that defeats the purpose of a transparent tracing tool and in many cases it may just not be feasible to modify the service code for troubleshooting purposes.
The good new is though that you no longer need tracing tools when you need to debug SOAP messages processed by a WSE service. You simple configure WSE to trace the output for you using the WSE 2.0 Settings tool. On the “Diagnostics” tab of the tool you will find the two sections “Message Tracing” and “Policy Tracing”. When you check the “Message Tracing” check boxes, WSE will write all processed messages – sent and received – to a trace file.
The “Policy Tracing” setting is even better though. With the powerful, declarative, policy based model, WSE does a lot of message processing with no coding involved. For example WSE will reject SOAP messages that violate the policy configuration. If the policy requires messages to be signed with a particular security token, but the message contains the wrong signature, WSE will simply return a policy violation fault. Unfortunately, the error message is not quite as descriptive as it was for the missing SoapActor attribute.
The policy trace output is extremely handy in this scenario, because it will tell you which policy was violated. The result of the policy enforcement step for each received message is written as a <message> element to the policy trace file:
<wset:message to="http://localhost/MyWebMethodsWse/Service1.asmx" from="http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous" action="http://example.org/mortgage-tools/CalculateMortgage" messageId="uuid:5334eabc-58e7-4220-984e-35cc2c5309ce" appDomain="/LM/W3SVC/1/Root/MyWebMethodsWse-16-127289102890960160" time="2004-05-12T22:52:19.7795824-05:00">
<wset:verify qname="wsp:Policy" wsu:Id="#Sign-Username-2" usage="Required" satisfied="false">
<wset:verify qname="wsp:MessagePredicate" usage="Required" satisfied="true" />
<wset:verify qname="wssp:Integrity" usage="Required" satisfied="false" />
</wset:verify>
</wset:message>
The example above shows that the required Integrity assertion of a policy named “Sign-Username-2” failed – the satisfied attribute for this assertion is set to false. Now you can check the policyCache.webinfo file for the policy with a wsu:Id attribute set to "Sign-Username-2":
<policyDocument xmlns="http://schemas.microsoft.com/wse/2003/06/Policy">
…
<policies …>
<wsp:Policy wsu:Id="Sign-Username-2">
…
<wssp:Integrity wsp:Usage="wsp:Required">
and verify what Integrity claims the policy required. Finally, you can cross-check the claims against the received message and you can determine the cause of the assertion failure. I really like the fact that tracing is now a framework feature. It seems to be the Microsoft way to handle this, more on that soon.