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

Amz*_*ath 8 wcf http-headers

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

这是绑定

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

这是服务电话

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

        client.ClientCredentials.UserName.UserName = "username";
        client.ClientCredentials.UserName.Password = "password";
        client.ProcessMessage("somevalue");
Run Code Online (Sandbox Code Playgroud)

使用Http Analyzer CONNECT HEADER查看Http头文件时

(Request-Line):CONNECT somehost.com:443 HTTP/1.1
主机:somehost.com
代理连接:Keep-Alive

POST HEADER

(请求行):POST /Company/1.0 HTTP/1.1
Content-Type:application/soap + xml; charset = utf-8
VsDebuggerCausalityData:uIDPo + voStemjalOv5LtRotFQ7UAAAAAUKLJpa755k6oRwto14BnuE2PDtYKxr9LhfqXFSOo8pEACQAA
主持人:somehost.com
内容长度:898
期望:100-continue
连接:Keep-Alive

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

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

小智 13

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

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

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

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

通过手动将所需的Authorization标头注入每个请求,可以避免服务器往返和对401响应的依赖.请参阅例如如何手动将Authorization标头注入WCF请求


Fla*_*DOA 9

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

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();
}
Run Code Online (Sandbox Code Playgroud)


Amz*_*ath 0

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