I have a console app client that talks to a WCF service hosted by a console app on a different server. It use windows authentication with security mode = message
It works just fine until I change the service to impersonate the clients credentials. The changes I do to accomplish that is:
1. Add <serviceAuthorization impersonateCallerForAllOperations="true" /> to the service behaviour
2. Add [OperationBehavior(Impersonation = ImpersonationOption.Required)] to my method signature
I then host my service and it runs as normal, all good.
In my client the only thing I do is add:
ChannelFactory<IService1> channel = new ChannelFactory<IService1>(binding, endPoint);
channel.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
I then run my client and get the error:
The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
Is there something else I'm missing that I need to do to the client config?
It could be that your server settings do not match the contract.
On the server side:
Is IIS set to windows authentication?
Is web.config set to windows authentication?
Is web.config set to impersonate = true
My guess is that you are missing the last one.
I would suspect that the wcf method call triggers an exception on the server side. Do you have any infrastructure in place to capture server side exceptions or payloads? If not then use something like wcf trace logging to record traffic.
This should give you a more meaningful error.
If you can add this to your question hopefully we can discern what is causing the issue.
Related
I have a WP8 app and this app needs to consume a WCF service to send/receive data from my server.
I have the service and the app working well in my developer computer, using localhost and VS2013.
Now I installed the WCF service in IIS and the service is working well!
My question is: I want a way to dinamicaly change the address of my WCF service without the need to recompile the app and deploy it!
I've found this peace of code in another thread at SO that I would like to know if it would work in any address that I change in my app dinamycally:
private MyServiceClient GetMyServiceClient(string url)
{
Uri uri = new Uri(url);
BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
EndpointAddress address = new EndpointAddress(uri);
MyServiceClient client = new MyServiceClient(binding, address);
return client;
}
My app will run for now just in intranet enviroment, so I don't need a high security level to access my server, the basic httpbinding it's for now good enough.
You can look at putting your wcf configuration into a configuration file. See the post here - http://msdn.microsoft.com/en-us/library/ms733932(v=vs.110).aspx
Also take a look at this link - http://www.codeproject.com/Articles/576820/Basic-Step-by-Step-WCF-WebService
It gives an example of consuming a wcf endpoint that is defined in a config file. It uses a wpf example, but it should be easily adaptable to your scenario.
I am having an issue with my WCF application when connecting a client from Windows 8.1. I've been going crazy over this the last couple of days, and cannot get to the bottom of it. Here is the scenario:
My WCF service is fairly straight forward. It uses a basicHttpBinding, with TransportCredentialOnly security mode, and digest client credential type. (The web.config file is here: http://pastebin.com/LsWmcfTs). It does it this way as I need the windows identity on the server side.
My client is a console application, the failure happens when it attempts to invoke the 'Ping' method in my service (which simply returns the text 'Pong') The code used to connect to the service is below:
var basicBinding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
basicBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Digest;
var client = new TestExecutionEngineClient(basicBinding, new EndpointAddress(uri));
client.Open();
client.Ping();
This has been working for over a year on all connecting clients All except for Windows 8.1 that is, where it never has worked.
When it hits client.Ping(); I get the exception below:
Exception:
The HTTP request is unauthorized with client authentication scheme 'Digest'. The authentication header received from the server was 'Digest qop="auth",algorithm=MD5-sess,nonce="+Upgraded+v1c1d404aaeb7edbba8daf132fea97aa12243033a0f40acf01376892331a408411c85513f482eab750b18498cb2d420b2fb99998b5b8b071a2",charset=utf-8,realm="Digest"'.
Inner Exception:
The remote server returned an error: (401) Unauthorized.
Base Exception:
No credentials are available in the security package
From what i can tell, it looks like server side is requesting digest (correctly) and the client is authenticating in digest, but it won't accept it.....
Any and all help would be greatly appreciated.
Thanks
The problem is that Microsoft have enhanced the security in the LSAS in 8.1 / 2012 R2. BasicHttpBinding is no longer supported for sending the users identity information over the network. You must use WSHttpBinding instead.
This solved my problem
I've got a problem getting my software to communicate through a proxy server at a client's site. It just gets (407) Proxy Authentication Required errors. It's a .NET Framework 3.5 C# WinForms application which uses old-style asmx web references to communicate (not WCF).
To diagnose the problem, I created a simple C# console app:
static void Main(string[] args)
{
try
{
System.Net.WebClient client = new System.Net.WebClient();
client.DownloadFile(#"https://www.myserver.co.uk/test.xml", #"C:\temp\test.xml");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
This gives the error (407) Proxy Authentication Required. So I added this to the app config:
<system.net>
<defaultProxy useDefaultCredentials="true" />
</system.net>
And it works. Great! However, in a similarly simple test WinForms application where I've put the same code behind a button click, I still get the 407 error with or without the extra config.
What's the difference between a Console application and a WinForms application in which the latter doesn't seem to send the default credentials? What else can I do to diagnose this?
Other things I've tried:
Setting the credentials in code using CredentialCache.DefaultCredentials and CredentialCache.DefaultNetworkCredentials.
Creating a new WebProxy and setting the default credentials in code.
Changing the config to point to a non-existent web proxy. This gives a different error, which shows that the WinForms app is at least reading the config.
I haven't tried creating a new NetworkCredential with username and password in code, partly because this wouldn't really be a viable solution for the production app, but mainly because I don't know the password! I'm having to do all my diagnosis over LogMeIn because the client site is in a different country and I'm dealing with a less-than-helpful IT department.
Thanks for any help.
I have a WCF service set up as a WSDuallHTTP and everything works ok using this. The problem I have is that I need to be able to get the service to run as a non admin program. I know I can setup the WCF service so that an admin just has to grant right for the service to be able to run on a certain port range but If I can get rid of the need for admins altogether it would be much better.
Due to this I have read that the NETTCP binding both supports duplex and doesnt require admin rights to host the service. My first question is is this correct?
Also when I change the WSDualHTTP binding to a NETTCP binding I get the following error.
Could not find a base address that matches scheme net.tcp for the endpoint with binding NetTcpBinding. Registered base address schemes are [http].
Here is the code thats failing:
string WCFHost = string.Format(WCF_URL, MainConfiguration.WCFCommunicationsURL,
MainConfiguration.WCFCommunicationsPort);
this.serviceHost = new ServiceHost(typeof(GX3WCFServerService), new Uri(WCFHost));
NetTcpBinding binding = new NetTcpBinding();
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
this.serviceHost.AddServiceEndpoint(typeof(IGX3WCFServerService), binding, "");
//the line above it the one throwing the exception
Please let me know if you need anymore information.
Worked out what the problem was. my WCFHost string began with HTTP:\ instead of NET.TCP:\
I am using a WCF service client generated by slsvcutil form Silverlight toolkit version 4. I've also tried version 3 with the same problems. When I use a client instance running on http with no user credentials it runs without problems. But I need to switch to https for productive servers and send user credentials that are hardcoded for my application. I use the following code for that:
var binding = new BasicHttpBinding (BasicHttpSecurityMode.TransportCredentialOnly);
var endpoint = new EndpointAddress (AppSettings.FlareEndPoint);
_service = new TopicAnalystAPIClient(binding, endpoint);
_service.ClientCredentials.UserName.UserName = "xxx";
_service.ClientCredentials.UserName.Password = "xxx";
When I call a method on that service pointing to http with no authentication it works. When I use the this code against http/https with the credential I get "There was an error on processing web request: Status code 401(Unauthorized): Unauthorized" exception. I've checked that the credentials are correct, I am able to open the service reference in my browser. I've also tried several combinations of http/https and SecurityMode value. I've also tried it on four different servers always with the same result.
What can be the problem?
A lot of permutations are possible. BasicHttpSecurityMode.TransportCredentialOnly should be usable without SSL [1] using HTTP itself. This means the server will send one (or more) authentication method(s) to the client (e.g. basic, digest, ntlm) and Mono (including MonoTouch) should be providing support for the most of them.
It is possible that the linker (if used) removes one of them. In that case you could try building and testing without linking (or skip linking of System.Net.dll).
It's also possible that the authentication method that the serve insist on is not supported. You could find which one is used by running a network trace (e.g. wireshark) or, maybe, it will show up in more details in the server log (along with the 401 error).
[1] http://msdn.microsoft.com/en-us/library/system.servicemodel.basichttpsecuritymode%28v=vs.95%29.aspx