Conéctese con WCF a una autenticación de servicio web con nombre de usuario / contraseña

StackOverflow https://stackoverflow.com/questions/806007

Pregunta

Creé un proxy de un servicio web con Visual Studio 2008, y me creó la siguiente entrada en el archivo 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>

El servicio web tiene autenticación de nombre de usuario / contraseña, así que necesito agregarlo en algún lugar aquí.

Estoy un poco perdido en el mar de la documentación de WCF, creo que debo cambiar de basicHttpBinding a wsHttpBinding o customBinding para poder agregar los elementos de autenticación, pero realmente no lo entiendo. ¿Alguien podría dar una sugerencia rápida o algún enlace útil que diga cómo hacerlo?

EDIT:

Cambié la sección de seguridad a:

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

y añadido en el código:

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

Ahora parece que podría estar usando las credenciales, pero me está dando el error:

el esquema de URI proporcionado 'http' no es válido URI esperado 'https'

Ni siquiera sé si este es el camino correcto ...

¿Fue útil?

Solución

Publico aquí la solución para futuros lectores:

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

Al final podría usar el enlace por defecto de BasicHttpBinding. La única diferencia con el código publicado en la pregunta es el nodo de seguridad .

También tenga en cuenta la opción mode = " TransportCredentialOnly " , esto le permite enviar un nombre de usuario / contraseña usando http en lugar de https . Esto es necesario para probar entornos como el que estoy usando. Más adelante, obviamente, preferirás que https envíe tus credenciales.

Luego, en el código, ingresará su nombre de usuario / contraseña:

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

Otros consejos

El mensaje de error es correcto. WCF no permitirá el transporte de nombres de usuario y contraseñas sobre un protocolo desprotegido. Su servicio web debe estar usando HTTPS (con el certificado SSL del asistente)

Una vez que tenga un certificado SSL, tiene dos opciones sobre cómo se envían las credenciales, el transporte o la seguridad, y múltiples opciones para el tipo de credencial. MSDN tiene una buena guía para todas las diversas opciones.

Tuve el mismo problema y probé la solución anterior De alguna manera esto no me funcionó Recibí el mensaje " No se encontró el encabezado WS-Security "

Después de mucho tiempo de probar y probar, logro que funcione ¡Agregué el código del encabezado en el cliente como se muestra a continuación y luego funciona!

<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>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top