BTS 2013 - The message has a bad message signature - c#

I've a problem with BizTalk Server 2013 and a WCF Service. BizTalk needs to consume the WCF Service. BizTalk needs to sign the message with a X509 certificate and I receive the following error message:
There was a failure executing the send pipeline: "BizTalkUtilities.SignPipeline,
BizTalkUtilities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d749e81ab815db56" Source:
"MIME/SMIME encoder" Send Port: "SndPort_Sign_V2" URI: "http://XXXX/DemoServiceSigned
/DemoService.svc" Reason: The message has a bad message signature.
First I've created the service without security, everything works. Once I've setup my security (message security, Sign) it didn't work anymore. To be sure my service was fine, I've created a test WCF client which consumes the service with the security - no problem.
The message needs to be signed using a X509 certificate. All the certificates are in the correct place. I followed the info stated on MSDN.
Service config:
<bindings>
<wsHttpBinding>
<binding name="clientSignConfig">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
<services>
<service name="SignServiceBL.DemoService" behaviorConfiguration="DemoServiceBehavior">
<endpoint address=""
binding="wsHttpBinding"
bindingConfiguration="clientSignConfig"
contract="SignServiceBL.IDemoService" />
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="DemoServiceBehavior">
<serviceMetadata httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<clientCertificate>
<authentication certificateValidationMode="PeerTrust" trustedStoreLocation="LocalMachine"/>
</clientCertificate>
<serviceCertificate findValue="CN=DemoServiceServerCertificate"/>
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
Client config (this works for a WCF Client, but doesn't work in BizTalk)
<bindings>
<customBinding>
<binding name="demoService_CustomBinding">
<transactionFlow />
<security authenticationMode="SecureConversation" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10">
<secureConversationBootstrap authenticationMode="MutualSslNegotiated" messageSecurityVersion="WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10" />
</security>
<textMessageEncoding />
<httpTransport />
</binding>
</customBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="signingBehavior">
<clientCredentials>
<clientCertificate findValue="CN=DemoServiceSigning"
storeLocation="CurrentUser" storeName="My"/>
<serviceCertificate>
<authentication certificateValidationMode="PeerTrust" trustedStoreLocation="LocalMachine"/>
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
<client>
<endpoint address="http://XXXX/DemoServiceSigned/DemoService.svc"
binding="customBinding" bindingConfiguration="demoService_CustomBinding" behaviorConfiguration="signingBehavior"
contract="DemoService.IDemoService" name="WSHttpBinding_IDemoService">
<identity>
<dns value="DemoServiceServerCertificate"/>
</identity>
</endpoint>
</client>
I've setup tracing, but BizTalk isn't even sending a message to my service. It's like the sendpipeline is blocking my request.
Any ideas?
EDIT
You don't need the pipeline with a MIME/SMIME encoder to sign WCF messages. You should use this pipeline if you need to sign emails... See the first sentence of MSDN
BizTalk Server supports signing outbound messages and signature verification for inbound Secure Multipurpose Internet Mail Extensions (S/MIME) messages
Once I remove the pipeline, BizTalk sends a message to the service. The problem now is that it's signed and encrypted. I am figuring out how to tell BizTalk to only sign the message. If you have any ideas, feel free to post them. If I find it, I will post it ;-)

It wasn't easy, but I was able to solve my issue :-)
I wrote a blogpost about it, because it's a bit to complicated to create an answer here.
So check it out!

Related

WCF / wsHttpBinding / Message Security - BadTokenRequest

So got an older WCF service / client I'm working on. Added a new (static) logging system to it, actually and now doing some load testing.
Getting some really annoying sporadic issues now - claiming "Secure channel cannot be opened because security negotiation with the remote endpoint has failed". I noticed I get a CommunicationException with a fault name of Sender and subcode of BadContextToken.
Weird thing is, I'll get 2-4 correct responses, then a flurry of these exceptions, then start getting good responses again.
This is my first real foray into WCF, and not loving it so far :)
Service web.config:
<system.serviceModel>
<bindings>
<wsHttpBinding>
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</wsHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="ServiceBehavior" name="MyNamespace.MyService">
<endpoint address="" binding="wsHttpBinding" contract="MyNamespace.IMyService" bindingConfiguration="wsMessage">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceBehavior">
<serviceMetadata httpGetEnabled="false" />
<serviceCredentials>
<serviceCertificate findValue="MyValue" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
<userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="MyNamespace.UserNamePassValidator, MyNamespace" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
And on the client side, the client is instantiated as such:
var binding = new WSHttpBinding();
binding.Name = "WSHttpBinding_IMyService";
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
var client = new MyService(binding, "http://myserver:8080/myapp/service.svc");
var endpointIdentity = new DnsEndpointIdentity("MyValue"); // Match the certificate name used by the server
client.Endpoint.Address = new EndpointAddress(new Uri("http://myserver:8080/myapp/service.svc"), endpointIdentity, client.Endpoint.Address.Headers);
var creds = client.ClientCredentials;
creds.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
creds.UserName.UserName = "myuser";
creds.UserName.Password = "mypassword";
string retVal = client.SendRequest(); // SendRequest == one of the methods on my IMyService, returns a string. This is also where I sporadically see my error when load testing.
I would appreciate any pointers to help me out with this WCF setup!
These might be useful additions to your web.config:
<behaviors>
<serviceBehaviors>
<behavior name="CalculatorServiceBehavior">
<serviceDebug includeExceptionDetailInFaults="False" />
<serviceMetadata httpGetEnabled="True"/>
<serviceThrottling maxConcurrentCalls="20" maxConcurrentInstances="100"/>
</behavior>
</serviceBehaviors>
</behaviors>
<binding name="basicHttp" allowCookies="true" maxReceivedMessageSize="1048576" maxBufferSize="1048576" maxBufferPoolSize="1048576">
<readerQuotas maxDepth="32" maxArrayLength="1048576" maxStringContentLength="1048576"/>
</binding>
Usually this kind of "random" behaviour might depend on:
Timeouts (probably not your case, since you'd get a different exception)
Too many connections: if you client opens too many connections (and "forgets" to close them), you'll exceed the default allowed maximum (depending on context, it might be 10 connections).
You can act on this if you alter your web.config, editing maxConcurrentCalls and maxConcurrentInstances
Perhaps those errors are not random, but specific to some message; if so, that might be due to its size (i.e. it's too large): again, alter your web.config setting maxReceivedMessageSize, maxBufferSize, maxBufferPoolSize and readerQuotas
Of course you will get more info if you turn on WCF tracing.

Https wcf webservice Error

<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp />
</behavior>
<behavior name="webHttpBehavior">
<webHttp />
</behavior></endpointBehaviors>
</behaviors>
<services>
<service name="Implementation.Service" behaviorConfiguration="serviceBehavior">
<endpoint address="" binding="basicHttpBinding" contract="Contract.IService" behaviorConfiguration="web" bindingConfiguration="basicHttpBinding"></endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="CodeItSoap" closeTimeout="00:01:00">
<security mode="Transport">
<transport clientCredentialType="Basic" proxyCredentialType ="Basic" realm =" "/>
<message clientCredentialType= "username" algorithm ="default">
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://******.****-***/*****_*****?SOAP"
binding="basicHttpBinding" bindingConfiguration="CodeItSoap"
contract="Service.CodeItSoap" name="CodeItSoap" />
</client>
</system.serviceModel>
</configuration>
This is just a sample of my web.config file. When I run the service in the local host it runs fine and with the help of wcf test client I am getting the required output.
But when I put the dlls & web.config in the server where I have to host the service it's throwing an error
"Could not find a base address that matches scheme HTTP for the endpoint with binding BasicHttpBinding. Registered base address schemes are [https]"
Could any one tell me what the reason for the above error is?
General Flow of my web service
Application -> Server hosting(calc.svc) -> https://******.****-*/*****_*****?SOAP(authenticated)
when i add the service reference app.config got generated and by default basichttpbinding got added to app.config file.
As per my understanding web.config file is used to host the service in iis & i think my web.config is wrong.
In the client end point what should be the end point to calc.svc or https://*?soap?
Is the basichttpbinding ok for the https://prd36/calc.svc url?
do i need to specify one more binding for the application too?
Please help me understand i am heavily confused as the web.config which i have edited is a existing one which is still running the old service reference.
<serviceMetadata httpsGetEnabled="true"/>
<endpoint address="json" binding="webHttpBinding" contract="Contract.IService" behaviorConfiguration="web"></endpoint>
<endpoint address="mex" binding="mexHttpsinding" contract="IMetadataExchange"/>
above changes i did and the service url is running in web browser.
Use http:// instead of https:// in your endpoint address.
OR
User BasicHttpsBinding instead of BasicHttpBinding in your endpoint.
follow this link if the problem still exist.

create net.tcp service reference in client app using VS2015

I am using VS2015 and creating a WPF client app for a web service. The service is running on IIS on my network on a dedicated web server. When I try to add a service reference I get an error message that says it cannot recognize the uri prefix.
The web service web.config file is as follows:
<system.serviceModel>
<diagnostics wmiProviderEnabled="true">
<messageLogging logMalformedMessages="true" logMessagesAtTransportLevel="true" />
</diagnostics>
<bindings>
<netTcpBinding>
<binding name="netTcpBinding-Streamed" transferMode="Streamed" maxReceivedMessageSize="1073741824">
<readerQuotas maxStringContentLength="8192000" />
</binding>
</netTcpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceAuthorization principalPermissionMode="UseWindowsGroups" />
<serviceMetadata httpGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="[Namespace].Services.IIS">
<endpoint address="net.tcp://[server:port]/[website on iis]/Shared/Shared.svc" bindingConfiguration="netTcpBinding-Streamed" binding="netTcpBinding" contract="[Namespace].Services.Interfaces.Shared.IShared" />
<endpoint address="net.tcp://[server:port]/[website on iis]/UITax/Reports.svc" bindingConfiguration="netTcpBinding-Streamed" binding="netTcpBinding" contract="[Namespace].Services.Interfaces.UITax.Reports.IReport" />
<endpoint address="net.tcp://[server:port]/[website on iis]/UITax/Assignments.svc" bindingConfiguration="netTcpBinding-Streamed" binding="netTcpBinding" contract="[Namespace].Services.Interfaces.UITax.Assignments.IAssignments" />
</service>
</services>
<extensions>
<behaviorExtensions>
<add name="errorHandler" type="[Namespace].Services.Framework.WCF.WcfErrorHandlerExtension, [Namespace].Services.WCF.Framework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
</behaviorExtensions>
</extensions>
I enter "net.tcp://[server:port]/[website on iis]/Shared/Shared.svc" into the Address box and click GO and get the error.
What am I doing wrong?
VS2015 error message:
The URI prefix is not recognized.
Metadata contains a reference that cannot be resolved: 'net.tcp://[server:port]/[website on iis]/shared/shared.svc'.
The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:04:59.9980001'.
An existing connection was forcibly closed by the remote host
If the service is defined in the current solution, try building the solution and adding the service reference again.
as CodeCaster said in comment to the question, you should enable metadata publishing (<serviceMetadata httpGetEnabled="true" />) and add mex endpoint of type mexHttpBinding (so use http://[server:port]/[website on iis]/UITax/Reports.svc) to add service reference. OR add mex endpoint of type mexTcpBinding and use your net.tcp addresses to add service reference
Endpoints for metadata exchange:
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
Or
<endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange"/>

Impersonation in self-hosted WCF?

I'm currently developing a WCF service self hosted in a Windows service with the Self-Hosted SL Svc template.
The template works as it should be and I'm able to make calls from my Silverlight application, but when I tried to modify the project to use Impersonation:
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
It throws me an exception during host.Open();:
System.InvalidOperationException was
unhandled Message=The contract
operation 'GetData' requires Windows
identity for automatic impersonation.
A Windows identity that represents the
caller is not provided by binding
('CustomBinding','http://tempuri.org/')
for contract
('IService1','http://tempuri.org/'.
This is my configuration:
<system.serviceModel>
<bindings>
<customBinding>
<binding name="binaryHttpBinding">
<binaryMessageEncoding/>
<httpTransport/>
</binding>
</customBinding>
</bindings>
<services>
<service name="SLServiceLibrary.Service1" behaviorConfiguration="SLServiceLibrary.ServiceBehavior">
<endpoint address="Service1" binding="customBinding" contract="SLServiceLibrary.IService1" bindingConfiguration="binaryHttpBinding"/>
<endpoint address="" binding="webHttpBinding" contract="SLServiceLibrary.IClientAccessPolicy" behaviorConfiguration="webHttpEnablingBehavior"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/"/>
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="SLServiceLibrary.ServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="webHttpEnablingBehavior">
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
What do I have to change to make this work? do I need to add some configuration to my Silverlight client too?
Thanks in advance :)
I haven't used custom bindings (yet), but this blog entry may give you some help: http://geekswithblogs.net/robz/archive/2007/10/03/wcf-impersonation---specifying-windows-authentication-credentials-on-the-service.aspx
Well after a long search, I've come up with two solutions, one I found at MSDN:
<bindings>
<customBinding>
<binding name="binaryHttpBinding">
<binaryMessageEncoding/>
<httpTransport authenticationScheme="Ntlm"/>
</binding>
</customBinding>
</bindings>
The other one was at the Silverlight forums:
<bindings>
<customBinding>
<binding name="binaryHttpBinding">
<binaryMessageEncoding/>
<httpTransport authenticationScheme="Negotiate"/>
</binding>
</customBinding>
</bindings>
Don't know what is the major difference between these two, I've managed to open the service and call it from Silverlight successfully. If someone call elaborate on the difference, I would appreciate it.

WCF Service multiple endpoint configuration

I have a WCF service:
https://myservice/service.svc
https://myservice/service.svc?wsdl
Given below are the related section of my WCF Application's web.config (let me know if you need more):
<bindings>
<basicHttpBinding>
<binding name="basicHttp">
<security mode="TransportWithMessageCredential">
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="MyService.ServiceBehavior">
<serviceMetadata httpsGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="true"/>
<serviceCredentials>
<userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="SqlMembershipProvider"/>
</serviceCredentials>
<serviceThrottling maxConcurrentCalls="100" maxConcurrentInstances="100" maxConcurrentSessions="100"></serviceThrottling>
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service behaviorConfiguration="MyService.ServiceBehavior" name="MyService.Service">
<endpoint address="/ClientA" binding="basicHttpBinding" bindingConfiguration="basicHttp" name="basicHttpEndpoint" contract="MyService.IService"></endpoint>
<endpoint address="/ClientB" binding="basicHttpBinding" bindingConfiguration="basicHttp" name="basicHttpEndpoint" contract="MyService.IService"></endpoint>
<endpoint address="/ClientC" binding="basicHttpBinding" bindingConfiguration="basicHttp" name="basicHttpEndpoint" contract="MyService.IService"></endpoint>
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
</service>
</services>
I want my clients be able to access the service through the following links, but the links don't work: (or may be my syntax is wrong for the links below, let me know if that is the case)
https://myservice/service.svc/ClientA
https://myservice/service.svc/ClientB
https://myservice/service.svc/ClientC
following links work, but i don't think this is due to my configuration, as if i write anything after the last forward slash it still works ....
https://myservice/service.svc?wsdl/ClientA
https://myservice/service.svc?wsdl/ClientB
https://myservice/service.svc?wsdl/ClientC
https://myservice/service.svc?wsdl/asfgvafgfgf ... (this works too !!!)
Please let me know how to achieve this. I don't want to create separate service for all clients.
if this works, i want to use different contract="MyService.IService" in the endpoint definition for all clients, as the methods for each clients exposed in service would differ.
i also want to ask, would i be able to specify which connection string to use, depending on via which endpoint client is accessing the service?
And lastly: I Dont want:
https://myservice/service.svc
https://myservice/service.svc?wsdl
links to be accessible, i want the clients to use only their specified links ...
is that at all possible, or should i create separate services for each client ... ?
Thanks.
I think it require some setting in config file.
See this link,
http://keyvan.io/host-wcf-service-and-asp-net-application-on-same-virtual-directory
THis might help you.

Categories