简体   繁体   English

CORS(跨源资源共享)https不起作用(IIS托管的启用WCF Rest的端点)

[英]CORS (Cross Origin Resource Sharing) https not working (IIS hosted WCF rest enabled endpoint)

Hi hoping that someone can help 嗨,希望有人能帮忙

I have been looking at getting a simple prototype working using CORS to WCF over https. 我一直在寻找使用CORS通过https到WCF的简单原型。 We have implemented a solution and tested it in http and it works fine. 我们已经实现了一个解决方案,并在http中对其进行了测试,并且效果很好。 As soon as we try and call the WCF endpoints using https we just get a "404 Not Found" in this case. 一旦尝试使用https调用WCF端点,在这种情况下,我们只会得到“ 404 Not Found”。 But in our production code I get a "400 Bad request" which I will post about later! 但是在我们的生产代码中,我收到一个“ 400错误的请求”,稍后我将发布它! For now I would like help with the 404 error. 目前,我需要404错误帮助。

I have searched and tried many things but still not got it working! 我已经搜索并尝试了许多方法,但是仍然无法正常工作!

I have written a little test web project and WCF endpoints that works fine in http. 我已经编写了一些测试Web项目和WCF端点,它们在http中可以正常工作。

On the client side I am making an jquery ajax request to the following endpoint 在客户端,我向以下端点发出了一个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");
        }
    });
}

On the server I have my WCF code that does all the preflight cors response and as I say working in http. 在服务器上,我有我的WCF代码,该代码可以完成所有预检cors响应,就像我在http中所说的那样。

  1. I have setup a self signed certificate and used that in my IIS, also making sure to add it the my certificate store via the mmc plugin. 我已经设置了一个自签名证书,并在IIS中使用了它,还确保通过mmc插件将其添加到我的证书存储中。

  2. When I make the request straight away I can see that it is not sending an OPTIONS request, so why not? 当我立即发出请求时,我可以看到它没有发送OPTIONS请求,为什么不呢? But it does sent it via http? 但是它确实通过http发送吗?

Fiddler Request: 提琴手要求:

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

Response: 响应:

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

The Web.config is as follows: 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>

Below is the WCF code or at least the important bit that does all the preflight cors stuff. 以下是WCF代码或至少是完成所有飞行前检查工作的重要部分。

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", "*");
        }
    }

Your help would be greatly appreciated, if you have ever been able to setup CORS over ssl and what did you do to get it to work? 如果您曾经能够通过ssl设置CORS,那么您将获得极大的帮助,并且您做了什么工作才能使它工作呢?

Many thanks Andrew 非常感谢安德鲁

Ok I got it working, after all that I just needed to provide the bindingConfiguration as my endpoint at the bottom of the config had this as an empty string 好的,我能正常工作了,毕竟我只需要提供bindingConfiguration即可,因为配置底部的端点将其作为一个空字符串

So the config file did have it in; 因此配置文件中确实包含了它; it I just had not specified this. 我只是没有指定这个。 You can also see that the security mode was Transport for ssl, otherwise over standard http this should be set to None. 您还可以看到安全模式为Transport for ssl,否则应通过标准http将其设置为None。

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

I also didn't need the crossDomainScriptAccessEnabled="True" on the CORSWebHttpBinding as this seemed to stop it when using http, but was ok on https. 我也不需要CORSWebHttpBinding上的crossDomainScriptAccessEnabled =“ True”,因为这在使用http时似乎可以将其停止,但在https上还可以。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM