CORS(跨源资源共享)https无法正常工作(IIS托管的WCF休息启用端点)

时间:2014-09-11 09:50:54

标签: c# wcf iis https cors

希望有人可以提供帮助

我一直在寻找一个简单的原型,使用CORS通过https进行WCF。我们已经实现了一个解决方案并在http中进行了测试,它运行良好。一旦我们尝试使用https调用WCF端点,我们就会得到一个" 404 Not Found"在这种情况下。 但是在我们的生产代码中,我得到了一个" 400 Bad request"我将在稍后发布!现在我想帮助解决404错误。

我已经搜索并尝试过很多东西,但仍然无法正常工作!

我已经编写了一个小测试Web项目和WCF端点,可以在http。

中正常工作

在客户端,我正在向以下端点发出jquery ajax请求

var theUrl = "https://myhostmachine/Cors/service.svc/web";
function makeGetDataJQueryRequest() {
    $.support.cors = true;
    $.ajax({
        url: theUrl + "/GetData?value=24",
        contentType: "application/json; charset=utf-8",
        type: "POST",
        cache: false,
        dataType: "json",
        //                data: undefined,
        success: function (response) {
            alert("success");
        },
        error: function (a, b, c) {
            alert("error");
        }
    });
}

在服务器上,我有我的WCF代码执行所有预检cors响应,正如我所说的在http中工作。

  1. 我已经设置了自签名证书,并在我的IIS中使用了它,并确保通过mmc插件将其添加到我的证书存储区。

  2. 当我立即发出请求时,我发现它没有发送OPTIONS请求,为什么不呢?但它确实通过http发送了它?

  3. Fiddler请求:

    POST https://myhostmachine/Cors/service.svc/web/GetData?value=24 HTTP/1.1
    Host: hsw10530.cse-servelec.com
    Connection: keep-alive
    Content-Length: 0
    Accept: application/json, text/javascript, */*; q=0.01
    Origin: https://myhostmachine
    X-Requested-With: XMLHttpRequest
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.103 Safari/537.36
    Content-Type: application/json; charset=utf-8
    Referer: https://hsw10530.cse-servelec.com/CorsClient/
    Accept-Encoding: gzip,deflate
    Accept-Language: en-US,en;q=0.8
    Cookie: ASPSESSIONIDCGCSARDQ=IFNPFPKAJIMFCJHEANDFOBCH
    

    响应:

    HTTP/1.1 404 Not Found
    Server: Microsoft-IIS/7.5
    X-Powered-By: ASP.NET
    Date: Thu, 11 Sep 2014 09:36:51 GMT
    Content-Length: 0
    

    Web.config如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    
    
      <system.web>
        <compilation debug="true" />
      </system.web>
    
      <system.serviceModel>
    
        <behaviors>
          <serviceBehaviors>
            <behavior>
              <serviceMetadata httpGetEnabled="True" />
              <serviceDebug includeExceptionDetailInFaults="True" />
            </behavior>
          </serviceBehaviors>
    
          <endpointBehaviors>
            <behavior name="restBehaviour">
              <webHttp />
              <CorsSupport />
            </behavior>
          </endpointBehaviors>
    
        </behaviors>
    
        <extensions>
          <behaviorExtensions>
            <add name="CorsSupport" type="WcfService.Cors.CorsSupportBehaviorElement, WcfService" />
          </behaviorExtensions>
        </extensions>
    
        <bindings>
          <webHttpBinding>
            <binding name="CORSWebHttpBinding" crossDomainScriptAccessEnabled="True" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">
              <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
              <security mode="Transport">
              </security>
            </binding>
          </webHttpBinding>
        </bindings>
    
        <services>
          <service name="WcfService.Service1">
            <host>
              <baseAddresses />
            </host>
            <endpoint address="" binding="wsHttpBinding" contract="WcfService.IService1" />
            <endpoint address="web" binding="webHttpBinding" bindingConfiguration="" behaviorConfiguration="restBehaviour" contract="WcfService.IService1" />
            <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
          </service>
        </services>
    
      </system.serviceModel>
    
    </configuration>
    

    以下是WCF代码或者至少是执行所有预检Cors的重要部分。

    public class CorsMessageInspector : IDispatchMessageInspector
        {
            public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
            {
                HttpRequestMessageProperty httpRequest = request.Properties["httpRequest"] as HttpRequestMessageProperty;
    
                // Check if the client sent an "OPTIONS" request
                if (httpRequest != null)
                {
                    if (httpRequest.Method == "OPTIONS")
                    {
                        // Store the requested headers
                        OperationContext.Current.Extensions.Add(new PreflightDetected(
                            httpRequest.Headers["Access-Control-Request-Headers"]));
                    }
                }
                return null;
            }
    
            public void BeforeSendReply(ref Message reply, object correlationState)
            {
                HttpResponseMessageProperty property = null;
    
                if (reply == null)
                {
                    // This will usually be for a preflight response
                    reply = Message.CreateMessage(MessageVersion.None, null);
                    property = new HttpResponseMessageProperty();
                    reply.Properties[HttpResponseMessageProperty.Name] = property;
                    property.StatusCode = HttpStatusCode.OK;
                }
                else
                {
                    property = reply.Properties[HttpResponseMessageProperty.Name] as HttpResponseMessageProperty;
                }
    
                PreflightDetected preflightRequest = OperationContext.Current.Extensions.Find<PreflightDetected>();
                if (preflightRequest != null)
                {
                    // Add allow HTTP headers to respond to the preflight request
                    if (preflightRequest.RequestedHeaders == string.Empty)
                        property.Headers.Add("Access-Control-Allow-Headers", "Accept");
                    else
                        property.Headers.Add("Access-Control-Allow-Headers", preflightRequest.RequestedHeaders + ", Accept");
    
                    //http://hsw10530.cse-servelec.com
                    property.Headers.Add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
                }
    
                // Add allow-origin header to each response message, because client expects it
                property.Headers.Add("Access-Control-Allow-Origin", "*");
            }
        }
    

    如果您能够通过ssl设置CORS以及您为使其工作了怎么办,我们将非常感谢您的帮助?

    非常感谢 安德鲁

1 个答案:

答案 0 :(得分:1)

好的,我得到它的工作,毕竟我只需要提供bindingConfiguration作为我的端点在配置的底部有一个空字符串

所以配置文件确实有;我只是没有指明这个。您还可以看到安全模式是传输为ssl,否则超过标准http应该设置为无。

<endpoint address="web" binding="webHttpBinding" bindingConfiguration="CORSWebHttpBinding" behaviorConfiguration="restBehaviour" contract="WcfService.IService1" />

我也不需要CORSWebHttpBinding上的crossDomainScriptAccessEnabled =“True”,因为这似乎在使用http时停止了它,但在https上没问题。