I have a WCF client connecting to a Java based Axis2 web service (outside my control). It is about to have WS-Security applied to it, and I need to fix the .NET client. However, I am struggling to provide the correct authentication. I am aware that WSE 3.0 might make it easier, but I would prefer not to revert to an obsolete technology. Similar issues (unsolved), include this, this and this. The SOAP message should look like this:
However, mine looks like this:
My client looks like this: P.S. Note the required SecurityHeaderType param. What is that?
Current binding is as follows:
I've also tried a custom binding and got a similar error:
And endpoint (Address obviously changed...):
The custom fault that is being returned is as follows:
I've read lots about custom headers, tokens, bindings and my brain is completely confused. Can anyone suggest a step by step process for sending the message in the right format? This appears to be the way forward for WCF, using custom tokens, but how should one apply the digest and nonce as required? Any help welcomed. UPDATEI've had some limited success. I've used the Microsoft.Web.Services3 library to create a UsernameToken with the correct digest. I've then created my own custom behavior and in the BeforeSendRequest method I've done the following to inject the header:
I add the behavior like so:
I can now see the headers going across:
But I'm getting the error:
There appears to be a missing Type attribute on the password node:
However, I'm not sure if the security tracing and logging settings are blanket removing the attributes and content of those nodes. I've attempted to use the logKnownPii setting in the diagnostics logging, but the security information remains obscured. Any ideas on that one? |
||||
I can confirm that the UPDATE from my question actually works:
And the client:
The error message was unrelated. The security header works with a very simple basicHttpBinding:
Code sample of this in action can be found on my blog: http://benpowell.org/supporting-the-ws-i-basic-profile-password-digest-in-a-wcf-client-proxy/ |
||||
This question is well written -- many thanks. In reference to @Junto's "How do I use this" comment, it turns out that the SecurityHeader param on the service method can be used to add the header. I've included an example below. I believe that what's happening is that the SvcUtil.exe tool is barfing when trying to read the WS* DTDs. This is not obvious when you use the "Add Service Reference" wizard. But it is very obvious when you run svcutil.exe from the command line. Because svcutil.exe fails to read the WS* DTD's, the SecurityHeader object is not well developed. But Microsoft gives you an out with the .Any property. You can serialize the UsernameToken class right into the .Any property and your header will be added to the message. Again, thanks for this excellent question. How to use the SecurityHeader parameter to add a UsernameToken security header: Required tools:
Required Reference:
WCF service call:
App.config:
|
|||||
|
I had a similar problem recently and gave up searching for a non-WSE solution. After a couple days of pulling my hair out I ended downloading the WSE 3.0 SDK, generating a proxy class using WseWsdl3.exe, and creating a new policy for the UsernameToken. I was up and running in 15min. The following is currently working for me.
|