1

Disclaimer: Similar to this question, this one is specific to the most voted comment from the answer

I use a ServiceHost object to create a HTTP service: http://{IP}:80/myService

My application runs from a non-admin account (and this must be kept like this). From several sources I found that the solution was calling the following from an administrator cmd prompt:

netsh http add urlacl url=http://+:80/myService/ user=Everyone

This does not work, I still get an exception regarding access:

System.ServiceModel.AddressAccessDeniedException: HTTP could not register URL http://127.0.0.1:80/myService/. Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details). ---> System.Net.HttpListenerException: Access is denied
   at System.Net.HttpListener.AddAllPrefixes()
   at System.Net.HttpListener.Start()
   at System.ServiceModel.Channels.SharedHttpTransportManager.OnOpen()
   --- End of inner exception stack trace ---
   at System.ServiceModel.Channels.SharedHttpTransportManager.OnOpen()
   at System.ServiceModel.Channels.TransportManager.Open(TransportChannelListener channelListener)
   at System.ServiceModel.Channels.TransportManagerContainer.Open(SelectTransportManagersCallback selectTransportManagerCallback)
   at System.ServiceModel.Channels.TransportChannelListener.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.HttpChannelListener`1.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Dispatcher.ChannelDispatcher.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open()

However if I call this line, it works:

netsh http add urlacl url=http://127.0.0.1:80/myService/ user=Everyone

Note I explicitely specified the IP. I don't know the IP that the user will be using, so I need the + wildcard to work. I cannot figure out why it is not working and I cannot find a workaround to this.

  • Runnin as administrator is not a solution.
  • Found info on the UrlPrefix wildcards from Microsoft but still not clear
Community
  • 1
  • 1
Sergio Basurco
  • 3,488
  • 2
  • 22
  • 40

1 Answers1

1

I've encountered this exact scenario as well. So far, I suspect that the behaviour actually varies based on the version of Windows. Windows 10 seems to treat URL reservations on the loopback IP (127.0.0.1) a bit differently -- everything else seems to work as expected though.

On my Windows 10 machine, I'm seeing the same thing you are -- if I have a reservation with a strong wildcard (ie, http://+:80/), registering a URL prefix tied to the local loopback fails every time. This is not the case on Windows Server 2008 or 2012, however; it works fine there.

I'm sure this is related, but I have actually had success registering URLs on the local loopback on Windows 10 without any prior reservation on that port for that user (and without being admin), which is a bit strange given that I can't find any documentation pointing to this being possible. Below is the output of a call to netsh http show servicestate which one such reservation:

Server session ID: E700000120000035
Version: 2.0
State: Active
Properties:
    Max bandwidth: 4294967295
    Timeouts:
        Entity body timeout (secs): 120
        Drain entity body timeout (secs): 120
        Request queue timeout (secs): 120
        Idle connection timeout (secs): 120
        Header wait timeout (secs): 120
        Minimum send rate (bytes/sec): 150
URL groups:
URL group ID: DF00000140000004
    State: Active
    Request queue name: Request queue is unnamed.
    Properties:
        Max bandwidth: inherited
        Max connections: inherited
        Timeouts:
            Timeout values inherited
        Number of registered URLs: 1
        Registered URLs:
            HTTP://127.0.0.1:8081:127.0.0.1/

Note that strange prefix format (HTTP://127.0.0.1:8081:127.0.0.1/) -- that is not what I passed to the ServiceHost (I just specified http://127.0.0.1:8081). I suspect that Microsoft at some point introduced the ability to make 'special' URL registrations on the local loopback without prior reservation via netsh.

This is pure speculation on my part, but I suspect that these special reservations also come with the caveat that the underlying socket in http.sys only binds to local loopback for security purposes. This would obviously clash with any other process that would like to handle requests on that port which would fit under the http://+:80/ reservation, which could include remote requests coming in on a different interface.

Jon Gaudet
  • 11
  • 1