2

我在 Visual Studio 2010 中创建了一个客户端来使用 Web 服务,使用 WSDL 自动创建代理类。在开发环境中,没关系,工作正常,因为它不需要在这个环境中进行身份验证。

我遇到的问题是该服务在测试和生产(真正的工作)环境中具有身份验证。WSDL 没有描述它。它们都使用相同的开发环境的 WSDL。

如果我尝试在测试环境中使用浏览器查看 WSDL,将“?WSDL”放在端点地址之后,它不会像开发环境一样返回 WSDL。它返回一个身份验证表单,一个普通的 html,并在通知用户和密码后返回 WSDL(与开发环境相同)。

我制作了这样的 app.config 绑定配置:

<wsHttpBinding>
          <binding name="WebServiceSoapAuth" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="true" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"  maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Mtom" textEncoding="utf-8"  useDefaultWebProxy="true">
            <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
            <security mode="None">
              <transport clientCredentialType="Basic" proxyCredentialType="None" realm=""/>
              <message clientCredentialType="UserName" algorithmSuite="Default"/>
            </security>
          </binding>  
        </wsHttpBinding>

如果我使用由 VS 2010 自动创建的 basicHttpBinding(在开发环境中工作),我的服务使用者会返回“无法验证或授权安全令牌”,如预期的那样。

更改为 wsHttpBinding(上面的代码),它返回“响应消息的内容类型 text/html;charset=utf-8 与绑定的内容类型(application/soap+xml;charset=utf-8)不匹配。如果使用自定义编码器,请确保正确实现 IsContentTypeSupported 方法。响应的前 1024 个字节为:" 后跟表单身份验证 html 代码。

我不知道我必须使用什么绑定配置。

我使用 SoapUI 测试了服务消耗,并且在两种环境中都可以工作,并且它使用身份验证工作,我只需要通知用户、密码并且需要将“WSS-Password Type”请求配置更改为“PasswordText”(只通知用户和密码我有“无法验证或授权安全令牌”返回)。

我很抱歉我的英语不好,我不流利,如果我在问题类别或格式方面犯了一些错误。

编辑:我无法在具有身份验证的环境中可视化 wsdl 文件。当我在地址后面加上?WSDL 时,它给了我一个验证表格(来自 Ensemble InterSystems 软件的表格),而不是 wsdl。

我使用 SoapUI 测试了服务消耗,并且在两种环境中都可以工作,并且它使用身份验证工作,我只需要通知用户、密码并且需要将“WSS-Password Type”请求配置更改为“PasswordText”(只通知用户和密码我有“无法验证或授权安全令牌”返回)。

为什么它不能使用自动生成的类,只是通知用户并通过?有人有想法吗?什么绑定配置相当于 SoapUI 配置的“WSS-Password Type”等于“PasswordText”?(我想这就是为什么我只通知用户和密码它不起作用的关键)

编辑 2:soap 消息的正文没问题。我在制作标题时遇到了麻烦。它可能是这样的:

<soapenv:Header> <wsse:Security soapenv:mustUnderstand="1" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <wsse:UsernameToken wsu:Id="UsernameToken-5"> <wsse:Username>USERNAME</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">PASSWORD</wsse:Password> <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">E1XqZ2v8IDaTBzfF3j/TOA==</wsse:Nonce> <wsu:Created>2012-12-21T12:24:23.380Z</wsu:Created> </wsse:UsernameToken> </wsse:Security> </soapenv:Header>

正如我所说,我无法访问服务器,它在我的客户那里。我只知道它是用java制作的。

4

2 回答 2

1

首先,您应该检查客户端是否使用与服务器相同的绑定。例如,如果您的客户端使用 wsHttpBinding 但指向使用 basicHttpBinding 的服务,那么它几乎在所有情况下都会出错。

其次,您将安全模式设置为 none,这意味着它不会使用传输或消息安全,我认为这不是您想要的。如果你想使用

<transport clientCredentialType="Basic" proxyCredentialType="None" realm=""/>

<message clientCredentialType="UserName" algorithmSuite="Default"/>

那么您应该将安全模式设置为 TransportWithMessageCredential。这将使用 HTTPS 的传输安全性和用于身份验证的消息安全性。其他安全模式将仅使用其中一种 clientCredentialType(传输将使用传输 clientCredentialType,而消息将使用消息 clientCredentialType)。

希望这可以帮助 :)。

于 2012-12-14T18:14:06.950 回答
0

我必须手动创建一个 http webrequest,并且必须手动创建 xml 并将其传递给请求。postData 变量来自手动创建的 xml。

    Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
    Dim req As HttpWebRequest = DirectCast(WebRequest.Create("http://site.customer/ens/qa/customer.bs.ws.service.cls"), HttpWebRequest)
    req.Method() = "POST"
    req.UserAgent = "Apache-HttpClient/4.1.1 (java 1.5)"
    req.ContentType = "text/xml;charset=UTF-8"
    req.ContentLength = byteArray.Length
    req.KeepAlive = True
    req.Host = "site.customer"
    req.AutomaticDecompression = 3
    req.Headers.Add("SOAPAction", "http://www.tempuri.org/customer.bs.ws.service.function")
于 2013-01-04T16:54:15.737 回答