【问题标题】:WCF Service over HTTPS only仅通过 HTTPS 的 WCF 服务
【发布时间】:2012-02-06 16:44:33
【问题描述】:

我想在 Windows Server 2008 R2 服务器上托管一个 RESTful WCF 服务。它目前作为现有网站中的应用程序托管。端口 443 正在使用自签名证书。

我希望仅通过 HTTPS 提供服务。在应用程序的 SSL 设置中,我将其设置为“需要 SSL”。端点配置如下:

  <system.serviceModel>
<behaviors>
  <endpointBehaviors>
    <behavior name="Rest">
      <webHttp />
    </behavior>
  </endpointBehaviors>
  <serviceBehaviors>

    <behavior>
      <serviceAuthorization serviceAuthorizationManagerType="ACME.MyAuthorizationManager, ACME.WS.Authorization" />
    </behavior>
  </serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
<standardEndpoints>

  <webHttpEndpoint>

    <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
  </webHttpEndpoint>
</standardEndpoints>

但是,当我尝试通过浏览器访问服务时收到 403 响应(例如 https://example.com/myservices/baz-service/yip-resource)。

我在配置过程中遗漏了什么吗?

【问题讨论】:

  • 您是如何尝试访问该服务的?从浏览器还是从 wcf 代理?
  • 您的 svc 的绑定/端点配置是什么样的?
  • 正在通过浏览器进行初始访问尝试。我已经添加了端点配置。

标签: wcf .net-4.0 https iis-7.5


【解决方案1】:

在 IIS 上设置“要求 SSL”选项意味着您正在使用客户端证书执行身份验证。如果您没有任何客户端证书身份验证,只需将该选项设置为忽略或禁用该选项。

为避免您的服务仅在 HTTPS 上提供服务,请从您网站的“绑定”选项中删除 HTTP 绑定。否则,只需公开您的绑定以使用传输作为安全机制,并且应该注意您的 WCF 服务仅在 HTTPS 上提供。

更新:

请了解我如何通过 Https 在 IIS 上托管 RESTful 服务:

[ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class RestService
    {
        // TODO: Implement the collection resource that will contain the SampleItem instances

        private static List<SampleItem> sampleCollection = new List<SampleItem>();

        [WebGet(UriTemplate = "/get-Collection")]
        public List<SampleItem> GetCollection()
        {
            // TODO: Replace the current implementation to return a collection of SampleItem instances
            if (sampleCollection.Count == 0)
            {
                sampleCollection = new List<SampleItem>();
                sampleCollection.Add(new SampleItem() { Id = 1, StringValue = "Hello 1" });
                sampleCollection.Add(new SampleItem() { Id = 2, StringValue = "Hello 2" });
                sampleCollection.Add(new SampleItem() { Id = 3, StringValue = "Hello 3" });
                sampleCollection.Add(new SampleItem() { Id = 4, StringValue = "Hello 4" });
                sampleCollection.Add(new SampleItem() { Id = 5, StringValue = "Hello 5" });
            }
            return sampleCollection;
        }
}

我的 Global.asax:

public class Global : HttpApplication
    {
        void Application_Start(object sender, EventArgs e)
        {
            RegisterRoutes();
        }

        private void RegisterRoutes()
        {
            // Edit the base address of Service1 by replacing the "Service1" string below
            RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(RestService)));
        }
    }

我的 web.config 文件:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>


  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
  </system.webServer>

  <system.serviceModel>
    <diagnostics>
      <messageLogging logEntireMessage="true" logKnownPii="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" />
      <endToEndTracing propagateActivity="true" activityTracing="true" messageFlowTracing="true" />
    </diagnostics>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
    <standardEndpoints>
      <webHttpEndpoint>
        <!-- 
            Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
            via the attributes on the <standardEndpoint> element below
        -->
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" maxBufferSize="500000" maxReceivedMessageSize="500000">          
          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />          
        </standardEndpoint>
      </webHttpEndpoint>
    </standardEndpoints>
    <behaviors>
        <serviceBehaviors>
            <behavior name="">
                <serviceCredentials>
                    <serviceCertificate storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" findValue="localhost" />
                </serviceCredentials>
            </behavior>
        </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

现在我的 IIS 指定了 Https 绑定:

现在我的虚拟目录已配置为名称 XmlRestService,因此当我浏览资源时,我得到以下输出:

【讨论】:

  • 我目前将“客户端证书”设置为忽略。
  • 您不需要有 readerQuotas 部分,但如果您的服务必须发送大量数据,最好离开它。
  • 使用该标准端点会导致以下结果:找不到与绑定 WebHttpBinding 的端点的方案 http 匹配的基地址。注册的基地址方案是 [https]。
  • 请找到我发布的示例应用程序,该应用程序使用 HTTPS 从基于 REST 的 WCF 服务获取信息。
【解决方案2】:

有很多不同的方法来实现 WCF。像许多人一样,这个答案对我不起作用。我想出了以下快速解决方案。我认为这可能是最通用和最简单的解决方案。这可能不被认为是雄辩的,但对于我们大多数人来说,无论如何在我们的工作中都没有受到赞赏。您可以尝试重定向,至少对于 GET 请求,而不是抛出错误。

#if !DEBUG
    // check secure connection, raise error if not secure 
    IncomingWebRequestContext request = WebOperationContext.Current.IncomingRequest;
    if (!request.UriTemplateMatch.BaseUri.AbsoluteUri.StartsWith("https://"))
    {
        throw new WebProtocolException(HttpStatusCode.BadRequest, "Https is required to use this service.", null);
    }
#endif

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多