在WCF和Windows身份验证中处理CORS

时间:2018-07-05 12:10:33

标签: c# angular wcf cors windows-authentication

我已经实现了一个自托管的WCF Rest服务和一个相应的Angular CLI客户端。我遇到了CORS的麻烦,但是在HttpClientCredentialType.None中设置了WebHttpBinding时,我能够解决它们。

问题是,我需要使用HttpClientCredentialType.Windows,因为我必须知道使用该系统的Windows用户的身份。
这是使用的绑定:

new WebHttpBinding
{
    MaxBufferSize = int.MaxValue,
    MaxBufferPoolSize = 524288,
    MaxReceivedMessageSize = int.MaxValue,                
    OpenTimeout = TimeSpan.FromMinutes(1),
    SendTimeout = TimeSpan.FromMinutes(1),
    ReceiveTimeout = TimeSpan.FromMinutes(10),
    CloseTimeout = TimeSpan.FromMinutes(1),
    ReaderQuotas =
    {
        MaxStringContentLength = int.MaxValue,
        MaxArrayLength = int.MaxValue,
        MaxDepth = int.MaxValue,
        MaxNameTableCharCount = int.MaxValue
    },
    Security =
    {
        Mode = WebHttpSecurityMode.Transport,
        Transport = { ClientCredentialType = HttpClientCredentialType.Windows }
        //Transport = { ClientCredentialType = HttpClientCredentialType.None}
    }
};

但是现在CORS-Options调用被HttpStatus 401 Unauthorized拒绝了,因为其中没有身份验证标头。因此,整个呼叫将被拒绝(理论上正确……)。

当然我已经添加了所有必需的标题。如前所述,它适用于None身份验证。

WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "http://localhost:4200");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept, Id, Origin, Authorization");
WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Credentials", "true");

所以我看到三种解决问题的可能性。

  1. 以某种方式通过我的Angular客户端获取CORS-Options调用以传递我的Windows凭据。
  2. 获取WCF服务以忽略CORS-Options调用中的身份验证。
  3. 将“授权”设置回“无”,并以其他方式传递我的Windows凭据(不强制用户输入其凭据)。

当我在--disable-web-security中使用Chrome Browser时,它甚至也适用于Windows身份验证。但是对我来说,这不是生产系统的解决方案。

也许有人对我的问题有任何想法甚至解决方案。

2 个答案:

答案 0 :(得分:0)

此处的选项是使用Microsoft.AspNet.WebApi.Cors

我使用Web Api遇到了这个问题,发现这个解决方案(nuget程序包)也可以与WCF一起使用。

您需要在课程上方使用此装饰器:

[EnableCors(origins: "http://example.com", headers: "*", methods: "*")]

,然后在您的方法上方添加装饰器:

[AcceptVerbs("POST")]

这将忽略飞行前请求,只会发送您的实际请求。

编辑

多看一些代码后,我了解了这个问题:您需要一个额外的参数:

var cors = new EnableCorsAttribute("http://IP:PORT", "*", "*") { SupportsCredentials = true };
config.EnableCors(cors); 

asp.net forums上有一篇很好的文章也可以帮助您解决情况。

要求

这是wcf中HttpConfiguration的{​​{3}}。

答案 1 :(得分:0)

您不能只添加global.asax并添加Access-Control-Allow-Origin标头

protected void Application_BeginRequest(object sender, EventArgs e)
{
    HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "http://YourDomain");
    if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
    {
        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, PUT, DELETE");

        HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
        HttpContext.Current.Response.AddHeader("Access-Control-Max-Age", "1728000");
        HttpContext.Current.Response.End();
    }
}