具有WCF和Windows身份验证的CORS

吉尔斯·亨伯格

强制执行Windows身份验证时,是否可以处理WCF服务的“跨源资源共享”请求?

我的情况:

  1. 我已经设置了通过webHttpBinding公开的自托管WCF服务。

  2. 应该使用jQuery从浏览器直接调用此服务。实际上,这将限制我使用basicHttpBinding或webHttpBinding。在这种情况下,我使用webHttpBinding来调用服务操作。

  3. HTML页面(将称为WCF服务)是从与WCF服务不同的端口在同一台计算机上的Web服务器提供的。这意味着我需要CORS支持才能在Firefox,Chrome等系统中正常工作。

  4. 用户在调用WCF服务时必须使用Windows身份验证进行身份验证。为此,我已将webHttpBinding配置为使用传输安全模式“ TransportCredentialsOnly”。

W3C规定在这种情况下应使用CORS。简而言之,这意味着浏览器将检测到我正在执行跨域请求。在将请求实际发送到我的WCF服务之前,它将向我的WCF服务URL发送一个所谓的“预检”请求。此预检请求使用HTTP方法“ OPTIONS”,并询问是否允许原始URL(=为我的HTML服务的Web服务器)将请求发送到我的服务URL。然后,浏览器在将实际请求发送到我的WCF服务之前需要HTTP 200响应(=“ OK”)。我的服务收到的其他任何答复都将阻止发送实际的请求。

目前WCF尚未内置CORS,因此我使用WCF扩展点来添加CORS兼容性。

我的自托管服务的App.Config的服务部分:

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="MyApp.DefaultServiceBehavior">
        <serviceMetadata httpGetEnabled="True"/>
        <serviceDebug includeExceptionDetailInFaults="True"/>
      </behavior>
    </serviceBehaviors>
    <endpointBehaviors>
      <behavior name="MyApp.DefaultEndpointBehavior">
        <webHttp/>
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <bindings>
    <webHttpBinding>
      <binding name="MyApp.DefaultWebHttpBinding">
        <security mode="TransportCredentialOnly">
          <transport clientCredentialType="Windows"/>
        </security>
      </binding>
    </webHttpBinding>
  </bindings>
  <services>
    <service 
      name="MyApp.FacadeLayer.LookupFacade"
      behaviorConfiguration="MyApp.DefaultServiceBehavior"
      >
      <endpoint
        contract="MyApp.Services.ILookupService"
        binding="webHttpBinding"
        bindingConfiguration="MyApp.DefaultWebHttpBinding"
        address=""
        behaviorConfiguration="MyApp.DefaultEndpointBehavior"
        >
      </endpoint>
      <host>
        <baseAddresses>
          <add baseAddress="http://localhost/Temporary_Listen_Addresses/myapp/LookupService"/>
        </baseAddresses>
      </host>
    </service>
  </services>
</system.serviceModel>

我已经实现了一个IDispatchMessageInspector,它可以响应预检消息:

public class CORSSupport : IDispatchMessageInspector
{
    private Dictionary<string, string> requiredHeaders;

    public CORSSupport(Dictionary<string, string> requiredHeaders)
    {
        this.requiredHeaders = requiredHeaders ?? new Dictionary<string, string>();
    }

    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext)
    {
        HttpRequestMessageProperty httpRequest = request.Properties["httpRequest"] as HttpRequestMessageProperty;

        if (httpRequest.Method.ToUpper() == "OPTIONS")
            instanceContext.Abort();

        return httpRequest;
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        HttpRequestMessageProperty httpRequest = correlationState as HttpRequestMessageProperty;
        HttpResponseMessageProperty httpResponse = reply.Properties["httpResponse"] as HttpResponseMessageProperty;

        foreach (KeyValuePair<string, string> item in this.requiredHeaders)
            httpResponse.Headers.Add(item.Key, item.Value);

        string origin = httpRequest.Headers["origin"];
        if (origin != null)
            httpResponse.Headers.Add("Access-Control-Allow-Origin", origin);

        if (httpRequest.Method.ToUpper() == "OPTIONS")
            httpResponse.StatusCode = HttpStatusCode.NoContent;
    }
}

通过自定义IServiceBehavior属性注册此IDispatchMessageInspector。

我这样通过jQuery调用服务:

$.ajax(
    {
        url: 'http://localhost/Temporary_Listen_Addresses/myapp/LookupService/SomeLookup',
        type: 'GET',
        xhrFields:
            {
                withCredentials: true
            }
    }
)
.done(function () { alert('Yay!'); })
.error(function () { alert('Nay!'); });

这在IE10和Chrome中有效(我看到一个消息框,说“是!”),但在Firefox中不起作用。在Firefox中,我得到一个“不!” 以及HTTP 401(未经授权)错误。

401是由于我在服务配置中设置的“ Windows身份验证”所致。身份验证的工作方式是浏览器首先发送没有任何身份验证信息的请求。然后,服务器用HTTP 401(未授权)进行回复,指示要使用的身份验证方法。然后,浏览器通常会重新提交包含用户凭证的请求(此请求将继续正常进行)。

不幸的是,W3C似乎表明不应将凭据传递到CORS飞行前消息中。因此,WCF使用HTTP 401进行回复。似乎Chrome确实以某种方式在预检请求标头中发送了凭据(根据W3C规范,这实际上是不正确的),而Firefox则没有。此外,W3C仅识别对预检请求的HTTP 200响应:任何其他响应(例如我收到的HTTP 401)仅表示CORS请求失败,并且实际的请求可能未提交。

我不知道如何使这种(简单的)方案起作用。有人可以帮忙吗?

吉尔斯·亨伯格

尤里卡(一种)。似乎Firefox不喜欢我为服务指定的“协商”身份验证。当我将身份验证方案从“协商,匿名”更改为“ Ntlm,匿名”时,它似乎起作用:

<system.serviceModel>
  <behaviors>
    <serviceBehaviors>
      <behavior name="MyApp.DefaultServiceBehavior">
        <serviceMetadata httpGetEnabled="True"/>
        <serviceDebug includeExceptionDetailInFaults="True"/>
        <serviceAuthenticationManager authenticationSchemes="Ntlm, Anonymous"/>
      </behavior>
    </serviceBehaviors>
    <endpointBehaviors>
      <behavior name="MyApp.DefaultEndpointBehavior">
        <webHttp/>
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <bindings>
    <webHttpBinding>
      <binding name="MyApp.DefaultWebHttpBinding">
        <security mode="TransportCredentialOnly">
          <transport clientCredentialType="InheritedFromHost"/>
        </security>
      </binding>
    </webHttpBinding>
  </bindings>
  <services>
    <service 
      name="MyApp.FacadeLayer.LookupFacade"
      behaviorConfiguration="MyApp.DefaultServiceBehavior"
      >
      <endpoint
        contract="MyApp.Services.ILookupService"
        binding="webHttpBinding"
        bindingConfiguration="MyApp.DefaultWebHttpBinding"
        address=""
        behaviorConfiguration="MyApp.DefaultEndpointBehavior"
        >
      </endpoint>
      <host>
        <baseAddresses>
          <add baseAddress="http://localhost/Temporary_Listen_Addresses/myapp/LookupService"/>
        </baseAddresses>
      </host>
    </service>
  </services>
</system.serviceModel>

我以为Firefox支持“协商”方案……任何人都知道为什么它不起作用?

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

具有Windows身份验证的HttpRequestMessage

来自分类Dev

具有Windows身份验证的SessionAuthenticationModule

来自分类Dev

具有SSL以及用户名和密码身份验证的自托管WCF服务

来自分类Dev

具有Windows身份验证的Web API中的Cors问题

来自分类Dev

在Firefox和Chrome中,基于XMLHttpRequest的具有基本身份验证的CORS调用失败

来自分类Dev

Windows身份验证与MVC。具有不同“访问级别”的Windows身份验证

来自分类Dev

WCF与Windows身份验证问题

来自分类Dev

WCF用户身份验证和授权

来自分类Dev

具有SSL和基本身份验证的SolrCloud

来自分类Dev

具有Kerberos身份验证的WCF:由于身份验证失败,无法满足对安全令牌的请求

来自分类Dev

具有Kerberos身份验证的WCF:由于身份验证失败,无法满足对安全令牌的请求

来自分类Dev

具有表单身份验证的ASP.NET MVC和具有基本身份验证的WebApi

来自分类Dev

具有表单身份验证的ASP.NET MVC和具有基本身份验证的WebApi

来自分类Dev

ASP.NET MVC + API和WCF具有针对自定义数据库和活动目录的基于声明的授权和身份验证

来自分类Dev

Windows计算机上具有身份验证和SSL连接问题的CUPS共享打印机

来自分类Dev

具有JWT和基本身份验证的HttpListener:如何发送WWW身份验证?(自托管)

来自分类Dev

在没有X.509或Windows身份验证的情况下对WCF流量进行加密

来自分类Dev

具有asp.net身份和Android授权的混合身份验证

来自分类Dev

具有WS-Security,签名标头,身份验证令牌和主体加密的WCF Web服务客户端

来自分类Dev

CORS预检请求返回带有Windows身份验证的HTTP 401

来自分类Dev

具有Windows身份验证的已启用CORS ASP.NET Web API 2应用程序中的预检请求

来自分类Dev

IIS 8和Windows身份验证

来自分类Dev

wsHttpbinding与TransportWithMessageCredential和Windows身份验证

来自分类Dev

R和Windows身份验证

来自分类Dev

具有相互身份验证证书的WCF Web服务无法进行客户端链信任验证

来自分类Dev

WCF Windows 身份验证不适用于 wsHttpBinding

来自分类Dev

Dynamics CRM和WSDL WCF身份验证

来自分类Dev

Azure Active Directory和WCF身份验证

来自分类Dev

WCF 身份验证和授权不起作用

Related 相关文章

  1. 1

    具有Windows身份验证的HttpRequestMessage

  2. 2

    具有Windows身份验证的SessionAuthenticationModule

  3. 3

    具有SSL以及用户名和密码身份验证的自托管WCF服务

  4. 4

    具有Windows身份验证的Web API中的Cors问题

  5. 5

    在Firefox和Chrome中,基于XMLHttpRequest的具有基本身份验证的CORS调用失败

  6. 6

    Windows身份验证与MVC。具有不同“访问级别”的Windows身份验证

  7. 7

    WCF与Windows身份验证问题

  8. 8

    WCF用户身份验证和授权

  9. 9

    具有SSL和基本身份验证的SolrCloud

  10. 10

    具有Kerberos身份验证的WCF:由于身份验证失败,无法满足对安全令牌的请求

  11. 11

    具有Kerberos身份验证的WCF:由于身份验证失败,无法满足对安全令牌的请求

  12. 12

    具有表单身份验证的ASP.NET MVC和具有基本身份验证的WebApi

  13. 13

    具有表单身份验证的ASP.NET MVC和具有基本身份验证的WebApi

  14. 14

    ASP.NET MVC + API和WCF具有针对自定义数据库和活动目录的基于声明的授权和身份验证

  15. 15

    Windows计算机上具有身份验证和SSL连接问题的CUPS共享打印机

  16. 16

    具有JWT和基本身份验证的HttpListener:如何发送WWW身份验证?(自托管)

  17. 17

    在没有X.509或Windows身份验证的情况下对WCF流量进行加密

  18. 18

    具有asp.net身份和Android授权的混合身份验证

  19. 19

    具有WS-Security,签名标头,身份验证令牌和主体加密的WCF Web服务客户端

  20. 20

    CORS预检请求返回带有Windows身份验证的HTTP 401

  21. 21

    具有Windows身份验证的已启用CORS ASP.NET Web API 2应用程序中的预检请求

  22. 22

    IIS 8和Windows身份验证

  23. 23

    wsHttpbinding与TransportWithMessageCredential和Windows身份验证

  24. 24

    R和Windows身份验证

  25. 25

    具有相互身份验证证书的WCF Web服务无法进行客户端链信任验证

  26. 26

    WCF Windows 身份验证不适用于 wsHttpBinding

  27. 27

    Dynamics CRM和WSDL WCF身份验证

  28. 28

    Azure Active Directory和WCF身份验证

  29. 29

    WCF 身份验证和授权不起作用

热门标签

归档