我正在使用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标头?我错过了什么吗? 。请询问您是否需要更多信息
答案 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分析器应用程序关闭时,上面的代码按预期工作。