仅通过 HTTPS 的 WCF 服务

发布于 2025-01-03 03:13:24 字数 1031 浏览 0 评论 0原文

我有一个 RESTful WCF 服务,希望将其托管在 Windows Server 2008 R2 服务器上。目前它作为应用程序托管在现有网站中。自签名证书正用于端口 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)。

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

I have a RESTful WCF service that I want to host on a Windows Server 2008 R2 server. It's currently hosted as an Application within an existing website. A self-signed certificate is being used for port 443.

I'd like the service to be served over HTTPS only. In the SSL Settings for the Application, I've set it to "Require SSL". The endpoint configuration is as follows:

  <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>

However, I'm receiving 403 responses when trying to access the service via a browser (e.g. https://example.com/myservices/baz-service/yip-resource).

Did I miss anything during configuration?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别理我 2025-01-10 03:13:24

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

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

更新:

请了解我如何使用 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 绑定:

IIS 中的站点绑定

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

HTTPS 上的 REST 服务的输出

Setting the "Require SSL" option on IIS means that you are performing authentication using client certificates. Just set that option to ignore or disable that option if you dont have any client certificate authentication.

To avoid your service to serve only on HTTPS remove the HTTP binding from the "Binding" option on your website. Else just expose your bindings to use transport as a security mechanism and that should take care of your WCF service being served only on HTTPS.

UPDATE:

Please find on how I have a RESTful service hosted on IIS with Https:

[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;
        }
}

My 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)));
        }
    }

My web.config file:

<?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>

Now my IIS has the Https binding specified:

Site Bindings in IIS

Now my virtual directory has been configured with the name XmlRestService and hence when i browse to the resource i get the below output:

Output from a REST Service on HTTPS

诗酒趁年少 2025-01-10 03:13:24

有很多不同的方法来实现 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

There are a lot of different ways to implement WCF. This answer like many did not work for me. I came up with the following quick solution. I think it is probably the most universal and simple solution. This may not be considered eloquent but for most of us that's not appreciated in our work anyway. You could try a redirect, at least for GET requests, instead of throwing an error.

#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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文