How to remove Soap Security header - c#

I'm currently trying to consume a SOAP 1.2 web service using a WCF client. Problem is, whenever I make a request a MessageSecurityException with the following inner message is thrown:
SOAP header Security was not understood
From what I can tell, the WS does not understand the Security header, which is currently marked as MustUnderstand="true".
How can I change MustUnderstandto false / remove the Security header?
Below is the binding I'm using right now:
<customBinding>
<binding name="CteRecepcaoSoap12">
<textMessageEncoding messageVersion="Soap12" />
<security authenticationMode="CertificateOverTransport"/>
<httpsTransport requireClientCertificate="true"/>
</binding>
</customBinding>

Related

SOAP redirect to another web service

I am consuming a SOAP Web Service through a client auto generated with the "Add Service Reference..." wizard in Visual Studio.
XML configuration on web.config like this :
<wsHttpBinding>
<binding name="ServiceBinding" allowCookies="true" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="52428800">
<readerQuotas maxDepth="52428800" maxStringContentLength="52428800" maxArrayLength="52428800" maxBytesPerRead="52428800" maxNameTableCharCount="52428800" />
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
</security>
</binding>
</wsHttpBinding>
I also pass an authorization header, and the service I call is in https
All working
Later I had to implement a redirect to another site without touching the client code
Server side then I made a 307 and changed the RedirectLocation of the ttpContext.Current.Response
The call to the other site is made but does not carry the authorization header
Situation: error - 401 not authorized
I also tried to make the other site in http, so that it is not necessary to pass the authorization header
With this XML configuration on web.config :
<wsHttpBinding>
<binding name="ServiceBinding" allowCookies="true" receiveTimeout="00:10:00" sendTimeout="00:10:00" maxReceivedMessageSize="52428800">
<readerQuotas maxDepth="52428800" maxStringContentLength="52428800" maxArrayLength="52428800" maxBytesPerRead="52428800" maxNameTableCharCount="52428800" />
<security mode="None"> </security>
</binding>
</wsHttpBinding>
Situation : Error because when the call comes back it violates the contract
I can make the second site in http / https but the first site of origin must necessarily be in https
How can I do ?
Thanks in advance

WCF set keepAliveEnable="false" not working

In my service I need to set keepAliveEnable=false in order to work with my load balancer. Therefore I followed instruction in this article. I did same thing mentioned in article but I am getting this error.
<customBinding>
<binding name="HttpBinding" keepAliveEnabled="False"/>
</customBinding>
The Scheme cannot be computed for this binding because this CustomBinding lacks a TransportBindingElement. Every binding must have at least one binding element that derives from TransportBindingElement.
Then I found set keepAliveFalse like below
<customBinding>
<binding name="HttpBinding" >
<textMessageEncoding />
<httpTransport allowCookies="false" keepAliveEnabled="false"/>
</binding>
</customBinding>
In this method service is getting started normal and I can get the responses. But in request headers still shows connection as keep alive. (I checked using firebug)
What is the correct way of doing this?
What is the end I need to set keep alive false (client or service) ?
Am I checking keepAlive in wrong way?

WCF-The request channel timed out after 1 min, while sendTimeout="00:25:00" on both sides

I am getting the error of "The request channel timed out after 1 min" even sendTimeout="00:25:00" on both sides.
If request is less than 1 min in time, then there is no issue but issue arises on request taking processing of greater than 1 min. on WCF service.
On WCF service side I have following bindings in my web.config file
<bindings>
<basicHttpBinding>
<binding maxReceivedMessageSize="67108864" transferMode="Streamed" closeTimeout="00:25:00" openTimeout="00:25:00" sendTimeout="00:25:00" receiveTimeout="00:25:00" >
<security mode="None" ></security>
</binding>
</basicHttpBinding>
</bindings>
On Client side, I have following bindings in my app.config file
<bindings>
<basicHttpBinding>
<binding name="streambinding" maxReceivedMessageSize="67108864" closeTimeout="00:25:00" openTimeout="00:25:00" sendTimeout="00:25:00" receiveTimeout="00:25:00" transferMode="Streamed">
<security mode="None"></security>
</binding>
</basicHttpBinding>
</bindings>
Can you add trace and message logs (at client and service) and share the findings? refer this article for client and this for service
from your config file of service and client I could make out that, your service bindingconfiguration is default I mean it doesn't have any name given, but client side binding configuration has a binding name. Try to keep it same both at the service and client, either have a name for binding configuration in service or remove the name from the client. Since you are accessing with different bindingName WCF not able to recognize the exact configuration and it might be timing out.

Configuring a service for multiple message ProtectionLevels while using transport security

I have a WCF service that I want to use message signing for, but only for certain calls- the rest should not be signed. I can't figure out how to set it up to support both.
The message signing uses a non-windows username and password that gets verified by a usernamepasswordvalidator on the service side. Both signed and unsigned messages should use transport security.
Here's an example of my interface:
[ServiceContract(ProtectionLevel=ProtectionLevel.None)]
public interface ISecTest
{
[OperationContract(ProtectionLevel = ProtectionLevel.Sign)]
string GetData(string value);
[OperationContract(ProtectionLevel = ProtectionLevel.None)]
string GetStuff(string stuff);
}
The problem I'm running into is that the signing seems to be based entirely on the service's binding configuration, as opposed to the ProtectionLevels defined on the interface.
If I use the following binding, both calls will require username credentials, regardless of the ProtectionLevel attributes:
<wsHttpBinding>
<binding name="secureWSHttpBindingConfig">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName" />
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
If I omit the message security and use the following binding, then neither call requires credentials:
<wsHttpBinding>
<binding name="tolerantWSHttpBindingConfig">
<security mode="Transport">
<transport clientCredentialType="None" />
</security>
</binding>
</wsHttpBinding>
Is this a complication from using transport security in addition to the message security?
Any advice on how I could accomplish this in a single service (if it's even possible)?
Thanks!
You cannot mix your protection level when you use transport security. You're going to have to use message security if this is important to you.

The provided URI scheme 'https' is invalid; expected 'http'. Parameter name: via

I am trying to make a WCF service over basicHttpBinding to be used over https. Here's my web.config:
<!-- language: xml -->
<service behaviorConfiguration="MyServices.PingResultServiceBehavior"
name="MyServices.PingResultService">
<endpoint address=""
binding="basicHttpBinding"
bindingConfiguration="defaultBasicHttpBinding"
contract="MyServices.IPingResultService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange" />
</service>
...
<bindings>
<basicHttpBinding>
<binding name="defaultBasicHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
...
<behaviors>
<serviceBehaviors>
<behavior name="MyServices.UpdateServiceBehavior">
<serviceMetadata httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
I am connecting using WCFStorm which is able to retrieve all the meta data properly, but when I call the actual method I get:
The provided URI scheme 'https' is invalid; expected 'http'. Parameter
name: via
Try adding message credentials on your app.config like:
<bindings>
<basicHttpBinding>
<binding name="defaultBasicHttpBinding">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None" realm=""/>
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
Adding this as an answer, just since you can't do much fancy formatting in comments.
I had the same issue, except I was creating and binding my web service client entirely in code.
Reason is the DLL was being uploaded into a system, which prohibited the use of config files.
Here is the code as it needed to be updated to communicate over SSL...
Public Function GetWebserviceClient() As WebWorker.workerSoapClient
Dim binding = New BasicHttpBinding()
binding.Name = "WebWorkerSoap"
binding.CloseTimeout = TimeSpan.FromMinutes(1)
binding.OpenTimeout = TimeSpan.FromMinutes(1)
binding.ReceiveTimeout = TimeSpan.FromMinutes(10)
binding.SendTimeout = TimeSpan.FromMinutes(1)
'// HERE'S THE IMPORTANT BIT FOR SSL
binding.Security.Mode = BasicHttpSecurityMode.Transport
Dim endpoint = New EndpointAddress("https://myurl/worker.asmx")
Return New WebWorker.workerSoapClient(binding, endpoint)
End Function
Change
from
<security mode="None">
to
<security mode="Transport">
in your web.config file. This change will allow you to use https instead of http
Are you running this on the Cassini (vs dev server) or on IIS with a cert installed? I have had issues in the past trying to hook up secure endpoints on the dev web server.
Here is the binding configuration that has worked for me in the past. Instead of basicHttpBinding, it uses wsHttpBinding. I don't know if that is a problem for you.
<!-- Binding settings for HTTPS endpoint -->
<binding name="WsSecured">
<security mode="Transport">
<transport clientCredentialType="None" />
<message clientCredentialType="None"
negotiateServiceCredential="false"
establishSecurityContext="false" />
</security>
</binding>
and the endpoint
<endpoint address="..." binding="wsHttpBinding"
bindingConfiguration="WsSecured" contract="IYourContract" />
Also, make sure you change the client configuration to enable Transport security.
I had same exception in a custom binding scenario. Anybody using this approach, can check this too.
I was actually adding the service reference from a local WSDL file. It got added successfully and required custom binding was added to config file. However, the actual service was https; not http. So I changed the httpTransport elemet as httpsTransport. This fixed the problem
<system.serviceModel>
<bindings>
<customBinding>
<binding name="MyBindingConfig">
<textMessageEncoding maxReadPoolSize="64" maxWritePoolSize="16"
messageVersion="Soap11" writeEncoding="utf-8">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
</textMessageEncoding>
<!--Manually changed httpTransport to httpsTransport-->
<httpsTransport manualAddressing="false" maxBufferPoolSize="524288"
maxReceivedMessageSize="65536" allowCookies="false" authenticationScheme="Anonymous"
bypassProxyOnLocal="false"
decompressionEnabled="true" hostNameComparisonMode="StrongWildcard"
keepAliveEnabled="true" maxBufferSize="65536"
proxyAuthenticationScheme="Anonymous"
realm="" transferMode="Buffered" unsafeConnectionNtlmAuthentication="false"
useDefaultWebProxy="true" />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="https://mainservices-certint.mycompany.com/Services/HRTest"
binding="customBinding" bindingConfiguration="MyBindingConfig"
contract="HRTest.TestWebserviceManagerImpl" name="TestWebserviceManagerImpl" />
</client>
</system.serviceModel>
References
WCF with custombinding on both http and https
I had the EXACT same issue as the OP. My configuration and situation were identical. I finally narrowed it down to being an issue in WCFStorm after creating a service reference in a test project in Visual Studio and confirming that the service was working. In Storm you need to click on the "Config" settings option (NOT THE "Client Config"). After clicking on that, click on the "Security" tab on the dialog that pops up. Make sure "Authentication Type" is set to "None" (The default is "Windows Authentication"). Presto, it works! I always test out my methods in WCFStorm as I'm building them out, but have never tried using it to connect to one that has already been set up on SSL. Hope this helps someone!
Ran into the same issue, this is how my solution turned out at the end:
<basicHttpsBinding>
<binding name="VerificationServicesPasswordBinding">
<security mode="Transport">
</security>
</binding>
<binding name="VerificationServicesPasswordBinding1" />
</basicHttpsBinding>
I basically replaced every occurrence of Http with Https. You can try adding both of them if you prefer.
If you do this programatically and not in web.config its:
new WebHttpBinding(WebHttpSecurityMode.Transport)
Its a good to remember that config files can be split across secondary files to make config changes easier on different servers (dev/demo/production etc), without having to recompile code/app etc.
For example we use them to allow onsite engineers to make endpoint changes without actually touching the 'real' files.
First step is to move the bindings section out of the WPF App.Config into it's own separate file.
The behaviours section is set to allow both http and https (doesn't seem to have an affect on the app if both are allowed)
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="true" />
And we move the bindings section out to its own file;
<bindings configSource="Bindings.config" />
In the bindings.config file we switch the security based on protocol
<!-- None = http:// -->
<!-- Transport = https:// -->
<security mode="None" >
Now the on site engineers only need to change the Bindings.Config file and the Client.Config where we store the actual URL for each endpoint.
This way we can change the endpoint from http to https and back again to test the app without having to change any code.
Hope this helps.
To re-cap the question in the OP:
I am connecting [to a WCF service] using WCFStorm which is able to retrieve all the meta data properly, but when I call the actual method I get:
The provided URI scheme 'https' is invalid; expected 'http'. Parameter name: via
The WCFStorm tutorials addresses this issue in Working with IIS and SSL.
Their solution worked for me:
To fix the error, generate a client config that matches the wcf service configuration. The easiest way to do this is with Visual Studio.
Open Visual Studio and add a service reference to the service. VS will generate an app.config file that matches the service
Edit the app.config file so that it can be read by WCFStorm. Please see Loading Client App.config files. Ensure that the endpoint/#name and endpoint/#contract attributes match the values in wcfstorm.
Load the modified app.config to WCFStorm [using the Client Config toobar button].
Invoke the method. This time the method invocation will no longer fail
Item (1) last bullet in effect means to remove the namespace prefix that VS prepends to the endpoint contract attribute, by default "ServiceReference1"
<endpoint ... contract="ServiceReference1.ListsService" ... />
so in the app.config that you load into WCFStorm you want for ListsService:
<endpoint ... contract="ListsService" ... />
I needed the following bindings to get mine to work:
<binding name="SI_PurchaseRequisition_ISBindingSSL">
<security mode="Transport">
<transport clientCredentialType="Basic" proxyCredentialType="None" realm="" />
</security>
</binding>
wsHttpBinding is a problem because silverlight doesn't support it!
I've added a "Connected Service" to our project by Visual Studio which generated a default method to create Client.
var client = new MyWebService.Client(MyWebService.Client.EndpointConfiguration.MyPort, _endpointUrl);
This constructor inherits ClientBase and behind the scene is creating Binding by using its own method Client.GetBindingForEndpoint(endpointConfiguration):
public Client(EndpointConfiguration endpointConfiguration, string remoteAddress) :
base(Client.GetBindingForEndpoint(endpointConfiguration),
new System.ServiceModel.EndpointAddress(remoteAddress))
This method has different settings for https service and http service.
When you want get data from http, you should use TransportCredentialOnly:
System.ServiceModel.BasicHttpBinding result = new System.ServiceModel.BasicHttpBinding();
result.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.TransportCredentialOnly;
For https you should use Transport:
result.Security.Mode = System.ServiceModel.BasicHttpSecurityMode.Transport;
In my case in web.config I had to change binding="basicHttpsBinding" to binding="basicHttpBinding" in the endpoint definition and copy the relative bindingConfiguration to basicHttpBinding section
<!-- Binding settings for HTTPS endpoint -->
<binding name="yourServiceName">
<security mode="Transport">
<transport clientCredentialType="None" />
<!-- Don't use message -->
</security>
</binding>
My solution, having encountered the same error message, was even simpler than the ones above, I just updated the to basicHttpsBinding>
<bindings>
<basicHttpsBinding>
<binding name="ShipServiceSoap" maxBufferPoolSize="512000" maxReceivedMessageSize="512000" />
</basicHttpsBinding>
</bindings>
And the same in the section below:
<client>
<endpoint address="https://s.asmx" binding="basicHttpsBinding" bindingConfiguration="ShipServiceSoap" contract="..ServiceSoap" name="ShipServiceSoap" />
</client>

Categories