calling WCF Services hosted on IIS Server with wsHttpBinding having Message security mode from Ios Device - wcf-binding

I am calling WCF Service (wsHttpBinding with Message Security mode) from ios device but i am not able to see encrypted request and response .
while i am calling service from TestClient i can see request and response is encrypted.i want my request and response should be secure on network .
my configuration in web.config
<wsHttpBinding>
<binding name="Service.BasicHttp.BindingConfig">
<security mode="Message" />
</binding>
</wsHttpBinding>
--binding applied on endpoint
<endpoint address="" binding="wsHttpBinding" contract="CloudMitoAPI.ICloudMitoService" bindingConfiguration="Service.BasicHttp.BindingConfig"/>

You should add some parameter secure parameter in which add both json object and encrypted secure object in your request and then when you send it to server check the parameter object and encrypted secure object with your secret key is it proper or tampered.

Related

Why is Message Security and Transport Security needed?

Please see the XML below:
<client>
<endpoint address="https://hq-wk-is.lincspolice.local/WCFSSL/Service1.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpsBinding_IService1"
contract="ServiceReferenceInsecure.IService1" name="BasicHttpsBinding_IService1" />
</client>
Here is a basicHttpBinding over HTTP. The channel is encrypted.
What is the point of Message Security and Transport Security, which are apparently not available for basicHTTPBinding? The binding above is encrypted over HTTPS (using SSL). Therefore why is MessageSecurity and TransportSecurity needed?

Authentication on WCF Service using BasicHttpBinding and Authorization header

I'm having some issue with authentication on a third party's WCF service. I don't know how it's configured, it's like a black box for me. The only thing that I know, that those webservice should use Basic authentication, but may not.
I've added fiddler, and even wireshark to analyze what's happening inside of those requests, and found out that requests with authorization header do get authenticated. So basically, using a SoapUI I was able to authenticate on those WCF service.
I've generated a test client using svcutil and specified config file like this:
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_1" useDefaultWebProxy="false" >
<security mode="Message" >
<message clientCredentialType="UserName" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://theurl.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_1"
contract="CA_TestMediaSaturn.IDCIntegration" name="BasicHttpBinding_2" />
</client>
Also I've added authorization information to client in code file:
client.ClientCredentials.UserName.UserName = "one";
client.ClientCredentials.UserName.Password = "two";
But I wasn't able to get those Authorization header encoded in base64.
I wonder how can I configure my client to obtain those header in order to get authorized on webservice side. I did found an article describing how to make it on your own. But maybe there is a way to make it a lot easier?
UPDATE 1:
I've just receiver service configuration settings from 3rd party vendor. Mb it can somehow help in finding out the reason of error.
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_1" >
<security mode="TransportCredentialOnly">
<message clientCredentialType="UserName"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
you should set mode="Transport" instead of "Message". This will generate Authorization header. current setting is message security so authentication is inside SOAP.
EDIT: seems like you need pre-authenitcate.
in general wcf will first not send authorization header, and if the service returns a challenge to do it then it will send the message again with the header. some servers do not support this challenge mechanism and will require to send authorization header already at first shot. this is called pre authentication in .net 2. unfortunetely wcf does not support it. but you could do it yourself: first set security mode to None so WCF will not send security at all. then see example here how to add this header yourself to the wcf call.

WCF - Cannot obtain Metadata, but works when the XML Endpoint is removed?

I'm having a problem with the WCF Test Client. I cannot connect to my WebService because it keeps hitting this error:
Error: Cannot obtain Metadata from
http://xxx.xxxxxxxx.xxx/DPITerminal.svc If this is a Windows
(R) Communication Foundation service to which you have access, please
check that you have enabled metadata publishing at the specified
address. For help enabling metadata publishing, please refer to the
MSDN documentation at
http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange
Error URI: http://xxx.xxxxxxxx.xxx/DPITerminal.svc
Metadata contains a reference that cannot be resolved:
'http://xxx.xxxxxxxx.xxx/DPITerminal.svc'. Content Type
application/soap+xml; charset=utf-8 was not supported by service
http://xxx.xxxxxxxx.xxx/DPITerminal.svc. The client and
service bindings may be mismatched. The remote server returned an
error: (415) Cannot process the message because the content type
'application/soap+xml; charset=utf-8' was not the expected type
'text/xml; charset=utf-8'..HTTP GET Error URI:
http://xxx.xxxxxxxx.xxx/DPITerminal.svc There was an error
downloading 'http://xxx.xxxxxxxx.xxx/DPITerminal.svc'.
Here is my Web.Config: Link.
As you can see, I already have the
<serviceMetadata httpGetEnabled="true" />
as well as
<endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="mex" contract="IMetadataExchange" />
as suggested in the other StackOverflow questions. Still doesn't work.
I also noticed that when I comment the following endpoint:
<endpoint address="x" behaviorConfiguration="poxBehavior" binding="webHttpBinding" bindingConfiguration="web" contract="xxx.xxxxxxxx.xxxxxx.WebService.IDPITerminal" />
Everything works as expected. So I guess there's a problem with my XML Endpoint? It's weird since the XML Endpoint is sharing the JSON Endpoint's binding configuration, and the JSON one doesn't have any problems.
Also, Let me clarify that I'm only having problems with the WCF Test Client. The JSON & the XML Endpoint is both working properly.
EDIT:
I tried to comment the XML Endpoint, publish, then connect via the WCF Test Client. Then I uncommented the XML Endpoint, republish. The WCF Test Client still works- I mean I can send and receive data. When I refreshed the service, the Cannot obtain Metadata error popped out again.
It seems that WCF does not allow to use the same configuration for 2 endpoints.
There is workaround to fix the issue:
Change bindingConfiguration attribute for endpoint address="x" from web to web2
Add new web2 webHttpBinding configuration (copy web configuration):
Code for new binding configuration:
<webHttpBinding>
<binding name="web" ... />
<binding name="web2" closeTimeout="00:10:00" openTimeout="00:10:00"
sendTimeout="00:10:00" allowCookies="true" maxBufferSize="2147483647"
maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
<readerQuotas maxDepth="64" maxStringContentLength="2147483647"
maxArrayLength="8192" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
</binding>
</webHttpBinding>
Update:
WCF Test Client is not able to obtain metadata for webHttpBinding because such metadata does not exist. RESTfull service does not support WSDL or similar protocol that is used for basicHttpBinding or wsHttpBinding. Service returns error when WCF Test Client tries to get metadata in both cases (when WCF Test Client fails and when not) but for some reason in case of proposed workaround WCF Test Client manages to swallow error. It is hard to say why without WCF Test Client source codes.
Error in Trace Viewer:

connecting to wcf service hosted on domain from a client that is not on the domain

I would like an example or explanation of how to connect a client to a wcf service when the client is not on the domain.
I imagine there is a way to specify domain credentials with the client and the wcf service could talk to the authority (dc) to see if the client is secure.
I followed the examples on the msdn and can connect to see the metadata (methods available) but when using wshttpbinding I get "An unsecured or incorrectly secured fault was received from the other party".
Thanks in advance!
By default, wsHttpBinding will use Windows credentials - this only works if both your service and your calling client are member of the same domain (or member of domains with a mutual trust relationship).
If you want to authenticate using username/password, there's a number of things you need to do:
the service needs a certificate to authenticate itself to the caller, and to provide an encryption mechanism for the exchange of username/passwords and messages. So you will need to create a security certificate and install it on the server machine, and configure it:
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Internet">
<serviceCredentials
findValue="MyServiceCertificate"
storeLocation="LocalMachine"
storeName="My"
X509FindType="FindBySubjectName" />
</behavior>
<serviceBehaviors>
<behaviors>
<services>
<service name="MyService" behaviorConfiguration="Internet">
......
</service>
</services>
</system.serviceModel>
the client needs to set up a config that defines wsHttpBinding with message security, and username/password client credentials
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="UserNameWS">
<security mode="Message">
<message clientCredentialType="UserName" />
</security>
</binding>
<wsHttpBinding>
<bindings>
<client>
<endpoint name="Default"
address="........."
binding="wsHttpBinding" bindingConfiguration="UserNameWS"
contract="........." />
</client>
</system.serviceModel>
on the server side, you need to set up a mechanism to authenticate those username/passwords - typically, the easiest way is to use the ASP.NET membership system
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior name="Internet">
<userNameAuthentication
userNamePasswordValidationMode="MembershipProvider" />
<serviceCredentials
.....
</system.serviceModel>
before each call from the client, you need to set the username/password on your client-side proxy (this is one of the few things you cannot do in config - works only in code).
proxy.ClientCredentials.UserName.UserName = "YourUserName";
proxy.ClientCredentials.UserName.Password = "Top$Secret";
Read all about WCF security at the WCF Security Guidance site on Codeplex.
The error message "An unsecured or incorrectly secured fault was received from the other party" is a rather misleading one. A common cause is a difference in the bindings configuration between the client and the server. Check the system.serviceModel section of the web.config at the service side, and modify your client settings to match.
The reason why you can access metadata and cannot call service is that you are using WsHttpBinding probably with default configuration. It uses message security wich is involved only for service usage - not service metadata. It uses Windows credentials and Windows security to encrypt and sign message. Because of Windows security it works only when both client and server are on the same domain.
Your client is not part of domain - you can send windows credentials either with message security or transport security. In case of message security you will have to use clientCredentialType="UserName", default password validator and you will have to configure X509 certificate in service behavior to support encryption and signing. In case of transport security will either use HTTPS (X509 certificate configured in http.sys/IIS) or TransportCredentialOnly mode which will send windows user name and password as a plain text over HTTP (this is bad solution). In case of transport security set clientCredentialType="Basic".

WCF Security - how to allow all callers to this url?

I have a WCF service self-hosted in a windows service environment that works fine over http; over https I am unable to get to one URL without seeing the windows login prompt when running the silverlight application (or just opening the page in IE). I am using the IPolicyRetriever interface to ensure that the ClientAccessPolicy.xml file is found for the Silverlight app. This is working correctly.
The service in question has two endpoints defined:
<service behaviorConfiguration="defaultBehavior" name="WCFServices.Scheduler">
<endpoint address="WCFServices/Scheduler/" binding="wsHttpBinding" bindingConfiguration="dBinding" contract="WCFServices.IScheduler" />
<endpoint address="" binding="webHttpBinding" contract="WCFServices.IPolicyRetriever" behaviorConfiguration="PolicyBehavior" bindingConfiguration="dBinding" />
<host>
<baseAddresses>
<add baseAddress="https://myservername.org/" />
</baseAddresses>
</host>
</service>
If I go to the https://myservername.org/ I see the test service frontend (with a link to the wsdl). This is exposing the root IPolicyRetriever instance that the Silverlight app uses to pull down the policy file. I can load this and other URLs that expose the WCF service without any login prompts. BUT if I go to https://myservername.org/WCFServices/Scheduler/ in IE 8 I am greeted with a windows login. If I reset the security settings on the service and client to use http, I am able to do go to the latter url without the login prompt, and the silverlight app functions as expected. I suspect it has something to do with this WCF service being the only one with two endpoints defined (this windows service hosts 5 other WCF services, all of which only have 1 endpoint defined). Am I missing some authorization rules? I don't understand how that can be because all the other services load without prompts.
I would appreciate any help. I need the full https://myservername.org/WCFServices/Scheduler/ to serve the WCF service without asking for a login. Thanks for taking the time to read this.
As far as security, I only have this as my binding:
<binding name="dBinding" maxBufferPoolSize="524288" maxReceivedMessageSize="6553600">
<security mode="Transport">
</security>
</binding>
This issue was resolved by adding these lines to my security binding:
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"/>
</security>
...but that led to a host of other issues, all of which I've been able to handle thanks to WCF logging. If you run into a NOT FOUND (400) error when debugging your WCF service, don't believe it. Turn on server side debugging and pour through the generated log files -- you'll get to the bottom of it.
I should also note that I've found the second endpoint to return a bad request (400) when opening in a web browser, and this is BY DESIGN. The first endpoint will list all additional endpoints in its wsdl, and you can still use any of them in a proxy generating tool. Don't worry if you're getting a bad request error when trying to access them directly in a browser.