SOAP Header not understood by .NET client when calling Webservice - c#

I've been trying to call a third-party webservice from a .NET client. I have had to set some custom headers for each request in order to adhere to their Authentication requirements.
I have used this answer in order for me to get the request header values to appear as so:
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" s:mustUnderstand="0">
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" wsu:Id="UsernameToken-2">
<wsse:Username>Jimbob</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">P#ssword</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</s:Header>
<s:Body>
...
</s:Body>
</s:Envelope>
(I am doing this by setting the a custom <endpoint><headers /></endpoint> section in config)
I have inspected the request via Fiddler and it is sending the correct header values, and the webservice is returning expected results.
However, the client is throwing the following exception when it receives the result:
System.ServiceModel.ProtocolException : The header 'Security' from the namespace 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd' was not understood by the recipient of this message, causing the message to not be processed. This error typically indicates that the sender of this message has enabled a communication protocol that the receiver cannot process. Please ensure that the configuration of the client's binding is consistent with the service's binding.
The relevant part of the repsonse (from Fiddler) is this:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" soap:mustUnderstand="1">
<wsse:UsernameToken wsu:Id="UsernameToken-371676">
<wsse:Username>SOMEUSERTOKEN</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">SOMEUSERTOKEN</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body>
...
<soap:Body>
</soap:Envelope>
Basically I'm now lost. I presume I need to perform some sort of message inspection to flag that header as understood, but it does seem quite a lot of heavy lifting just to interpret a result (which I'm already getting from the webservice).
Any help is much appreciated.

If you just want to do the authentication , I did used the following code for my c# console application and it worked. I used this code in the config file though under <system.serviceModel>-><client>-> <endpoint>
<headers>
<wsse:Security mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" >
<wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:Username>SOMEUSERTOKEN</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">SOMEUSERTOKEN</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</headers>

Related

EWS Managed API Error - An object within a change description must contain one and only one property to modify

Any ideas why exchange keeps throwing this error?
I'm using Microsoft Exchange Managed API 2.0, from C#.
The sample request and responses are intercepted using Fiddler
I'll post a request and response sample.
I even tried to remove all properties and leave just a simple one, and still same error.
It doesn't seem to be a collections related issue
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:RequestServerVersion Version="Exchange2013_SP1" />
</soap:Header>
<soap:Body>
<m:UpdateItem MessageDisposition="SaveOnly" ConflictResolution="AlwaysOverwrite">
<m:ItemChanges>
<t:ItemChange>
<t:ItemId Id="AAMkADgwNWY5NDQ3LWRkMTQtNGQyZS04ODMxLTQzMDQ1NWU5NTI2OABGAAAAAADzrqMpUzgAQoRJwq9Jq9ArBwDjC+q0IBppSKdYNLEIzckAAADAlx38AADjC+q0IBppSKdYNLEIzckAAADAly/BAAA=" ChangeKey="EQAAABYAAADjC+q0IBppSKdYNLEIzckAAADAis/g" />
<t:Updates>
<t:SetItemField>
<t:FieldURI FieldURI="contacts:GivenName" />
<t:Contact>
<t:GivenName>Mickeyaabsbbcdsf</t:GivenName>
</t:Contact>
</t:SetItemField>
<t:SetItemField>
<t:FieldURI FieldURI="contacts:FileAs" />
<t:Contact />
</t:SetItemField>
<t:DeleteItemField>
<t:FieldURI FieldURI="contacts:FileAs" />
</t:DeleteItemField>
</t:Updates>
</t:ItemChange>
</m:ItemChanges>
</m:UpdateItem>
</soap:Body>
</soap:Envelope>
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" MajorVersion="15" MinorVersion="20" MajorBuildNumber="2241" MinorBuildNumber="12" Version="V2018_01_08"/>
</s:Header>
<s:Body>
<m:UpdateItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:UpdateItemResponseMessage ResponseClass="Error">
<m:MessageText>An object within a change description must contain one and only one property to modify.</m:MessageText>
<m:ResponseCode>ErrorIncorrectUpdatePropertyCount</m:ResponseCode>
<m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
<m:MessageXml>
<t:Value Name="PropertyCount">0</t:Value>
<t:Value Name="PropertyInfo"/>
</m:MessageXml>
<m:Items/>
</m:UpdateItemResponseMessage>
</m:ResponseMessages>
</m:UpdateItemResponse>
</s:Body>
</s:Envelope>
Turns out the problem is, I am performing 2 operations on the "FileAs" field.
At some point in the code I assigned a value to it, use that value somewhere else in the flow, and then making it null, like it was.
This, in turns, triggers a state change in the object that holds the property.
The contact objects sees that I did an assignment, and then a null, which equals deleting the value.
This double state change is confusing for exchange, because it doesn't know which of the 2 state changes is the correct one that should be persisted in Exchange, therefore, triggering that error.
So all in all, avoid doing this in the code!
contact.FileAs = "SomeValue"
........
contact.FileAs = null;
You can also see the confusing effect it has on the request xml (it does a set item field, with no value, and then a delete item field)
<t:SetItemField>
<t:FieldURI FieldURI="contacts:FileAs" />
<t:Contact />
</t:SetItemField>
<t:DeleteItemField>
<t:FieldURI FieldURI="contacts:FileAs" />
</t:DeleteItemField>

Configuration WCF Client for WIF .NET 4.5

I've a problem to get a token from the STS. I get the token if I use SoapUI. But I don't know how to configure my client application that it creates a request like:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://docs.oasis-open.org/ws-sx/ws-trust/200512/RST/Issue</a:Action>
<a:To s:mustUnderstand="1">https://.../idp/sts.wst</a:To>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<o:UsernameToken>
<o:Username>xxxUSERxxx</o:Username>
<o:Password>xxxPWxxx</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body>
<trust:RequestSecurityToken Context="http://client.ws.com" xmlns:trust="http://docs.oasis-open.org/ws-sx/ws-trust/200512">
<wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<a:EndpointReference>
<a:Address>xxxADDRESSxxx</a:Address>
</a:EndpointReference>
</wsp:AppliesTo>
<trust:KeyType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Bearer</trust:KeyType>
<trust:RequestType>http://docs.oasis-open.org/ws-sx/ws-trust/200512/Issue</trust:RequestType>
<trust:TokenType>http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0</trust:TokenType>
</trust:RequestSecurityToken>
</s:Body>
</s:Envelope>
Can anybody help me?
Does the STS expose a metadata exchange endpoint? If so you could create a client proxy via visual studio's "add service reference" dialogue (or just use svcutil).
You could use this article as a starting point.

WebMethod is been added like a part of the request, WCF Service

I have tried to test my svc service with SoapUI, but when I create the request, the method is been added like a part of him. but is not part of the request.
There's anyone know how to fixed ?
Here is an example of my request
<soap:Body>
<findSchedule> <!--findSchedule is the part that i want to remove-->
<request>
...
</request>
</findSchedule>
</soap:Body>
This is how the request has to look like.
<soap:Body>
<request>
...
</request>
</soap:Body>

SOAP call with multiple namespaces

I have a problem with some calls to a web service:
When I create the SoapEnveloper I put this on the wire
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header/>
<soapenv:Body>
<tem:GetUserIDByName>
<tem:sUser>sample</tem:sUser>
<tem:oParam>
<tem:CountryURL>US</tem:CountryURL>
<tem:noCache>false</tem:noCache>
</tem:oParam>
</tem:GetUserIDByName>
</soapenv:Body>
</soapenv:Envelope>
But the response comes as:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing">
<env:Header>
<wsa:MessageID>urn:16092960528611E1BFADB7181697B03B</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://www.w3.org/2005/08/addressing/anonymous</wsa:Address>
<wsa:ReferenceParameters>
<instra:tracking.ecid xmlns:instra="http://xmlns.oracle.com/sca/tracking/1.0">0000JLUJsMq0VsSqyCBh6G1FCdSn000GYf</instra:tracking.ecid>
</wsa:ReferenceParameters>
</wsa:ReplyTo>
</env:Header>
<env:Body>
<GetUserIDByNameResponse xmlns="http://tempuri.org/">
<Error>
<ErrorCode>0</ErrorCode>
<ErrorMessage>''</ErrorMessage>
</Error>
<ReturnValue>0</ReturnValue>
<GetUserIDByNameResult>9815</GetUserIDByNameResult>
</GetUserIDByNameResponse>
</env:Body>
</env:Envelope>
Now the autogenerated proxy classes for this service call has the following attribute:
[SoapDocumentMethodAttribute("http://tempuri.org//GetUserNameById",
RequestNamespace="http://tempuri.org/",
ResponseNamespace="http://tempuri.org/",
Use=System.Web.Services.Description.SoapBindingUse.Literal,
ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
corresponding to the default namespace.
The problem seems that the de-serialization process does not seem to understand the response.
Any idea on how to fix this?

Convert XML namespace prefixes with C#?

I have run into an exasperating problem getting a Java service client to communicate successfully with a WCF service. I have overcome many hurdles, and I believe that this is my last one. The problem boils down to how Java Axis + WSS4J seem to handle xml namespaces. The Java platform seem to be very rigid in what they expect for xml namespace prefixes, and as such, do not understand the WCF reply messages.
My problem in a nutshell is as follows. I have an xml response similar to the following from my WCF service:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1" u:Id="_3">http://tempuri.org/IProcessor/DoProcessingResponse</a:Action>
<h:CorrelationID xmlns:h="http://tempuri.org/">1234</h:CorrelationID>
<a:RelatesTo u:Id="_4">uuid:40f800a0-9613-4f4a-96c5-b9fd98085deb</a:RelatesTo>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<!-- WS-Security header stuff -->
</o:Security>
</s:Header>
<s:Body u:Id="_1">
<e:EncryptedData Id="_2" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:e="http://www.w3.org/2001/04/xmlenc#">
<e:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<e:CipherData>
<e:CipherValue>NfA6XunmyLlT2ucA+5QneoawHm+imcaCltDAJC1mRZOSxoB6YGpDLY1FyVykPbPGDoFGUESLsmvvbD62sNnRrgE+AuKPo+1CD3DF4LfurRcEv9A50ba9V+ViqlrhydhK</e:CipherValue>
</e:CipherData>
</e:EncryptedData>
</s:Body>
</s:Envelope>
This response uses simple one-character namespace prefixes for most things, such as 's' for SOAP Envelope, 'a' for WS-Addressing, 'o' for 'WS-Security', etc. The Java client, namely WSS4J, seems to expect the following:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://www.w3.org/2005/08/addressing" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<wsa:Action soap:mustUnderstand="1" wsu:Id="_3">http://tempuri.org/IProcessor/DoProcessingResponse</wsa:Action>
<h:CorrelationID xmlns:h="http://tempuri.org/">1234</h:CorrelationID>
<wsa:RelatesTo wsu:Id="_4">uuid:40f800a0-9613-4f4a-96c5-b9fd98085deb</a:RelatesTo>
<wsse:Security soap:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<!-- WS-Security header stuff -->
</wsse:Security>
</soap:Header>
<soap:Body u:Id="_1">
<xenc:EncryptedData Id="_2" Type="http://www.w3.org/2001/04/xmlenc#Content" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#">
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
<xenc:CipherData>
<xenc:CipherValue>NfA6XunmyLlT2ucA+5QneoawHm+imcaCltDAJC1mRZOSxoB6YGpDLY1FyVykPbPGDoFGUESLsmvvbD62sNnRrgE+AuKPo+1CD3DF4LfurRcEv9A50ba9V+ViqlrhydhK</xenc:CipherValue>
</xenc:CipherData>
</xenc:EncryptedData>
</soap:Body>
</soap:Envelope>
Upon receipt of my response message, the Java client and WSS4J seem to want to look up elements by their own internal xml aliases, such as 'wsa' for WS-Addressing, and 'wsse' for WS-Security Extensions. Since neither of those namespaces are present in the actual response xml, exceptions are thrown.
I am wondering if there is any simple way to transform an xml document from one set of namespaces to another set using C#, .NET, and the System.Xml namespace. I've poked around with XmlNamespaceManager a bit, but it does not seem to fully support what I need...or at least, I have been unable to find any really useful examples, and am not fully sure how it works. I am trying to avoid having to write some heavy-duty process to handle this manually myself, as I do not want to drastically impact the performance of our services when called by a Java Axis/WSS4J client.
This particular problem seemed to stem from an old and buggy version of WSS4J. Newer versions do not seem to have this problem, and it is no longer an issue.

Categories