具有基本身份验证的Web引用失败

时间:2011-06-14 22:36:41

标签: c# .net web-services cxf basic-authentication

我有一个使用Apache CXF创建的Web服务,以及两个使用Web引用(不是服务引用)的.NET客户端。紧凑的框架客户端可以工作,但.NET 4.0桌面客户端仅在与localhost通信时才有效。这是客户端设置:

        var client = new Permission.Permission();
        client.Credentials = new NetworkCredential(username, password);
        client.PreAuthenticate = true;
        client.Url = url + "/Permission";

如果urlhttp://localhost:8080/,则呼叫成功,但如果为http://127.0.0.1:8080,则呼叫失败并显示错误401.由于某种原因,生成的客户端代码在401响应处停止,并且不发送用户名和密码。

编辑:我找到了罪魁祸首,但我不知道最终的答案。 Visual Studio已将此部分插入app.config文件中:

<applicationSettings>
    <MyService.Properties.Settings>
        <setting name="MyService_Permission_Permission" serializeAs="String">
            <value>http://localhost:8080/api/Permission</value>
        </setting>
    </MyService.Properties.Settings>
</applicationSettings>

如果我更改app.config以匹配所需的网址,则身份验证有效。所以我的关键问题是:我的代码如何命令生成的客户端切换到不同的Web服务实例,而不编辑app.config并重新启动?

有关更多背景信息,当我将服务代码移动到另一台机器时,Wireshark显示以下序列:

  1. 为客户提供服务:

     HTTP/1.1 100 Continue\r\n
    
  2. 客户服务:

     POST /api/Permission HTTP/1.1
     User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 4.0.30319.225)
     VsDebuggerCausalityData: uIDPo8B4pxEyITVOlb6i18R2juMAAAAACwClY0YyykuVhoiZKG7oEPZ1kukkB6NLnxx6RVnHjT8ACQAA
     Content-Type: text/xml; charset=utf-8
     SOAPAction: ""
     Host: xxxxxx:8080
     Content-Length: 307
     Expect: 100-continue
    
  3. 为客户提供服务:

     HTTP/1.1 401 Unauthorized
     Content-Length: 0
     content-type: text/xml; charset=utf-8
     Expect: 100-continue
     Host: xxx:8080
     SOAPAction: ""
     User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 4.0.30319.225)
     VsDebuggerCausalityData: uIDPo8B4pxEyITVOlb6i18R2juMAAAAACwClY0YyykuVhoiZKG7oEPZ1kukkB6NLnxx6RVnHjT8ACQAA
     WWW-Authenticate: Basic realm=realm
     Server: Jetty(6.1.25)
    
  4. 客户端应该在添加基本身份验证标头的情况下重复POST,而是停止。

1 个答案:

答案 0 :(得分:0)

我找到了答案。主机名localhost在Web引用中是神奇的。生成的代码内部存在此函数:

    private bool IsLocalFileSystemWebService(string url) {
        if (((url == null) 
                    || (url == string.Empty))) {
            return false;
        }
        System.Uri wsUri = new System.Uri(url);
        if (((wsUri.Port >= 1024) 
                    && (string.Compare(wsUri.Host, "localHost", System.StringComparison.OrdinalIgnoreCase) == 0))) {
            return true;
        }
        return false;
    }
}

通过将我的app.config更改为默认值127.0.0.1,我绕过了本地Web服务身份验证的特殊行为。

这个故事的寓意:在针对本地服务实例开发Web引用客户端时,不要在URL中使用localhost