VB.NET 中的 SOAP 请求认证

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22968018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 17:19:44  来源:igfitidea点击:

SOAP request authentication in VB.NET

vb.netauthenticationsoap

提问by BrotherBarnabas

I'm trying to write a SOAP request to a 3rd party web service in VB. I've added a service reference which automatically added the following to the web.config:

我正在尝试在 VB 中向第 3 方 Web 服务写入 SOAP 请求。我添加了一个服务引用,它自动将以下内容添加到 web.config:

<basicHttpBinding>
        <binding name="Soap11">
          <security mode="None">
            <transport clientCredentialType="None" proxyCredentialType="None"
              realm="" />
            <message clientCredentialType="UserName" algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>

Now I have to write the following request:

现在我必须编写以下请求:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Header>
       <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
           <wsse:UsernameToken>
               <wsse:Username>username</wsse:Username>
               <wsse:Password>password</wsse:Password>
           </wsse:UsernameToken>
       </wsse:Security>
   </soapenv:Header>
   <soapenv:Body>
      <sch:Request>
      </sch:Request>
   </soapenv:Body>
</soapenv:Envelope>

I don't have a clue what to do next. I don't know how to provide the authentification details. All I've done is the following:

我不知道接下来要做什么。我不知道如何提供身份验证详细信息。我所做的一切如下:

    Dim myClient As New MyServiceReference.Client
    Dim myRequest As New MyServiceReference.Request
    Dim myResponse As New MyServiceReference.Response

    myClient.ClientCredentials.UserName.UserName = "Bob"
    myClient.ClientCredentials.UserName.Password = "Dole21"

    myResponse = myClient.Lookup(myRequest)

Obviously, not a lot. This has produced the following (according to fiddler).

显然,不是很多。这产生了以下内容(根据提琴手)。

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Lookup xmlns="http://example.com/schemas"/></s:Body></s:Envelope>

Any help would be greatly appreciated. How do I add the authentication headers to the SOAP request? I've tried changing

任何帮助将不胜感激。如何将身份验证标头添加到 SOAP 请求?我试过改变

security mode="Transport"

安全模式=“运输”

but it throws up a "The provided URI scheme 'http' is invalid; expected 'https'." error.

但它会抛出“提供的 URI 方案‘http’无效;预期为‘https’。” 错误。

回答by BrotherBarnabas

I managed to do it after a couple of weeks of trial and error. It's actually answered quite well hereexcept it's presented slightly convolutedly.

经过几周的反复试验,我设法做到了。它实际上在这里得到了很好的回答只是它的呈现方式有点令人费解。

Before I give the code I think a few words of advice for those starting out with SOAP requests in .NET:

在我给出代码之前,我想对那些开始使用 .NET 中的 SOAP 请求的人提出一些建议:

  • Avoid asmx and "web service" solutions when looking up solutions. asmx is legacy technology.
  • Download SoapUI. It's an open source soap testing tool.
  • Get Fiddler to log HTTP(S) traffic between your computer and the third party web service.
  • 在查找解决方案时避免使用 asmx 和“Web 服务”解决方案。asmx 是传统技术。
  • 下载 SoapUI。这是一个开源的肥皂测试工具。
  • 让 Fiddler 记录您的计算机和第三方 Web 服务之间的 HTTP(S) 流量。

Ok, so here's the code:

好的,这是代码:

    Dim myRequest As New ServiceReference1.LookupRequest
    Dim myResponse As New ServiceReference1.LookupResponse
    Dim address As New EndpointAddress("https://example.com/Service")

    Dim binding = New BasicHttpBinding(BasicHttpSecurityMode.TransportWithMessageCredential)
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None
    binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName

    Dim myClient As New ServiceReference1.Client(binding, address)
    myClient.ClientCredentials.UserName.UserName = "username"
    myClient.ClientCredentials.UserName.Password = "password"

    myResponse = myClient.Lookup(myRequest)

Then , you need to change your web.config to include

然后,您需要更改您的 web.config 以包含

<client>
     <endpoint ...>
            <headers>
                <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                    <wsse:UsernameToken>
                        <wsse:Username>USERNAME</wsse:Username>
                        <wsse:Password>PASSWORD</wsse:Password>
                    </wsse:UsernameToken>
                </wsse:Security>
            </headers>
     </endpoint>
 </client> 

When I ran the client it produced a (more verbose) SOAP request with the client credentials in the header which communicated with the web service:

当我运行客户端时,它生成了一个(更详细的)SOAP 请求,其中包含与 Web 服务通信的标头中的客户端凭据:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
   <s:Header>
      <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT</a:Action>
      <a:MessageID>urn:uuid:979816ec-0f1e-4052-a4e6-2449805178e2</a:MessageID>
      <a:ReplyTo>
         <a:Address>http://www.w3.org/2005/08/addressing/anonymous</a:Address>
      </a:ReplyTo>
      <a:To s:mustUnderstand="1">https://example.com/Service</a:To>
      <o:Security xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" s:mustUnderstand="1">
         <u:Timestamp u:Id="_0">
            <u:Created>2014-04-24T14:44:59.601Z</u:Created>
            <u:Expires>2014-04-24T14:49:59.601Z</u:Expires>
         </u:Timestamp>
         <o:UsernameToken u:Id="uuid-7c02f0c6-107d-45ac-b682-f0462211da21-3">
            <o:Username>username</o:Username>
            <o:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">password</o:Password>
         </o:UsernameToken>
      </o:Security>
   </s:Header>
   <s:Body>
      <t:RequestSecurityToken xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
         <t:TokenType>http://schemas.xmlsoap.org/ws/2005/02/sc/sct</t:TokenType>
         <t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
         <t:Entropy>
            <t:BinarySecret u:Id="uuid-45689ab6-30d3-4db6-a08e-99179e0dc65f-3" Type="http://schemas.xmlsoap.org/ws/2005/02/trust/Nonce">fQHEdTa+AGk8uAH5xbUkP+kfNkoTdEl5uwpWOf8QFug=</t:BinarySecret>
         </t:Entropy>
         <t:KeySize>256</t:KeySize>
      </t:RequestSecurityToken>
   </s:Body>
</s:Envelope>

回答by cgicgi

If your service client supports the constructor new ServiceReference.Client(endpointConfigurationByName As String)then you can configure all stuff within the application config:

如果您的服务客户端支持构造函数,new ServiceReference.Client(endpointConfigurationByName As String)那么您可以在应用程序配置中配置所有内容:

<client>
 <endpoint address="http://someserver", binding="Soap11", name="myService">
        <headers>
            <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
                <wsse:UsernameToken>
                    <wsse:Username>USERNAME</wsse:Username>
                    <wsse:Password>PASSWORD</wsse:Password>
                </wsse:UsernameToken>
            </wsse:Security>
        </headers>
 </endpoint>

After doing that you can create a new Client instance providing the configuration name:

完成后,您可以创建一个提供配置名称的新客户端实例:

Dim myClient As New ServiceReference1.Client("myService")

Dim myClient As New ServiceReference1.Client("myService")

whenever myClientsends a SOAP request, it will send the configured header along with it.

每当myClient发送 SOAP 请求时,它都会随同发送配置的标头。

You can have more than one endpoint in your configuration to support several instances/stages

您可以在配置中拥有多个端点以支持多个实例/阶段