WCF: The HTTP request was forbidden with client authentication scheme 'Anonymous' - c#

I am pretty new to WCF and I was hoping someone could point me in the right direction.
Basically, I am trying to pull information from an existing WCF which was not developed by me.
So, for testing purposes, I created a console application and added the svc as a service reference.
I create a new instance of the client, and whenever I try to execute any of the methods, I get the following error:
The HTTP request was forbidden with client authentication scheme 'Anonymous'.
Does this mean the WCF requires a signed certificate to authenticate the client?
If this is the case, do I need to request/provide anything from/to the WCF's provider?
I´ve looked through several post related to this issue, but all these scenarios are based on the assumption that you have access to the server.
EDIT
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="..." />
<binding name="SecureByTransport">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/Web/ConnectWcf.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ConnectBasic"
contract="ConnectBasic.IConnectBasic" name="BasicHttpBinding_IConnectBasic" />
<endpoint address="https://localhost/Web/ConnectBasicWcf.svc"
binding="basicHttpBinding" bindingConfiguration="SecureByTransport"
contract="ConnectBasic.IConnectBasic" name="SecureByTransport" />
</client>
</system.serviceModel>
</configuration>

Related

How to implement security to WCF service to restrict the service to consume(not allow to consume service) at client side for other users

i am created WCF service and consumed that service at client application(web application) it is working fine.
but I am trying to implement security to WCF service to not consuming/restrict the service at client side for other users,i am using basicHttpBinding.
please find the client web.config code below,
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_WCFService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost/ WCFService.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IWCFService" contract="WCFServices.IWCFService" behaviorConfiguration="endpointCredentialsBehavior"
name="BasicHttpBinding_IWCFService" >
</endpoint>
</client>
Any help would be appreciated.

Can I configure a WCF service and consume a different on in the same application?

I'm trying to host on a website both the creation of a WCF service to send JSON data back to the client-side, as well as consume a different webservice used for cross application data exchange (it's a medical app, the data I need is hosted in an old ASMX webservice somewhere else)
My problem is the app is behind SSL, and basic authentication (which will go when we deploy to live), the service I'm consuming is over http and the rediculous amount of settings I need in the web.config are getting in each others way.
The web.config looks like this now
<behaviors>
<endpointBehaviors>
<behavior name="AJAXEndpoint" >
<webHttp/>
</behavior>
</endpointBehaviors>
</behaviors>
<services>
<service name="MyNamespace.Service.ACSvc">
<endpoint
behaviorConfiguration="AJAXEndpoint"
address="" binding="wsHttpBinding" bindingConfiguration="UsernameWithTransport"
contract="MyNamespace.Service.IACSvc">
</endpoint>
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true" />
<bindings>
<basicHttpBinding>
<binding name="wsAbbVieSoap">
<security mode="Transport" />
</binding>
</basicHttpBinding>
<wsHttpBinding>
<binding name="UsernameWithTransport">
<security mode="Transport">
<transport clientCredentialType="Basic" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://somewhere.else.com/externalservice.asmx"
binding="basicHttpBinding" bindingConfiguration="wsAbbVieSoap"
contract="AbbvieService.wsAbbVieSoap" name="wsAbbVieSoap" />
</client>
Over various iterations, I've had my service working, but the external service not working or neither service working.
What I want
My service - HTTPS, Basic authentication, response in JSON
External service - HTTP, Anonymous, SOAP response
These services are not aware of each other and have nothing to do with each other. They're separate parts of the same website - one (mine) for my own clientside scripts, and the other (external) for me to call serverside for various business uses.
Any help appreciated

How to configure WCF service deployed on IIS and remote client to authenticate from remote client PC?

I'm a noob; please help me understand this authentication config / bindings stuff that confuses me so much.
I have a C# WCF service deployed on IIS 7 on Win 2008. My client is a Windows Forms C# app. My client works just fine when it's running from the same server where the WCF service is running, but when I try to run my client from a remote PC, I get the following exception...
System.ServiceModel.Security.SecurityNegotiationException: The caller was not authenticated by the service.
I've read a few posts about these issues, and know that my problem is because my service and client are configured to use Windows authentication, which I guess is the default when using Visual Studio to create the service, and to add the service reference to the client. Below is my config before I made any changes, when it was still set to Windows (with irrelevant bits removed)...
Web.Config
<system.web>
...
<authentication mode="Windows"/>
...
<system.serviceModel>
<services>
<service name="MCLaborServer.LaborService" behaviorConfiguration="MCLaborServer.LaborServiceBehavior">
<!-- Service Endpoints -->
<endpoint address="" binding="wsHttpBinding" contract="MCLaborServer.ILaborService">
<!--
Upon deployment, the following identity element should be removed or replaced to reflect the
identity under which the deployed service runs. If removed, WCF will infer an appropriate identity
automatically.
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="MCLaborServer.LaborServiceBehavior">
<!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
<serviceMetadata httpGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
And from the App.Config on the client...
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ILaborService" closeTimeout="00:01:00"
openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows" proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows" negotiateServiceCredential="true"
algorithmSuite="Default" establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://<myDnsNameGoesHere>/MCLaborServer/LaborService.svc"
binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ILaborService"
contract="LaborService.ILaborService" name="WSHttpBinding_ILaborService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
</client>
</system.serviceModel>
So, first I changed "authentication mode="None"" in the web.config, and set "security mode="None"" in the client's app.config, and set both the clientCredentialType="None" for message and transport. I also commented out the "identity" sections in both the web.config and client's app.config. That broke it completely though and now the client running locally won't even work; it gives a "The remote server returned an unexpected response: (405) Method Not Allowed" error.
So what can I do to turn security off so that I can connect using a remote client? I do have anonymous access enabled by the way in IIS for my application.
I'd also like to ask, what's the best practice way to configure this so I can make webservice calls on a remote client over the internet in a semi-secure fashion without using SSL or doing anything that would cost money. I'm not really that concerned about security of the data because it's not really sensitive data, but still I'd like to make sure the server isn't open to attacks.
Also, I read that I can use Windows authentication, and then explicitly specify credentials in code, like below. If I do that, will it still work remotely? And if so, does that end up making my Windows credentials for the server be sent over the wire in an insecure fashion, so then I'd be open to getting my credentials hijacked?
SomeService.ServiceClient someService = new SomeService.ServiceClient();
someService.ClientCredentials.Windows.ClientCredential.UserName="windowsuseraccountname"
someService.ClientCredentials.Windows.ClientCredential.Password="windowsuseraccountpassword"
I've read through the following posts / links, but still am confused. Thanks for any help!
WCF error: The caller was not authenticated by the service
How to fix "The caller was not authenticated by the service"?
http://msdn.microsoft.com/en-us/library/aa291347(v=vs.71).aspx
http://www.devx.com/codemag/Article/33342/1763/page/2
We ran into similar issues when setting up low security WCF services that ran across domains. One of the biggest problems (if you can call it that) is that WCF is configured to be very secure by default. Because our application was entirely within a secure network, we did not want to have to bother with a lot of complicated certificates. Our workaround was to create a custom binding that allowed us to use username/password authentication for our services without any encryption. We based our implementation off of Yaron Naveh's Clear Username Binding. I would recommend that you have a look at that (and at his blog post introducing it).
Some good resources for learning about WCF Bindings and Security:
MSDN - Windows Communication Foundation Bindings Overview
MSDN - System-Provided Bindings
MSDN - Security Overview
MSDN - Programming WCF Security
MSDN - WCF Security Fundamentals
MSDN - Choosing a Transport
I fixed this by changing binding to basicHttpBinding, changing authentication to Forms and turning security off.

WCF Service ask login and password

Good day all
I have the following question: how to change web.config to ask for the credentials before user uses the service?
Thanks in advance
You have to do basic authentication for your purpose and disable all authentication from your IIS (Where your wcf will be hosted) except Basic Authentication
By default anonymous authentication is enabled that's why it will not ask when you access your service.
You need to do web.config setting also as per below
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="myHttpGetBinding">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="yourserviceaddress"
binding="basicHttpBinding"
bindingConfiguration="myHttpGetBinding"
contract="BasicAuthTest.MyServiceContract"
name="myBasicEndpoint"/>
</client>
</system.serviceModel>
Please refer following links
http://www.codeproject.com/KB/WCF/WCFBasicHttpBinding.aspx
http://www.codeproject.com/KB/WCF/BasicAuthWCFRest.aspx
http://msdn.microsoft.com/en-us/library/ee817643.aspx
Since your service is hosted in IIS, you should check out the guidance provided in this link, specifically the section on Authentication.
I believe that unless you have Windows Authentication turned on in IIS, which will automatically prompt the user, your application will be responsible for gathering the user's credentials.

How to sign a SOAP request with WCF

I have an 3rd party SOAP web service. I need to make a call to one of its methods. The request needs to be signed. How can I sign the request?
I assume by signing you mean that you sign the message using a certificate that is installed on the client side.
Doing this is relatively easy in WCF. Assuming you are using the wsHttpBinding in the security element you have to set the mode to SecurityMode.Message. You also have to set the clientCredentialType of the message element to MessageCredentialType.Certificate.
Then, you would have to set up a endpoint behavior and configure the clientCertificate element (which is a child of the clientCredentials element) to indicate where the client certificate is stored.
Even if you aren't using the wsHttpBinding, the configuration is pretty much the same for most of the other bindings when you want to use a client certificate to provide message-level security.
If you are making the call over HTTPS, then note that you will have to set the mode attribute on the security element to Mode.TransportWithMessageCredential.
The following is a question that was asked about using WCF to use the Amazon SOAP service which requires signing. I think the answer gives a great example, which might help with your situation.
How to sign an Amazon web service request in .NET with SOAP and without WSE
Edit: There was evidently some confusion about the link to this other StackOverflow question. I would like to point out the highest voted chosen answer. It is most definitely a WCF solution. You will notice the class SigningMessageInspector which inherits from IClientMessageInspector (a WCF interface). I think this section might help you.
Building on the very helpful answer from #casperOne I ended up with the following config:
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.2" />
</startup>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding>
<security mode="TransportWithMessageCredential">
<message clientCredentialType="Certificate" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<!-- specifies the endpoint to use when calling the service -->
<endpoint address="https://SomeEndPointUrl/v1"
binding="wsHttpBinding"
behaviorConfiguration="SigningCallback"
contract="ServiceReference1.EboxMessagePortType" name="MyBindingConfig">
</endpoint>
</client>
<behaviors>
<endpointBehaviors>
<behavior name="SigningCallback">
<clientCredentials>
<clientCertificate findValue="*somecertsubjectname*"
storeLocation="LocalMachine"
storeName="TrustedPublisher"
x509FindType="FindBySubjectName"
/>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
This for a soap client over https

Categories