7

新しい Microsoft.AspNet.WebApi.SelfHost NuGet パッケージを使用して、Azure ワーカー ロールで ASP.NET WebApi エンドポイントをホストしようとしています。私のワーカーの Run() コードは、おおよそ次のようになります。

// 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);

これは開発ファブリックでは正常に機能しますが、Azure にデプロイするときに、次の例外スタックを含む server.OpenAsync() 呼び出しから AggregateException を取得します。

[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

私はバニラワーカーの役割を実行しているだけで、これはセルフホストの「ハローワールド」のようです...

ServiceDefinition.csdef のエンドポイント部分は次のようになります。

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

RoleEnvironment InstanceEndpoint から取得した baseAddress は正当に見えます - http://10.115.[X].[Y]:8081

同じポート/localPort (8080) を使用しているか、上記のようにマッピングを行っているかにかかわらず、エラーが発生します。

このように従来の WCF サービスをワーカー ロールでホストできることは明らかです。ASP.NET WebApi SelfHost がこの構成で機能しない理由はありますか?

4

3 に答える 3

4

デフォルトでは、RoleEntryPointは、セキュリティのために最小限の権限のユーザーアカウントで実行されます。エラーが示すように、これらの権限のためにそのポートを予約できません。ここには2つのオプションがあります。

  1. ランタイム要素をロール定義に追加して、ワーカープロセスをSYSTEMとして実行します(つまり<Runtime executionContext="elevated"/>)。
  2. 昇格して実行され、そのポートを予約する起動スクリプトを作成します。

遊んでみる(そしてそれが許可の問題である場合はトラブルシューティングする)ために、#1を実行することはそれをテストする簡単な方法です。

編集:ワイルドカードの予約を行う際のWCFとWindowsAzureのアクセス許可の問題を思い出しているようです。完全なホスト名を使用すると、以前は正常に機能していました。

host.AddServiceEndpoint(
 typeof(IEchoService), new BasicHttpBinding(BasicHttpSecurityMode.None) { HostNameComparisonMode = HostNameComparisonMode.Exact }, "echo");
于 2012-06-28T16:54:39.993 に答える
2

昇格したスタートアップ スクリプトから netsh.exe を呼び出して無駄に半日実験した後、私はあきらめて大きなハンマーを使用し、ワーカー ロール全体を昇格して実行するという Ryan の最初の提案を受け入れました。

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

それはすべての問題を解決しました。

参考までに、昇格されていないユーザー アカウントの HTTP 登録を許可しようとした方法を次に示します (実際には機能しませんでした)。

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>

そして、起動スクリプト(私の場合はstartup\Install.cmd)で:

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

これは基本的に、AspNetWebApi に取り組んでいる善良な人々によって推奨されたソリューションです (彼らがここで推奨することを実行するためのより短い方法です) が、残念ながらそれは私にとってはうまくいきませんでした - netsh コマンドは正常に実行され、私は確認できました私が自己ホストしている URL (http://+:8080/api/) の urlacl が \Everyone によって許可されていることを確認しましたが、それでも同じ許可エラーが発生していました。昇格されていないワーカーロールを実行しているときにこれを機能させる方法を誰かが理解している場合は、投稿してください!

于 2012-06-28T21:41:46.163 に答える
-1

プロジェクトに参照「System.ServiceModel」を追加し、「config.HostNameComparisonMode = System.ServiceModel.HostNameComparisonMode.Exact;」を使用します。管理者特権の例外 (アクセスが拒否されました) は発生しません。

于 2014-09-16T09:20:24.223 に答える