本番環境でhttpsで機能するようにWCFサービスを構成する方法を理解するのに長い時間を費やしました。
基本的に、私はこれを行う必要がありました:
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
<service name="MyNamespace.MyService" behaviorConfiguration="MyServiceBehavior">
<endpoint address="" bindingNamespace="https://secure.mydomain.com" binding="basicHttpBinding" bindingConfiguration="HttpsBinding" contract="MyNamespace.IMyService"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="HttpsBinding">
<security mode="Transport">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
エンドポイントにbindingNamespace
属性を追加することで、エンドポイントが機能しました。
しかし、この構成は、通常のhttpで作業しているローカル開発環境では機能しません。だから私の設定があります:
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
<service name="MyNamespace.MyService" behaviorConfiguration="MyServiceBehavior">
<endpoint address="" binding="basicHttpBinding" contract="MyNamespace.IMyService"/>
</service>
</services>
ここでの違いは、httpsGetEnabled
属性をfalseに設定したことと、bindingConfigurationとbindingNamespaceを削除したことです。
問題は:両方を処理する1つの構成ブロックを作成するにはどうすればよいですか?
私はリリースを行うたびに設定に特別な変更をたくさん加える必要が本当に嫌いです。はい、値を自動的に変更するビルド後のタスクを作成できることはわかっていますが、可能であれば構成をマージしたいと思います。
私はこのようなものを試しました:
<behaviors>
<serviceBehaviors>
<behavior name="MyServiceBehavior">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
<services>
<service name="MyNamespace.MyService" behaviorConfiguration="MyServiceBehavior">
<endpoint address="" binding="basicHttpBinding" contract="MyNamespace.IMyService"/>
<endpoint address="" bindingNamespace="https://secure.mydomain.com" binding="basicHttpBinding" bindingConfiguration="HttpsBinding" contract="MyNamespace.IMyService"/>
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="HttpsBinding">
<security mode="Transport">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
両方のエンドポイントを配置すると、サービスをアクティブ化するときに探す2つのオプションが得られると考えました。ただし、これは機能しません。私はこのエラーを受け取ります:
BasicHttpBindingをバインドしているエンドポイントのスキームhttpsに一致するベースアドレスが見つかりませんでした。登録されているベースアドレススキームは[http]です。
SOとインターネットの残りの部分を見ると、他の人がこのドラゴンを倒すことに問題を抱えているようです。
さて、あなたの組み合わせた設定の1つの問題は、2つのエンドポイントが同じアドレス上にあることです-これは機能しません。
IISでホストしている場合は、サーバー、仮想ディレクトリ、および必要な* .svcファイルによって基本アドレスが決まります。次のようになります。
http://yourservername/VirtualDirectory/YourService.svc
2つのエンドポイントが必要な場合は、少なくとも1つで相対アドレスを定義する必要があります。
<services>
<service name="MyNamespace.MyService"
behaviorConfiguration="MyServiceBehavior">
<endpoint
address="basic"
binding="basicHttpBinding"
contract="MyNamespace.IMyService"/>
<endpoint
address="secure"
binding="basicHttpBinding" bindingConfiguration="HttpsBinding"
contract="MyNamespace.IMyService"/>
</service>
</services>
この場合、HTTPエンドポイントは次の場所にあります。
http://yourservername/VirtualDirectory/YourService.svc/basic
および安全なHTTPSエンドポイント:
https://yourservername/VirtualDirectory/YourService.svc/secure
さらに、安全なエンドポイントはHttpsBinding
構成を使用しますが、そのようなバインディング構成が不足しています-必要なのは次のとおりです。
<bindings>
<basicHttpBinding>
<binding name="HttpBinding">
<security mode="None">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</basicHttpBinding>
</bindings>
HttpsBinding
設定を追加する必要があります!!
<bindings>
<basicHttpBinding>
<binding name="HttpBinding">
<security mode="None">
<transport clientCredentialType="None"></transport>
</security>
</binding>
<binding name="HttpsBinding">
<security mode="Transport">
<transport clientCredentialType="Windows" />
</security>
</binding>
</basicHttpBinding>
</bindings>
問題は設定ファイルではなく、IIS設定です。IISでHTTPとHTTPSの両方を有効にする必要があります。IIS 7.5では、サイトをクリックし、[サイトアクションの編集]の下の[バインディング]をクリックします。httpとhttpsの両方が追加されていることを確認します。次に、セキュリティモードを[なし]に設定して、<basicHttpBinding>
の下にHTTPのバインディングを作成する必要があります。新しく作成したバインディング構成をhttpエンドポイント。準備完了です。さらに問題が必要な場合はお知らせください。
最近、WCF 3.5 REST(webHttpBinding
)サービスをMicrosoft Azure App Service(IIS)のHTTPとHTTPSの両方で利用できるようにする必要がありました。苦しむ冒険。これが私の発見と私のweb.config
の<system.serviceModel>
です。
注:これらの注意事項は、WCFの場合ですREST *.svc
(@ServiceHost
)内で実行されているWebサービス最小のASP.NET 4.7アプリケーション(Global.asax
付き)IIS 10 in Windows Server 2016)。これらの注記は自己に適用されません -ホストされたWCFサービス、非REST WCFサービス(SOAPなど)、または.NET Framework 4.7より古いプラットフォーム。これは.NET Coreにも適用されません。
<serviceHostingEnvironment>
要素の使用が不可欠です。multipleSiteBindingsEnabled="true"
が設定されていることを確認してください。<baseAddressPrefixFilters>
を使用する必要がありましたが、これはもう必要ありません。<serviceMetadata>
ファイルにweb.config
要素は必要ありません必要はありません。<endpoint address=""
属性で絶対URIを使用しないでください-属性を空のままにしてください。PATH_INFO
スタイルのエンドポイントに相対URIを使用する)と言っています:IISがホストするサービスエンドポイントには、常に相対エンドポイントアドレスを使用する必要があります。完全修飾エンドポイントアドレス(例: http://localhost/MyService.svc )を指定すると、エンドポイントアドレスがIISアプリケーションを指していない場合、サービスのデプロイメントでエラーが発生する可能性がありますエンドポイントを公開するサービスをホストします。ホステッドサービスに相対エンドポイントアドレスを使用すると、これらの潜在的な競合を回避できます。
web.config
ファイルが、WCFに親WebサイトでHTTPSが有効になっていないときに、HTTPS接続を受け入れるようにWCFに指示するとエラーを発生させます<services>
要素を省略して自動的に舞台裏で生成できるようにすることでWCFの構成を簡素化しましたが、デュアルHTTP + HTTPSのRESTfulサービスで一貫した結果が得られませんでしたバインディングなので、引き続き<services>
を手動で指定します。これが私の<system.serviceModel>
ファイルのweb.config
要素です。
<system.serviceModel>
<services>
<service name="WcfService1.MainService">
<endpoint address="" binding="webHttpBinding" contract="WcfService1.IMainService" behaviorConfiguration="myWebBehavior" bindingConfiguration="myWebHttpBindingInsecure" />
<endpoint address="" binding="webHttpBinding" contract="WcfService1.IMainService" behaviorConfiguration="myWebBehavior" bindingConfiguration="myWebHttpBindingSecure" />
</service>
<service name="WcfService1.AnotherService">
<endpoint address="" binding="webHttpBinding" contract="WcfService1.IAnotherService" behaviorConfiguration="myWebBehavior" bindingConfiguration="myWebHttpBindingInsecure" />
<endpoint address="" binding="webHttpBinding" contract="WcfService1.IAnotherService" behaviorConfiguration="myWebBehavior" bindingConfiguration="myWebHttpBindingSecure" />
</service>
<!-- etc... -->
</services>
<behaviors>
<endpointBehaviors>
<behavior name="myWebBehavior">
<webHttp />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior>
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<!-- By default (in machine.config), the 'http' scheme is mapped to 'basicHttpBinding' (SOAP), not 'webHttpBinding' (REST) and the 'https' scheme is not mapped. -->
<add binding="webHttpBinding" scheme="https" bindingConfiguration="myWebHttpBindingSecure" />
<add binding="webHttpBinding" scheme="http" bindingConfiguration="myWebHttpBindingInsecure" />
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<bindings>
<webHttpBinding>
<!-- maxReceivedMessageSize="104857600" is 100MiB -->
<binding name="myWebHttpBindingInsecure" maxReceivedMessageSize="104857600" transferMode="Streamed">
<security mode="None" />
</binding>
<binding name="myWebHttpBindingSecure" maxReceivedMessageSize="104857600" transferMode="Streamed">
<security mode="Transport" />
</binding>
</webHttpBinding>
</bindings>
</system.serviceModel>
ローカルドメインで実行し、本番環境やその他の環境でも実行するためのソリューションは、メモリを変更することなく変更を行う構成変換です。選択した構成プロファイルに基づいて、コンパイル済みのweb.configを変換します。ローカルでDebug
モードで実行し、テスト環境で publish をTestRelease
プロファイルに、本番環境に別のプロファイルを持っています。
Web.configを展開できない場合は、右クリックして構成変換を追加できます。デバッグとリリース以上のものを取得するには、マネージャーを介して構成を追加します。
次に変換の例を示します。
<configuration xmlns:xdt="http://schemas.Microsoft.com/XML-Document-Transform">
<!--...-->
<system.serviceModel>
<protocolMapping>
<add binding="basicHttpBinding" scheme="http" xdt:Transform="SetAttributes" />
</protocolMapping>
<bindings>
<basicHttpBinding>
<binding xdt:Locator="Match(name)" name="basicHttpBindingConfiguration">
<security xdt:Transform="Remove">
<transport xdt:Transform="Remove"/>
</security>
</binding>
<binding xdt:Locator="Match(name)" name="fileTransferBinding">
<security xdt:Transform="Remove">
<transport xdt:Transform="Remove"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
<configuration xmlns:xdt="http://schemas.Microsoft.com/XML-Document-Transform">
<!--...-->
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="false" httpsGetEnabled="false" xdt:Transform="Replace"/>
<serviceDebug includeExceptionDetailInFaults="false" xdt:Transform="Replace"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpsBinding" scheme="https" xdt:Transform="Replace"/>
</protocolMapping>
<bindings>
<basicHttpBinding>
<binding xdt:Locator="Match(name)" name="basicHttpBindingConfiguration">
<security mode="Transport" xdt:Transform="Insert">
<transport clientCredentialType="None" proxyCredentialType="None" />
</security>
</binding>
<binding xdt:Locator="Match(name)" name="fileTransferBinding">
<security mode="Transport" xdt:Transform="Insert">
<transport clientCredentialType="None" proxyCredentialType="None" />
</security>
</binding>
</basicHttpBinding>
</bindings>
</system.serviceModel>
<system.webServer>
<directoryBrowse enabled="false" xdt:Transform="Replace"/>
</system.webServer>
</configuration>