2

WebHttpBinding を基本認証 (HttpClientCredentialType.Basic) に設定して WCF を使用して POX REST 呼び出しを行う際に問題が発生する

HTTP ヘッダーに「Authorization: Basic」を指定したクライアントからの 1 回の呼び出しの代わりに、2 回の呼び出しが行われます。サービスが 401 Unauthorized エラーで応答する認証なしの最初の呼び出し、適切な認証情報を持つ 2 番目の呼び出し。

これは、問題なく WCF サービスによって処理されるようです。サードパーティのサービスを呼び出すと、すぐにエラーが返されるため、明らかに問題が発生します。

サービスコード:

[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");
    }
}

クライアントコード:

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;
    }

}

TcpTrace を使用すると、次のようなリクエストが連続して表示されます。

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> 

Authorization: Basic dGVzdDp0ZXN0最初 のリクエスト (認証なし) を停止するには?

TcpTrace ユーティリティを使用したサンプル ソリューションは、次の場所からダウンロードできます。

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 に従って、基本認証はダイジェストと同様に 2 つの呼び出しで行われます。サーバーは、レルムを含むチャレンジで最初の呼び出しに応答する必要があります。

保護空間内の URI に対する無許可の要求を受信すると
、オリジン サーバー
は次のようなチャレンジで応答する場合があります。

  WWW-Authenticate: Basic realm="WallyWorld"

ここで、「WallyWorld」は
、Request-URI の保護スペースを識別するためにサーバーによって割り当てられた文字列です。

WCF エンドポイントは、最初の呼び出し以降の呼び出しのみを事前認証します。appdomain によってリソースに対して行われる最初の呼び出しには、基本ヘッダーのユーザー名とパスワードは含まれません。

WCF の PreAuthenticate フラグに何が起こったのかも参照してください。

于 2009-09-22T20:32:53.663 に答える