使用 SSL 加密在 IIS 10 上托管 WCFService 库

Hosting WCFService Library on IIS 10 with SSL encryption

我正在尝试使用自签名 SSL 在 IIS 10 上托管 WCF 服务库。

获取最小完整可验证示例,打开Visual studio 2017

New>Project>C#>Web>WCFLibrary 有了这个你会得到一个简单的代码,它有一个操作契约,它接受一个整数和 returns 一个字符串。

现在我正在尝试使用自签名 SSL 在 IIS 上托管它(我的有更多的操作合同,但这可以)。

到目前为止我已经尝试了什么。

现在下一部分是在 IIS 上托管它,所以我创建了 SVC 文件

我的 SVC 文件包含 ->

<%@ ServiceHost Language = "C#" Debug = "true" Service = "WcfServiceLibrary2.Service1" %>

然后我能找到的所有教程编辑 Web.Config,在 Visual Studio 2017 中不可用,所以我尝试了两件事 1.创建一个Web.Config文件并添加配置 2. 发布网站然后获得Web.Config不需要任何修改

然后我进入 IIS(以管理员身份)并添加了一个新网站

然后在尝试浏览时,为了查看托管 IIS 服务的消息,我收到了此错误 "Cannot read configuration file" 为了解决这个问题,我遵循了 success.trendmicro.com/...

现在错误消失了,但现在我得到了

为了解决这个问题,我关注了 IIS - 401.3 - Unauthorized 但这导致浏览器让我浏览目录而不是给出服务已创建的消息。

知道我在这里遗漏了什么吗?

显然我在这里遗漏了一些重要的东西,因为我未能在 HTTP 本身上托管它,我在网上找到的所有教程都有一个文件 Web.Config 而不是 App.config,我正在寻找一个示例(最好使用图像)仅通过这个小示例进行演示。

我知道这并没有遵循所有关于提问的 SO 指南,但我未能将其明确表达为符合要求的问题。

编辑

根据 LexLi 的建议,它可能已经托管,我尝试使用 svcutil 使用它,但出现错误

WS-Metadata Exchange Error
    URI: http://localhost/Service1.svc

    Metadata contains a reference that cannot be resolved: 'http://localhost/Service1.svc'.

    The remote server returned an unexpected response: (405) Method Not Allowed.

    The remote server returned an error: (405) Method Not Allowed.


HTTP GET Error
    URI: http://localhost/Service1.svc

    There was an error downloading 'http://localhost/Service1.svc'.

    The request failed with HTTP status 404: Not Found.

Url 是正确的,因为我是使用 IIS 的浏览功能获得的。

简而言之,步骤如下:

  1. 创建自签名证书
    1. 添加 SSL 绑定
    2. 为 SSL 配置虚拟目录
    3. 为 HTTP 传输安全配置 WCF 服务

这个 link 更深入:https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-an-iis-hosted-wcf-service-with-ssl

首先请不要将IIS物理路径设置为桌面,这样会造成权限问题。我们可以将IIS站点物理路径设置为C分区下的文件夹。
其次,请阅读下面的link,主要说明WCF服务库项目无法直接发布到IIS,因为其Appconfig无法被IIS识别,除非在网站根目录手动添加额外的Webconfig。
https://docs.microsoft.com/en-us/dotnet/framework/wcf/deploying-a-wcf-library-project
一般来说,我们使用包含自动生成的 Webconfig 文件的 WCF 服务项目模板而不是 WCF 服务库项目模板,因为它通常用作 class 库。

默认情况下,该服务使用 BasicHttpBinding 托管,它取决于以下标记。

<protocolMapping>
        <add binding="basicHttpBinding" scheme="http" />
</protocolMapping>

服务也可以通过以下方式手动配置。这两种方式配置文件是等价的。

<system.serviceModel>
    <services>
      <service name="WcfService1.Service1" behaviorConfiguration="mybehavior">
        <endpoint address="" binding="basicHttpBinding" contract="WcfService1.IService1" bindingConfiguration="mybinding"></endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
      </service>
    </services>
    <bindings>
      <basicHttpBinding>
        <binding name="mybinding">
          <security mode="None">
          </security>
        </binding>
      </basicHttpBinding>
</bindings>

不需要在webconfig中分配服务endpoing地址。应该在IIS站点绑定模块中完成。
WCF System.ServiceModel.EndpointNotFoundException
最后,我们可以通过添加额外的服务端点来通过 https 托管服务,请参考以下配置(简化配置)。

<protocolMapping>
  <add binding="basicHttpBinding" scheme="http"/>
    <add binding="basicHttpsBinding" scheme="https" />
</protocolMapping>

然后在IIS站点绑定模块中添加https协议。

https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-an-iis-hosted-wcf-service-with-ssl
如果有什么我可以帮忙的,请随时告诉我。

首先归功于应得的功劳,我被多个 SO 用户指出正确方向的许多问题将是:Mikael bolinder, Abraham Qian, Lex Li, the wonderful people in the C# chat room 和我的一个同事(不是在撰写此答案时在 SO 上有一个帐户),在这个答案中,我计划涵盖使用 HTTPS 安全性在 IIS 服务器中托管 WCF 库可能需要的所有内容。

我使用的工具:

  • Visual Studio 2017专业
  • IIS 10(附带 windows 10,但必须在 windows 功能中激活)(见下文)

首先: 确保您已安装 visual studio 中需要的所有组件。

  1. Windows -> .Net 桌面开发
  2. Windows -> 通用 Windows 开发平台
  3. 网络与云 -> ASP.NET 和网络开发

在此列表和其他列表中,可能会包含一些额外的组件,原因是我安装了它们,但无法验证它们是否绝对必要。

现在,让我们添加必要的 windows 功能。 控制面板 -> 程序 -> 打开或关闭 Windows 功能

确保进入 WCF 服务并检查 HTTP 激活,不要被方块所迷惑(我的错误之一)

现在让我们开始创建服务。打开 Visual Studio 文件 -> 新建 -> 项目 -> Visual C# -> Web -> WCF -> WCF 服务库 这会生成您尝试托管的 MCVE

现在您必须 link 它与网站一起生成 Web.Config 文件和 SVC 文件,为此,在解决方案资源管理器上,右键单击您的解决方案,添加->新建网站.

现在在 web.config 文件中添加

<system.serviceModel>
    <services>
      <service name="WcfServiceLibrary4.Service1"> <!-- Change the library name as per your need -->
        <endpoint address=""
                  binding="wsHttpBinding"
                  bindingConfiguration="secureHttpBinding"
                  contract="WcfServiceLibrary4.IService1"/> <!-- Change the library name as per your need -->

        <endpoint address="mex"
                  binding="mexHttpsBinding"
                  contract="IMetadataExchange" />
      </service>
    </services>
    <bindings>
      <basicHttpBinding>
        <binding name="secureHttpBinding">
          <security mode="Transport">
            <transport clientCredentialType="None"/>
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpsGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

接下来在网站上添加对服务的引用

发现服务并添加您创建的服务。现在构建您的解决方案并发布它。 **注意不要将解决方案发布在桌面或文档等用户目录中,否则 ACL 权限会让您头疼,而是直接将其发布在 Drive 中的目录中。

现在托管时间 首先让我们打开 IIS(始终以管理员身份)并创建一个新证书。

在服务器上转到 IIS 部分和 Select 服务器证书,然后单击右端的创建新证书。

现在从左侧菜单创建一个新网站

确保在此处切换到 https 和 select 您的证书,现在要验证您的服务是否已创建,您需要浏览已创建的网站 svc 文件,遗憾的是此时您会收到一条错误消息Server Error in '/' Application. Could not find a base address that matches scheme http for the endpoint with binding BasicHttpBinding. Registered base address schemes are [https].我找不到错误的原因,但我找到了绕过它的方法,

绕过此错误的步骤 -> Select 您从左侧菜单中的网站,在右键菜单中单击绑定并添加一个 HTTP 绑定,使用不同的端口。 在此之后,您将能够浏览您的 svc 文件的 HTTPS 版本。

现在,如果您浏览 HTTPS link,您会收到服务已创建的消息

现在您可以继续创建使用此服务的应用程序。

前方有什么

  1. 我将尝试找到一种无需添加额外绑定的方法
  2. 第二个目标是在不添加额外网站的情况下实现这一目标。

如果我实现了这些,我会更新,但是这些不是我现在的优先事项,可能会在很长一段时间内不会添加,如果有任何不合理的地方,或者您有任何改进的想法,请在下方评论.