Using WCF's net.pipe in a website with impersonate=true - wcf

I'm trying to use WCF named pipes in a web site, and it's failing with errors:
There was no endpoint listening at net.pipe://localhost/mypipename
that could accept the message. This is often caused by an incorrect
address or SOAP action. See InnerException, if present, for more
details.
and the InnerException:
The pipe name could not be obtained for net.pipe://localhost/mypipename.
and there is another inner exception giving an access denied message.
My web site is using impersonation, and looking around the internet, this seems to be relevant, but I don't know how to fix it.
Does anyone have any ideas?
Thanks
Matt

The standard WCF NetNamedPipesBinding creates a randomly-generated pipe name when the service starts up, and also a kernel shared memory object which the WCF client-side channel stack has to consult to find out the name of the pipe.
Using impersonation on your web site means that the security context from which your WCF service is being invoked has a logon token (the impersonation token) which includes membership of the NETWORK USERS group.
When the service listener starts up, the WCF binding creates an Access Control List (ACL) on both the named pipe itself, and on the shared memory object where the pipe name is published. Both of these ACLs deny access to the NETWORK USERS group. Thus your web site, impersonating the remote user, is denied access to the shared memory object before it can even discover the pipe name. Even if it found out the pipe name some other way, it would still be denied access to the pipe.
Everything works when you remove impersonation, because now the service is being invoked in the security context of the web application worker process, whose logon token does not have membership of the NETWORK USERS group - it is a local logon.
More details at http://blogs.charteris.com/blogs/chrisdi if you're interested. I show how the ACLs can be adjusted, and in principle this approach could be used to grant access to remote users, but I don't recommend this.

If you're getting this particular exception, it typically means that your service is not running. I see that you use localhost in the URL. I just want to make sure that the host and the service are running on the same machine. WCF does not allow communication across machines with this binding.
When I get this message, usually I check and see that I forgot to start the service, thus, there is no endpoint listening. Please check that your service is actually still running and hasn't crashed at the time that the exception is thrown. If that doesn't fix the problem, please post your progress and I can make more suggestions.

I worked around the problem by making the IIS endpoint where I ended up calling the net pipe from available to anonymous users, which meant no impersonation.

Related

WCF Service Accounts

I have a WCF self-hosted as a Windows Service.
When I start the service (under the NETWORK_SERVICE account), I can consume the service from my ASP.NET application on a different server.
However, the business rules have changed. Now I need to run the service under my own account. I am able to stop the service, and start it again under my account. No problem there.
Until I try to consume the service from my ASP.NET application on the other service. I get:
A call to SSPI failed, see inner exception
I'm relatively certain there's something I need to do security wise to eliminate this error, being new to all this I just don't know what.
Any help is greatly appreciated.
Thanks,
Jason
Usually this is a sign of a missing or misconfigured SPN, which gets in the way when you're using windows authentication (at the transport or message level) and Kerberos is being negotiated.
Notice that how/when the error manifests itself might depend on the way the hostname (or IP address) of the service host is used in the URL used by the client, since WCF will try, by default, to deduce the right SPN to use based on the URL information, unless you explicitly override it by setting the endpoint identity.
So likely all you need to do is register an SPN (using setspn.exe) for your new service and make sure your client uses an appropriate identity.
There's some more extra information on how WCF uses service identities here, here and here.

Getting a MethodAccessException(in event log of server) and HTTP Error 401 Unauthorized(at client side) in WCF Rest Service in IIS6.0 Win2K3 enviorn

I wrote a WCF REST based service that uses webHttpBinding and uses JSON to post data.This service works fine in all of our internal environments. But in one of our environment which is exact replica of Production. It is not working. If I inspect in Firebug, I see "HTTP Error 401 Unauthorized" and in server I See following in the event log.
System.MethodAccessException
System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous
MethodAccessException: System.ServiceModel.Activation.HostedHttpRequestAsyncResult.ExecuteSynchronous(System.Web.HttpApplication, Boolean) at System.ServiceModel.Activation.HttpHandler.ProcessRequest(HttpContext context)
I haven't pasted the whole event log. But,afore are the key parts of it.
I am not able to figure out what is happening, we are using custom httpmodule for authentication.
Need urgent help on this
Thanks in advance
From MSDN, a MethodAccessException occurs when you try to call a private/protected method from somewhere that you aren't allowed. This is thrown during reflection, which is more than likely what WCF is doing under the covers.
My bet is that one of your service methods is marked as private or protected.
This would work in your local environment because it's under Full Trust. Your production environment is most likely running in Medium Trust. (Under Medium Trust, you aren't allowed to bypass the accessibility modifiers.)
-- Tatham

wcf service stops after few requests

I am working on an application where i am using a wcf service. I am currently hosting my service on localhost and accessing it from there only by adding the service reference in my project. On one of my page i am sending request on change of selected index on dropdown list. It works fine for first few requests but suddenly stops after that giving following excsption
"Failed to invoke the service. Possible causes: The service is offline or inaccessible; the client-side configuration does not match the proxy; the existing proxy is invalid. Refer to the stack trace for more detail. You can try to recover by starting a new proxy, restoring to default configuration, or refreshing the service."
How can service stop without any reason and that too from my localhost. It only works for first 3-4 requests. In service i am just sending a integer and getting back the records on its basis using a class in a generic list.
Thanks in advance
What protocol / bindings are you using? Can you show us the config? Anything inside the <system.serviceModel> on both the server and the client side.
Do you maybe create a client proxy and call the service method and not properly close and dispose of the client proxy? In that case, you might run out of connections at some point - but that's next to impossible to tell without some code to see what you're doing. Can you show us the service contract in question, and the code how you call it from the client side?

Multiple DataContract Callbackcontract

Greetings,
in our company we are developing wcf service. This is used as a server and it works quite well. Hover there is a wish from customer that after they login to application they would like to see which users are logged in too.
I read about CallbackContract (based on some wcf chat application). How can we achive this goal?
Similar question asked here
You can deffinetly manage the logged users inside the server. I have created a personal pattern for dealing with such situations, and it ussually goes like this:
create a client class inside the WCF server that will hold all the needed information about the client.
create 2 methods in the service: logIn, logOut. the login method should be able to gather all the informations about the client that you want to store. Make sure to define properties that can uniquely identify a client instance. When the client conencts to the server it calls the login method, allowing the server to gather and save the information from the client. If using callbacks, this is the place to save the CallBack context object, in the client obejt. You can now save the Client object in the WCF server instance (I use a dictioary). When the client logs out, it calls the log out method and the server removes the entry.
create a KeepAlive method in the server that regularry checks the connected clients to see if they are still connected (in case of network failure or app crash a client may not call the logout method).
I think this is the simplest way (not
saying it's the best) to manage
clients in the server. There is no
problem with having multiple clients
from the same computer (you save the
Context when a client logges in) as
long as you have a way of uniquely
identify clients.
As for your last question, having
multiple services should not be a
problem. In fact you have the same WCF
server with different contracts (and
endpoints) for the different services
you offer. ALl the contracts reside in
the same WCF server instance so they
all can access the connected client
list.
If you have further questions, I would
be happy to answer them.
You can find the code you need to actually build the WCF service you require here

Reading a caller's IP address in WCF (OperationContext is null)?

I am validating users using the UserNamePasswordValidator.Validate(string username, string password) and the service is hosting itself (e.g. no IIS).
The problem I have is that if the user fails the validation I want to track the users IP address. This works fine of the user gets validated, because then the OperationContext has been initialized (it is null inside the validate method and not created until later).
Does anyone know how to get the clients IP address either in the validate method or before the validate method has been executed?
Yes, I know about how to get the IP address using RemoteEndpointMessageProperty but like I said, it never get that far if validation fails :-)
I've researched this to death all week, and I can't come up with a single blog entry or MSDN article that deals with the issue.
As far as I can tell, you cannot log IP address during the Validate stage.
The only workaround I can suggest is to host in IIS and use the weblogs there, which do log IP address. It's painful, unfortunately, but it may be the only way.
If you're hosting in IIS then this becomes much more simple. This chunk of config comes straight from my hosting web project and forces ASP.NET requests to come down the IIS pipeline rather than being dispatched straight to the ASP err bits of IIS.
aspNetCompatibilityEnabled: When this attribute is set to
true, requests to Windows Communication Foundation (WCF) services
flow through the ASP.NET HTTP pipeline, and communication over
non-HTTP protocols is prohibited.
See: http://msdn.microsoft.com/en-us/library/ms731336.aspx
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
I use the AuthenticationService and make use of the HttpContext to get at all the interesting stuff about the client, much of it is useful for things like ensuring a user isn't logging in from six different subnets as well as playing around with cookies.
Although I think this is applied to the MS AuthenticationService, any other services you have will need this attrib:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
If you want to pursue your non-IIS hosted service route, then I'd see what stuff is available inside the MS API using reflection, poking around on a WCF with the debugger while stopped, unfolding all those Non-public members.
I suppose the problem will be getting a reference to a bit of WCF which is initialized from which to start poking. You might have to register some kind of listener to one of the dispatchers when you setup the service host.
http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.channeldispatcher.aspx
Edit:
Adding this link as my thoughts are that you'd need to get at stuff in WCF that's right down the stack before it gets to your code:
http://blogs.msdn.com/sonuarora/archive/2007/06/11/passing-soap-actions-to-adapter-inbound-handler-for-filtering-type-of-listeners.aspx