My testing environment is:
1* Server :: SharePoint Site with WCF Service (in the ISAPI folder) and we configured the SSL and Cert on it.
1* Client :: Windows 10 with one Console Application to involve the WCF service
Testing (1) :all programs (WCF Service and Console Application) on the SharePoint Server
I created a Console application to invoke the WCF Service in SharePoint. Meantime, the Console application and WCF are on the same server. the outcome is everything works properly. It is successful to upload file into a Document Library.
Testing (2) :to simulate my client environment:
1* SharePoint :WCF Service
1* Windows 10 :Console application
the outcome failed and I got the error message:
The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'NTLM'
To be honest, I stuck here for a while. I also list out a portion of my source code for someone of experience to look at. I also posted some sample code and web.config in here.
Updated.
If we enable NTLM authentication, we have to enable the windows authentication.
Then when calling the service, we need to provide windows credential.
//it will use the binding and service endpoint address in the system.servicemode section.
ServiceReference1.ServiceClient client = new ServiceReference1.ServiceClient();
//windows account on the server.
client.ClientCredentials.Windows.ClientCredential.UserName = "administrator";
client.ClientCredentials.Windows.ClientCredential.Password = "abcd1234!";
try
{
Console.WriteLine(client.SayHello());
}
catch (Exception)
{
throw;
}
Auto-generated configuration.
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService">
<security mode="Transport">
<transport clientCredentialType="Ntlm" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="https://vabqia969vm:21011/" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService" contract="ServiceReference1.IService"
name="WSHttpBinding_IService">
<identity>
<userPrincipalName value="VABQIA969VM\Administrator" />
</identity>
</endpoint>
</client>
</system.serviceModel>
Feel free to let me know if the problem still exists.
Related
I have an application that pushes messages to a WCF endpoint via an MSMQ.
In dev, it works well when using the MSMQ protocol, but in production I need to do a network hop. I need to set this up so the queue pushes to the WCF endpoint over HTTP on a specific port (22200).
I thought this would work with SRMP, but it is not working. My outgoing MSMQ hangs with a message saying "Waiting to connect".
I've checked and I have access to the URL on the correct port.
How do I work out what the issue is?
Below is my client application configuration:
<bindings>
<netMsmqBinding>
<binding name="NetMsmqBinding_IMyProjectReceiverService" exactlyOnce="false" timeToLive="00:01:00" queueTransferProtocol="SrmpSecure">
<security mode="None" />
</binding>
</netMsmqBinding>
</bindings>
<client>
<endpoint
address="net.msmq://exampleuri.com:22200/private/MyProject.Receiver/v1/MyProjectReceiverService.svc"
contract="IMyProjectReceiverService"
binding="netMsmqBinding"
bindingConfiguration="NetMsmqBinding_IMyProjectReceiverService"
name="NetMsmqBinding_IMyProjectReceiverService" />
</client>
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>
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.
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.
I created WCF service and testing WCF client using stand alone application. I was able to view this service using Internet Explorer also able to view in Visual studio service references. Here is the error message.
"The content type text/html; charset=UTF-8 of the response message does not match the content type of the binding (text/xml; charset=utf-8)."
Could you please advice what could be wrong?
Thank you.
Since the returned content type is text/html, I suspect your call result in a server-side error outside of WCF (you are receiving an HTML error page).
Try viewing the response with a web debugging proxy such as Fiddler.
(Edit based on comments) :
Based on your comments, I see that your WCF is hosted under Sharepoint 2010, in a form-authenticated site.
The error you are receiving is due to the fact that your your WCF client is NOT authenticated with sharepoint -- it does not have a valid authentication cookie. Sharepoint then return an HTTP Redirect to an html page (the login.aspx page); which is not expected by your WCF client.
To go further you will have to obtain an authentication cookie from Sharepoint (see Authentication Web Service) and pass it to your WCF client.
(Updated edit) :
Mistake: The site is using claim based authentication.
Although this is not necessarily due to cookies or form authentication, the explaination of the provided error message remain the same. An authentication problem cause a redirection to an HTML page, which is not handled by the WCF client.
This may be helpful, check the url rewrite rules in ISS 7. This issue will occur if is you didn't configure rule properly.
It sounds like your application is expecting XML but is receiving plain text. What type of object are you passing in?
text/html is SOAP 1.1 header and Content-Type: application/soap+xml is SOAP 1.2
Verify your bindings and return header.
It should be same either 1.1 or 1.2
Add the following code to the web.config server project
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBinding_IService">
<security mode="Transport">
<transport clientCredentialType="None" proxyCredentialType="None"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="Service">
<endpoint address="" name="BasicHttpBinding_IService"
binding="basicHttpBinding"
bindingConfiguration="basicHttpBinding_IService"
contract="IService" />
</service>
then update client web service,After the update, the following changes are made web.config
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService">
<security mode="Transport" />
</binding>
</basicHttpBinding>
</bindings>
<endpoint address="https://www.mywebsite.com/Service.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IService"
contract="Service.IService" name="BasicHttpBinding_IService" />
I hope to be useful
i was getting this error in NavitaireProvider while calling BookingCommit service (WCF Service Reference)
so, when we get cached proxy object then it will also retrived old SigninToken which still may not be persisted
so that not able to authenticate
so as a solution i called Logon Service when i get this exception to retrieve new Token