2

Having an issue while making POX REST call using WCF with WebHttpBinding set to Basic Authentication (HttpClientCredentialType.Basic)

Instead of one call from the client with “Authorization: Basic” specified in HTTP Header, two calls are made. First call without authentication at all to which service responses with 401 Unauthorized error, second call with proper authentication info.

This seems to be handled by WCF service with no hiccup at all. Calling third party services obviously creates a problem since they respond with error immediately.

Service Code:

[ServiceContract]
public interface IService
{
    [OperationContract]
    [WebInvoke(BodyStyle = WebMessageBodyStyle.Bare,
        RequestFormat = WebMessageFormat.Xml,
        UriTemplate = "")]
    Message SendData(Message message);

}

public class Service : IService
{
    public Message SendData(Message message)
    {           return Message.CreateMessage(MessageVersion.None, String.Empty, "test");
    }
}

Client Code:

public class Client: WebChannelFactory<IService>, IService
{
    public Client(Uri baseUri, string userName, string password)
        : base(CreateBinding(),
               baseUri)
    {
        Credentials.UserName.UserName = userName;
        Credentials.UserName.Password = password;
    }

    public Message SendData(Message requestMessage)
    {
        var channel = CreateChannel();
        Message responseMessage = channel.SendData(requestMessage);
        return responseMessage;
    }

    private static Binding CreateBinding()
    {
        var binding = new WebHttpBinding();
        binding.Security.Mode = WebHttpSecurityMode.TransportCredentialOnly;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
        return binding;
    }

}

Using TcpTrace I’m seeing these to requests back to back:

POST / HTTP/1.1  
Content-Type: application/xml; charset=utf-8  
VsDebuggerCausalityData:   uIDPo2lH6p+lUOdFmrqDKGWYeQkAAAAA7+Y4QR6wNUWZmwCaasMx7xrfcJZxph9NocstwCh8NQsACQAA  
Host: localhost:9090  
Content-Length: 89  
Expect: 100-continue  
Connection: Keep-Alive  

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">test request</string>  

POST / HTTP/1.1  
Content-Type: application/xml; charset=utf-8  
VsDebuggerCausalityData: uIDPo2lH6p+lUOdFmrqDKGWYeQkAAAAA7+Y4QR6wNUWZmwCaasMx7xrfcJZxph9NocstwCh8NQsACQAA  
Authorization: Basic dGVzdDp0ZXN0  
Host: localhost:9090  
Content-Length: 89  
Expect: 100-continue  

<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">test request</string> 

Note only second call contains: Authorization: Basic dGVzdDp0ZXN0 How to stop the first request (without authorization) to be made?

Sample solution with TcpTrace utility can be downloaded here:

WCF-BasicAuthenticationIssue.zip

4

2 回答 2

4

所以根据 Remus 的回答,这是我的解决方法

        public Message SendData(Message requestMessage)
    {
        var channel = CreateChannel();
        Message responseMessage;
        using (new OperationContextScope((IClientChannel)channel))
        {
            WebOperationContext.Current.OutgoingRequest
                .Headers[HttpRequestHeader.Authorization] = "Basic "
                + Convert.ToBase64String(Encoding.ASCII.GetBytes(
                Credentials.UserName.UserName + ":" + Credentials.UserName.Password));
            responseMessage = channel.SendData(requestMessage); 
        }
        return responseMessage;
    }

我只是用基本授权强制第一个请求出去

于 2009-09-22T22:23:10.663 回答
3

问题实际上在于那些第三方。根据RFC 2617,基本身份验证在两个调用中完成,就像 Digest 一样。服务器应在第一次调用时响应包含领域的挑战:

在收到保护空间内未经授权的 URI 请求后
,源服务器可能会以
如下所示的质询响应:

  WWW-Authenticate: Basic realm="WallyWorld"

其中“WallyWorld”是服务器分配的字符串,用于标识
Request-URI的保护空间

WCF 终结点将仅对第一个调用之后的后续调用进行预身份验证。appdomain 对任何资源的第一次调用将不包含基本的标头用户名和密码。

另请参阅WCF 中的 PreAuthenticate 标志发生了什么

于 2009-09-22T20:32:53.663 回答