Sending SOAP request to WCF from a not .NET client - wcf

I have a WCF webservice that works correctly if I call it from a WPF client application, which is not in the same machine nor in the same domain. The app.config of the client application is:
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IMyService" closeTimeout="00:05:00"
openTimeout="00:05:00" receiveTimeout="00:10:00" sendTimeout="00:05:00"
allowCookies="false" bypassProxyOnLocal="false" maxBufferPoolSize="1524288000"
maxReceivedMessageSize="1524288000" useDefaultWebProxy="true">
<readerQuotas maxDepth="2000" maxStringContentLength="819200" maxArrayLength="163840" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<security mode="TransportWithMessageCredential" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://my.service.com/MyService.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IMyService"
contract="LicenseService.IMyService" name="BasicHttpBinding_IMyService" />
</client>
After calling the WCF service I sniff with fiddler the SOAP envelope, I modify the timestamp, I copy/paste the content in the client, for instance Chrome Postman, I send the request to the WCF and I receive an error. Below there the SOAP request envelope and the given error, which is too generic and I cannot find a good solution anywhere. My best guess is that it has something to do with the way WPF handles the security tokens but I cannot find what's wrong. The token can be used just once? Anybody might help?
Error message:
The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be
because of either a contract mismatch (mismatched Actions between
sender and receiver) or a binding/security mismatch between the sender
and the receiver. Check that sender and receiver have the same
contract and the same binding (including security requirements, e.g.
Message, Transport, None).
SOAP envelope:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2014-10-24T09:39:11.198Z</u:Created>
<u:Expires>2014-10-24T09:44:11.198Z</u:Expires>
</u:Timestamp>
<o:UsernameToken u:Id="token">
<o:Username>MyUsername</o:Username>
<o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</o:Password>
</o:UsernameToken>
</o:Security>
</s:Header>
<s:Body>
<GetProduct xmlns="http://tempuri.org/">
<productGuid>productGuid</productGuid>
</GetProduct>
</s:Body>
</s:Envelope>

The WCF service used CustomValidation with WS-Security. The client didn't support the WS-Security therefore it couldn't process the header of the SOAP message. Morevoer in the client the WS token was not refreshed and it was already been consumed by the WCF service

Related

How to create a .NET client for a wso2 Secure Token Service

I need to create a .NET client for a wso2 Secure Token Service.
Normally I would create a simple console or WinForm project adding a Service Reference to it. The exposed WSDL would be turned in a set of classes that I can use to query the service and to properly manage its response.
Unfortunately, the generated request and response classes are empty: just the class declaration without any property or method. This is similar to the behaviour described in this other (unanswered) Stack Overflow question https://stackoverflow.com/q/22049080/2131913
I have found a sample request for the service in this forum post: http://cxf.547215.n5.nabble.com/Sample-STS-Client-tp4643980p4664175.html and I made it to work with SOAP UI.
Is there a proper, and possibly automated, way to recreate the complex data structure needed to query the Secure Token Service?
EDIT
OK, after many tries I have reduced the SOAP request from the above forum post to the minimal structure needed to still get a RequestSecurityTokenResponse from the STS service.
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header xmlns:wsa="http://www.w3.org/2005/08/addressing">
<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">
<wsse:UsernameToken wsu:Id="UsernameToken-6D35592DCDDA26FFF3141578725699577">
<wsse:Username>USERNAME HERE</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">PASSWORD HERE</wsse:Password>
</wsse:UsernameToken>
<wsu:Timestamp wsu:Id="TS-6D35592DCDDA26FFF3141578725699576">
<wsu:Created>2014-11-12T10:14:16.995Z</wsu:Created>
<wsu:Expires>2014-11-12T10:16:16.995Z</wsu:Expires>
</wsu:Timestamp>
</wsse:Security>
<wsa:Action soap:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</wsa:Action>
<wsa:MessageID soap:mustUnderstand="1">uuid:6d4eab69-77f9-42b7-8d6b-1f710020fb0b</wsa:MessageID>
<wsa:To soap:mustUnderstand="1">STS ENDPOINT ADDRESS HERE</wsa:To>
</soap:Header>
<soap:Body>
<wst:RequestSecurityToken xmlns:wst="http://schemas.xmlsoap.org/ws/2005/02/trust">
<wst:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</wst:RequestType>
<wst:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</wst:TokenType>
<wst:Claims>
<wsid:ClaimType Uri="http://wso2.org/claims/userid" xmlns:wsid="http://schemas.xmlsoap.org/ws/2005/05/identity"/>
</wst:Claims>
</wst:RequestSecurityToken>
</soap:Body>
</soap:Envelope>
I have obtained a partial success defining in the app.config of my project either a single wsHttpBinding like the following:
<wsHttpBinding>
<binding name="SendUsername" messageEncoding="Text">
<security mode ="TransportWithMessageCredential">
<message clientCredentialType ="UserName"/>
<transport clientCredentialType ="Basic" />
</security>
</binding>
</wsHttpBinding>
with or without adding a CustomBinding like the following:
<customBinding>
<binding name="wso2carbon-stsSoap12Binding">
<security defaultAlgorithmSuite="Default" authenticationMode="IssuedToken"
requireDerivedKeys="true" securityHeaderLayout="Lax" includeTimestamp="true">
<localClientSettings detectReplays="false" />
<localServiceSettings detectReplays="false" />
<issuedTokenParameters keyType ="SymmetricKey" tokenType ="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0">
<issuer address =STS ENDPOINT ADDRESS HERE binding ="wsHttpBinding" bindingConfiguration ="SendUsername"/>
<claimTypeRequirements>
<add claimType ="http://wso2.org/claims/userid"/>
</claimTypeRequirements>
</issuedTokenParameters>
</security>
<textMessageEncoding messageVersion="Soap12" />
<httpsTransport />
</binding>
</customBinding>
In both cases however the request throws a timeout exception, and inspecting with WCF tracing the issued request I can see that it is missing the Claims element. Any hints?
Please refer this article
Security Token Service with WSO2 Identity Server 2.0
For more insight on this please refer:
http://wso2.com/library/3190/
Configuring WSO2 Identity Server Passive STS with an ASP.NET
Client
After many days struggling with WCF configuration option I have obtained a partial success.
The key that allows me to obtain a response from the Security Token Service is that I realized that, in the long term, I will need to operate in a federated security scenario. I don't need the token per se, but I need it to obtain a mean to authenticate to other services.
With this option in mind I started to explore what WCF has to offer for this kind of scenario and I built the following configuration options:
<wsFederationHttpBinding>
<binding name="fs">
<security mode="TransportWithMessageCredential">
<message issuedKeyType="SymmetricKey" issuedTokenType ="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0">
<issuer address = <!-- STS address here --> binding ="customBinding" bindingConfiguration ="StsBinding"/>
<claimTypeRequirements>
<add claimType="http://wso2.org/claims/userid" />
</claimTypeRequirements>
</message>
</security>
</binding>
</wsFederationHttpBinding>
The above binding is used to contact the service that needs token authentication while the following adds further instructions about how to contact the security token issuer:
<customBinding>
<binding name="StsBinding">
<textMessageEncoding messageVersion="Soap12WSAddressingAugust2004"/>
<useManagedPresentation/>
<security authenticationMode="UserNameOverTransport" includeTimestamp ="true" keyEntropyMode ="ServerEntropy" securityHeaderLayout ="Lax"
messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" >
</security>
<httpsTransport authenticationScheme ="Basic"/>
</binding>
</customBinding>
With this configuration, and with the help of Fiddler and WCF trace I can see I get a Security Token Response from the STS issuer.
Howevere as I said, in the beginnig, this was only a partial success because WCF infrastructure, when processing the token, says that it has a wrong action... but this can be the subjet of another question ;-)
I hope this can be considered a valid answer although my quest for token authentication is not yet concluded

WCF The HTTP request is unauthorized with client authentication scheme 'Negotiate'

I have a WCF service hosted on IIS with Windows Aut, I am able to connect to the service from my client application (WPF) on my local machine, but when I try to access the service from some other machine I get the following error
The HTTP request is unauthorized with client authentication scheme 'Negotiate'. The authentication header received from the server was 'Negotiate,NTLM'. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized.
I checked the providers in my IIS and there "Negotiate" is the first one and then the "NTLM". I also tried removing "NTLM" but that also did not help.
I have following configuration in my App.config
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding" maxReceivedMessageSize="2147483647"
receiveTimeout="00:30:00" sendTimeout="00:30:00"
openTimeout="00:10:00" closeTimeout="00:10:00">
<readerQuotas maxStringContentLength="2147483647" maxArrayLength="20971520" />
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
You may need to enable anonymous access in IIS.

Best way to communicate with non-WCF service

I have a non-WCF service that i need to communicate with. I have the WSDL of the service, and it uses WS-Security 1.0 with UsernameToken policy.
Example of the header:
<S11:Envelope xmlns:S11="..." xmlns:wsse="...">
<S11:Header>
...
<wsse:Security>
<wsse:UsernameToken>
<wsse:Username>username</wsse:Username>
<wsse:Password>password</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
...
</S11:Header>
...
</S11:Envelope>
What is the best way to communicate with this service?
If i use WCF, making the header look like what i need for the UsernameToken is going to be a problem from what i know, right? How can i do that?
On the other hand, i can make a non WCF proxy even though it's kind of obsolete.
What's the best way?
if the service uses ssl then you can have your wcf config like this:
<customBinding>
<binding name="NewBinding0">
<textMessageEncoding messageVersion="Soap11" />
<security authenticationMode="UserNameOverTransport">
<secureConversationBootstrap />
</security>
<httpTransport />
</binding>
</customBinding>
if the service does not use ssl then you should use ClearUsernameBinding

WCF client passing username token with mustUnderstand set to true

I'm tasked with creating a WCF service that will be consumed by an external client. The client is using WSSE security, specifically, they're passing a username token via a SOAP header.
The WCF service is hosted on an IIS server with SSL enabled.
At this point, I have a semi-working prototype. The issue I'm dealing with now is that the SOAP header has the mustUnderstand attribute set to 1, and this causes the process to fail.
I'd like some advice (or better yet, a code example smiles) on how to handle the username token in such a fashion as to return the proper response when the mustUnderstand attribute is true.
Here's a sample of the SOAP request that's failing:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:UsernameToken>
<wsse:Username>TestUser</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPWD</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">NzU3MjFhN2YtYTlmYS00ZWZjLTkxNjktY2ExZjlkZDEwNzE5</wsse:Nonce>
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2011-10-26T03:04:39Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<tem:Getstuff>
<tem:Arg1>Arg1</tem:Arg1>
<tem:Arg2>Arg2</tem:Arg2>
</tem:Getstuff>
</soapenv:Body>
</soapenv:Envelope>
If soapenv:mustUnderstand="1" is changed to soapenv:mustUnderstand="0", then the process works.
PS: Here's a revised sample request the client sent:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://tempuri.org/WService/Getstuff</Action>
<Security xmlns="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" wsu:Id="removed" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:Username>TestUser</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPass</wsse:Password>
<wsse:Nonce>2Udx78sh2y2xRJYJpZZ9+w==</wsse:Nonce>
<wsu:Created>2011-09-26T19:12:48Z</wsu:Created>
</wsse:UsernameToken>
</Security>
</s:Header>
<s:Body>
<Getstuff xmlns="http://tempuri.org/">
<Arg1>Arg1</Arg1>
<Arg2>Arg2</Arg2>
</Getstuff>
</s:Body>
</s:Envelope>
I receive the following response to the above requests:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode>s:MustUnderstand</faultcode>
<faultstring xml:lang="en-US">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.</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
Here's the binding:
<bindings>
<basicHttpBinding>
<binding name="TransportBind" maxBufferSize="2147483647" maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
<binding name="basic" maxBufferSize="2147483647" maxBufferPoolSize="2147483647"
maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</basicHttpBinding>
</bindings>
Your binding is basicHttpBinding. You need to use wsHttpBinding.
I solved this issue by not using the generated WS-Security header (when you add the Service Reference) in the WCF configuration, but rather commenting this out and instead letting .NET generate the header itself by using Client Credentials and specifying a Security Mode of "TransportWithMessageCredential":
client.ClientCredentials.UserName.UserName = "UserName";
client.ClientCredentials.UserName.Password = "Password";
<basicHttpBinding>
<binding name="Binding">
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
(We are using SSL, so hence this security setting).
Commented-out generated header:
<client>
<endpoint ...>
<!--<headers>
<wsse:Security...>
</wsse:Security>
</headers>-->
</endpoint>
</client>
Unfortunately I don't know enough WCF to capture the raw soap request/response to compare the difference and see why ClientCredentials doesn't cause the "was not understood" fault, while the generated header does.
As an aside, according to the MSDN documentation, if you only use "Transport" it won't know to use WS-Security: "Leave this property at its default value, which is System.ServiceModel.SecurityMode.Transport to not use WS-Security."
+1 #JohnSaunders because he is most likely barking up the right tree here.
Is your client .NET/WCF? If not, it may not be implementing WS-Security, or at least not in the way WCF wants it to.
If the client is .NET, this is just an mismatched binding on the client side.
The mustUnderstand flag says that the WS-Security header must be acknowledged and processed. A non-WS-Security client, whether it's because it doesn't speak WS-Security or isn't configured to, will ignore the header, try to use the message anyway and the server will punt.
Your other option is to turn of repudiation on the server. It'll stop sending WS-Security headers. Of course, then you don't get repudiation.

Configure WCF Client to Use Web Services Security Kerberos Token Profile 1.1

Morning,
Does anyone know how to configure WCF (any binding type, we are currently using WSHttpBinding but am happy to move to a CustomBinding or alternative if necessary) to use
Web Services Security Kerberos Token Profile 1.1
the details of which can be found here:
http://www.oasis-open.org/committees/download.php/16788/wss-v1.1-spec-os-KerberosTokenProfile.pdf
In particular I would like to know how to include the Security BinarySecurityToken and the SecurityTokenReference sections in the SOAP header. Example (taken from the above document)below:
<S11:Envelope xmlns:S11="..." xmlns:wsse="..." xmlns:wsu="...">
<S11:Header>
<wsse:Security>
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/oasis-wss225 kerberos-token-profile-1.1#Kerberosv5_AP_REQ" wsu:Id="MyToken">
boIBxDCCAcCgAwIBBaEDAgEOogcD...
</wsse:BinarySecurityToken>
...
<wsse:SecurityTokenReference>
<wsse:Reference URI="#MyToken" ValueType="http://docs.oasis-open.org/wss/oasis-wss-kerberos-token232 profile-1.1#Kerberosv5_AP_REQ" >
</wsse:Reference>
</wsse:SecurityTokenReference>
...
</wsse:Security>
</S11:Header>
<S11:Body>
...
</S11:Body>
</S11:Envelope>
Thanks in advance, Paul.
Straight from the MSDN documentation:
<wsHttpBinding>
<binding name="MyBinding">
<security mode="Message>
<message
clientCredentialType="Windows"
negotiateServiceCredential="false"
establishSecurityContext="false"/>
</security>
</binding>
</wsHttpBinding>