Reputation: 693
I want to implement a simple self-hosted REST API in my WPF application, that listens on a specific port on localhost. This API will be consumed by a website in order to communicate with the WPF application, if it's running.
It didn't take long before I encountered the System.ServiceModel.AddressAccessDeniedException error. The URL must be reserved and this can only be done if the process is running with elevated privileges. The problem is that this application is in use at thousands of companies with varying IT policies, which makes it virtually impossible for the application to require administrative privileges each time it's started.
This is my test code:
_task = Task.Factory.StartNew(() =>
{
var uri = new Uri("http://localhost:5000/test");
var type = typeof (TestService);
WebServiceHost host = new WebServiceHost(type, uri);
WebHttpBinding binding = new WebHttpBinding();
binding.CrossDomainScriptAccessEnabled = true;
host.AddServiceEndpoint(type, binding, uri);
host.Open();
});
Are there any ways around this? Any 3rd party packages that I can use? Or could I reserve the URL during installation of the application, since the installation requires elevated privileges? Or this is a dead end?
Upvotes: 3
Views: 3262
Reputation: 6986
Just run this during installation:
netsh http add urlacl url=http://+:5000/Test/ user=Everyone
Note you can restrict the user
from Everyone
to the logged in user e.g. user=MyDomain\John
Upvotes: 3
Reputation: 62093
Well, you do not need administrative privileges to start it. You only need them if you do not have the right to use the URL.
ACLURL (tool) can be used in the installer to grant the right to a user or program. Then there will be no administrative privileges required at runtime.
Upvotes: 0
Reputation: 91805
You're getting "access denied" because you're attempting to bind to http://+:12345
, where +
refers to all addresses on the machine. If you bind explicitly to localhost
then (as long as you use an unused port number) you shouldn't have any problems.
It's been a (long) while since I last used WCF, so I don't remember the relevant incantation to do that.
Personally, if I was doing this, I'd investigate something like NancyFX, which is much easier to use than WCF, but doesn't, strictly speaking, support REST natively, so you'd need to layer something on top. See http://engineering.laterooms.com/building-microservices-with-nancy-fx/, for example.
And, if you do decide to use Nancy, in terms of listening to a port on the local machine without needing administrator privileges, you need to specify HostConfiguration.RewriteLocalhost
in the configuration (or, at least, you did the last time I used NancyFX).
Upvotes: 1