使用WCF的Http请求中缺少授权标头

时间:2010-11-02 18:35:40

标签: wcf http-headers

我正在使用WCF访问Web服务。使用WSHttpBinding,安全模式设置为传输(https),客户端凭据类型为基本。当我尝试使用代理访问服务时,获得401未经授权的异常。

这是Binding

var binding = new WSHttpBinding()
        {
            UseDefaultWebProxy = true,
            Security =
            {
                Mode = SecurityMode.Transport,
                Transport =
                {
                    ClientCredentialType = HttpClientCredentialType.Basic,
                },
            }
        };

这是服务电话

var client = new InternetClient(binding, new EndpointAddress("httpsurl"));

        client.ClientCredentials.UserName.UserName = "username";
        client.ClientCredentials.UserName.Password = "password";
        client.ProcessMessage("somevalue");

使用Http Analyzer查看Http头文件时 连接头

(请求行):CONNECT somehost.com:443 HTTP / 1.1
主持人:somehost.com
代理连接:保持活动

POST HEADER

(请求行):POST /Company/1.0 HTTP / 1.1
内容类型:应用/肥皂+ xml的;字符集= UTF-8
VsDebuggerCausalityData:uIDPo + voStemjalOv5LtRotFQ7UAAAAAUKLJpa755k6oRwto14BnuE2PDtYKxr9LhfqXFSOo8pEACQAA
主持人:somehost.com
内容长度:898
预计:100,继续
连接:保持活动

如果您看到标题Authorization标头丢失

现在我的问题是为什么WCF调用缺少Authorization标头?我错过了什么吗? 。请询问您是否需要更多信息

4 个答案:

答案 0 :(得分:11)

这是一个常见问题,但情况与您的想法不同。

事实证明,最初对于第一个请求,配置为使用HTTP基本身份验证的WCF客户端仍会将请求不带必要的授权标头发送到服务器。这是WCF客户端使用的HttpWebRequest类的默认行为。

通常,Web服务服务器将向WCF客户端返回HTTP 401 Unauthorized响应,然后后者将重新发送消息 授权标头。这意味着在正常情况下,对于HTTP基本身份验证,将会有一个相当无用的往返服务器。

这也解释了为什么你的嗅探消息中缺少标题。一些Http嗅探器可能没有传递401响应,所以整个交换都搞砸了。

通过在每个请求中手动注入所需的Authorization标头,可以避免服务器往返和对401响应的依赖。参见例如how to manually inject Authorization header into WCF request

答案 1 :(得分:8)

作为对前一个答案的略微修改,为了支持异步/等待调用,您实际上可以创建一个新的OperationContext并在您喜欢的任何线程上传递它(只要它不是在并发线程之间共享,因为它不是&# 39; ta线程安全对象)

var client = new MyClient();
client.ClientCredentials.UserName.UserName = "username"; 
client.ClientCredentials.UserName.Password = "password";
var httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Headers[HttpRequestHeader.Authorization] = "Basic " + Convert.ToBase64String(Encoding.ASCII.GetBytes(client.ClientCredentials.UserName.UserName + ":" + client.ClientCredentials.UserName.Password));

var context = new OperationContext(ormClient.InnerChannel);
using (new OperationContextScope(context))
{
    context.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
    return await client.SomeMethod();
}

答案 2 :(得分:1)

注意Expect:100-continue在标题中。这就是往返的原因。

将它放入web.config并再试一次:

<system.net>
    <settings>
      <servicePointManager expect100Continue="false"/>
    </settings>
</system.net>

答案 3 :(得分:0)

实际上,我对这个问题错了。运行HTTP分析器时,我确实看到了不同的行为。当Http anaylzer运行时,我的应用程序在收到401响应后崩溃了。当Http分析器应用程序关闭时,上面的代码按预期工作。