ASP.NET WebApi SelfHost Service Fails When Registering HTTP URLs

I am trying to place an ASP.NET WebApi endpoint on a working Azure role using the new Microsoft.AspNet.WebApi.SelfHost NuGet package. My run () working code looks something like this:

// Endpoint is defined as in ServiceDefinition.csdef as // HTTP, external port 8080, internal port 8080 (or 8081 - error both ways) RoleInstanceEndpoint externalEndPoint = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["Endpoint"]; string baseAddress= String.Format("http://{0}", externalEndPoint.IPEndpoint); var maxsize = 1024 * 1024; var config = new HttpSelfHostConfiguration(baseAddress) { MaxBufferSize = maxsize, MaxReceivedMessageSize = maxsize }; config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); // Create and open the server var server = new HttpSelfHostServer(config); server.OpenAsync().Wait(); // keep the worker thread alive while (true) Thread.Sleep(Timeout); 

This works fine in a dev structure, but when deploying to Azure, I get an AggregateException message from a server.OpenAsync () call containing the following exception stack:

 [0] One or more errors occurred. [1] HTTP could not register URL http://+:8081/. Your process does not have access rights to this namespace (see http://go.microsoft.com/fwlink/?LinkId=70353 for details). [2] Access is denied 

I just fulfill the role of a vanilla worker, and this seems to be a "hello world" self-service ...

The final part of my ServiceDefinition.csdef looks like this:

 <Endpoints> <InputEndpoint name="Endpoint" protocol="http" port="8080" localPort="8081" /> </Endpoints> 

The base address that I get from the RoleEnvironment InstanceEndpoint instance looks legit - http: //10.115. [X]. [Y]: 8081

I see an error if I use the same port / localPort (8080) or when I perform the mapping as described above.

It is clear that you can put a regular WCF service in a working role this way - is there a reason why ASP.NET WebApi SelfHost will not work in this configuration?

+7
source share
3 answers

By default, RoleEntryPoint runs under a user account with a minimum resolution for security. As the error shows, it cannot reserve this port because of these permissions. You have two options:

  • Start the Worker process as SYSTEM by adding a Runtime element to the role definition (i <Runtime executionContext="elevated"/> ).
  • Create a launch script that runs at a higher level and reserves this port for you.

To play back (and troubleshoot if it's a permission issue), running # 1 is a quick way to test it.

Edit: It seems I remember the permission issue with WCF and Windows Azure when doing wildcard reservations. It worked great when using the fully qualified host name, for example.

 host.AddServiceEndpoint( typeof(IEchoService), new BasicHttpBinding(BasicHttpSecurityMode.None) { HostNameComparisonMode = HostNameComparisonMode.Exact }, "echo"); 
+4
source

In the afternoon, experimenting with calling netsh.exe with an elevated script run to no avail, I gave up and ended up using a big hammer, and first suggested Ryan play the whole working role:

 <WorkerRole name="WorkerRole" vmsize="ExtraSmall"> <Runtime executionContext="elevated"> </Runtime> </WorkerRole> 

This solved all the problems.

For reference, here is how I tried to allow HTTP registration for failed user accounts (which never worked):

In ServiceDefinition.csdef:

 <Startup> <Task executionContext="elevated" commandLine="startup\Install.cmd"> <Environment> <Variable name="ENDPOINTPORT "> <RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/Endpoints/Endpoint[@name='Endpoint']/@port" /> </Variable> </Environment> </Task> </Startup> <Endpoints> <InputEndpoint name="Endpoint" protocol="http" port="8080" localPort="8080" /> </Endpoints> 

And in the start script (startup \ Install.cmd in my case):

 netsh.exe http add urlacl url=http://+:%ENDPOINTPORT%/api user=everyone listen=yes delegate=yes 

This is basically the solution recommended by the good people working on AspNetWebApi (just a shorter way to do what they recommend here ) but unfortunately this did not work for me - as long as the netsh command was successful and I was able to verify that urlacl on The url that I host (http: // +: 8080 / api /) is resolved \ Everything, I still got the same permission error. If someone finds out how to make this work when starting a working role that is not elevated, send a message!

+2
source

Add the link "System.ServiceModel" to your project and with "config.HostNameComparisonMode = System.ServiceModel.HostNameComparisonMode.Exact;" you do not receive an administrator privilege exception (access is denied).

-one
source

All Articles