Connect with WCF to a WebService authenticated with username/password

核能气质少年 提交于 2019-12-03 03:49:37

问题


I created a proxy of a Web Service with Visual Studio 2008, and it created for me the following entry in the app.config:

<system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="MyNameHandlerSoapBinding" closeTimeout="00:01:00"
                    openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
          <endpoint address="http://www.***/***/***"
              binding="basicHttpBinding" bindingConfiguration="MyNameHandlerSoapBinding"
              contract="***.MyNameHandler" name="MyName">
          </endpoint>
        </client>
    </system.serviceModel>

The webservice is has username/password authentication so I need to add it somewhere here.

I'm a bit lost in the sea of WCF documentation, I think I have to change from basicHttpBinding to wsHttpBinding or customBinding to be able to add the authentication elements, but I don't really understand it. Could anybody give any quick tip or any useful link that says how to do so?

EDIT:

I changed the security section to:

<security mode="Transport">
    <transport clientCredentialType="Basic" proxyCredentialType="None"
         realm="" />
</security>

and added in the code:

ws.ClientCredentials.UserName.UserName = "";
ws.ClientCredentials.UserName.Password = "";

Now it seems it might be using the credentials but it's giving me the error:

the provided URI scheme 'http' is invalid URI expected 'https'

I don't even know if this is the right way to go...


回答1:


I post here the solution for future readers:

<system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="MyHandlerSoapBinding" closeTimeout="00:01:00"
            openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
            allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
            messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
            useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
              maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="TransportCredentialOnly">
            <transport clientCredentialType="Basic"  />
          </security>
        </binding>
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://www.***/***/***/MyHandler"
          binding="basicHttpBinding" bindingConfiguration="MyHandlerSoapBinding"
          contract="***.MyHandler" name="MyHandler">
      </endpoint>

    </client>
  </system.serviceModel>

In the end I could use the default basicHttpBinding. The only difference from the code posted in the question is the security node.

Also note the mode="TransportCredentialOnly" option, this allows you to send username/password using http instead of https. This is necessary for testing environments as the one I'm using. Later on obviously you'll prefer https to send your credentials.

Afterwards in code you'll enter your username/password:

var ws = new ***.MyHandlerClient("MyHandler");
ws.ClientCredentials.UserName.UserName = "myUsername";
ws.ClientCredentials.UserName.Password = "myPassword";
var result = ws.executeMyMethod();



回答2:


The error message is right. WCF will not allow transport of usernames and passwords over an unprotected protocol. Your web service must be using HTTPS (with the attendant SSL certificate)

Once you have an SSL certificate you have two options on how the credentials are sent, transport or security and multiple options for the type of credential. MSDN has a good guide to all of the various options.




回答3:


I had the same problem and tried the solution above Somehow this didn't work for me I was keep getting the message "No WS-Security header found"

After a long time of testing and trying I manage to get it work I added the header code in the client as below and then it works!

<client>
    <endpoint address="http://your.service.com" binding="basicHttpBinding" bindingConfiguration="XXXBinding" contract="contract.XXX" name="XXXPort">
        <headers xmlns:wsse="http://your.xsd">
            <wsse:Security mustUnderstand="1">
                <wsse:UsernameToken>
                    <tenant>XXX</tenant>
                    <wsse:Username>XXX</wsse:Username>
                    <wsse:Password Type="http://www.xxxx.com/wss#PasswordText">XXX</wsse:Password>
                </wsse:UsernameToken>
            </wsse:Security>
        </headers>
    </endpoint>
</client>


来源:https://stackoverflow.com/questions/806007/connect-with-wcf-to-a-webservice-authenticated-with-username-password

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!