autenticacion - Conéctese con WCF a un servicio web autenticado con nombre de usuario/contraseña
autenticacion wcf c# (3)
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 tengo que cambiar de basicHttpBinding a wsHttpBinding o customBinding para poder agregar los elementos de autenticación, pero realmente no lo entiendo. ¿Alguien podría dar algún consejo rápido o algún enlace útil que diga cómo hacerlo?
EDITAR:
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. Se espera un URI ''https''
Ni siquiera sé si este es el camino correcto a seguir ...
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 utilizando 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.
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 pude usar el enlace por defecto 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
lugar de https
. Esto es necesario para probar entornos como el que estoy usando. Más adelante, obviamente, preferirás https
para enviar 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();
Tuve el mismo problema y probé la solución anterior. De alguna manera, esto no me funcionó. Seguí recibiendo el mensaje "No se encontró el encabezado WS-Security"
Después de un largo tiempo de pruebas e intentos, logro que funcionara. ¡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>