c# web-services ws-security wse3.0

c# - Agregar SOAP: HEADER nombre de usuario y contraseña con WSE 3.0



web-services ws-security (2)

He creado con éxito un cliente de WS que funciona correctamente cuando NO utiliza la autenticación.

Sin embargo, el servidor (WebSphere) ahora requiere agregar un token de nombre de usuario de ws-security, y estoy teniendo dificultades para hacerlo. El mensaje SOAP resultante se supone que debe verse más o menos así:

<soapenv:Envelope xmlns:ns="http://foo.bar/1.0" xmlns:ns1="http://www.witsml.org/schemas/140" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"> <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"> <wsse:UsernameToken wsu:Id="UsernameToken-2" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> <wsse:Username>foo</wsse:Username> <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">bar</wsse:Password> <wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">foooooobar==</wsse:Nonce> <wsu:Created>2010-01-25T13:09:24.860Z</wsu:Created> </wsse:UsernameToken> </wsse:Security> </soapenv:Header> <soapenv:Body> <ns:fooBar>...</ns:fooBar> </soapenv:Body>

He descargado e instalado WSE 3.0 SDK de Microsoft y he agregado una referencia a la DLL en mi proyecto de Visual Studio 2005.

Ahora tengo acceso a los espacios de nombres Microsoft.Web.Services3. *, Pero actualmente no sé cómo proceder.

El código del cliente ha sido generado automáticamente por una referencia web, por lo que solo realizo una pequeña cantidad de trabajo para enviar el mensaje al servidor no autenticado :

WS.FooResultHttpService ws = new WS.FooResultHttpService(); ws.Url = "http://foo.bar.baz"; ws.SendSomething(message);

Acabo de comenzar a investigar usando Microsoft.Web.Services3.Security.Tokens.UsernameTokenManager , pero hasta ahora no he podido poner en marcha nada.

Cualquier sugerencia sería muy apreciada, ya que parece que no puedo encontrar ninguna buena receta en la red.

¡Gracias!


Asegúrese de que su clase de proxy herede de Microsoft.Web.Services3.WebServicesClientProtocol .

Puede hacer esto cambiando la clase de proxy en sí o generándola a través de la línea de comando usando wsewsdl3.exe con el modificador /type:webClient .

A continuación, puede pasar las credenciales de esta manera:

using Microsoft.Web.Services3; using Microsoft.Web.Services3.Security.Tokens; using Microsoft.Web.Services3.Security; . . . WS.FooResultHttpService ws = new WS.FooResultHttpService(); ws.RequestSoapContext.Security.Tokens.Add(new UsernameToken("blah", "blah", PasswordOption.SendPlainText));

Esto es lo que hice en el pasado para obtener WSE3.0 en Studio 2008. Espero que eso ayude.


Lo conseguí trabajando, desafortunadamente antes de leer la gran respuesta de wsanville .

Para ayudar a otros, estoy publicando todos los pasos que necesitaba para que funcione con Visual Studio 2005:

  • Instale WSE 3.0 , elija personalizado y seleccione todo
  • Lea Implementación de autenticación directa con token de nombre de usuario en WSE 3.0 para obtener sugerencias
  • Vuelva a iniciar Visual Studio 2005, ahora haga clic con el botón derecho en su proyecto en el explorador de soluciones, y debería tener un elemento de menú de Configuración de WSE 3.0 y usarlo si lo desea.
  • Actualice sus referencias web, esto debería crear una nueva clase de proxy del servicio web HTTP, con un nombre diferente, por ejemplo, YourWsNameHttpServiceWse . Esto es esencialmente lo mismo que ejecutar wsewsdl3.exe
  • Utilice esta nueva clase, y debe tener acceso a los métodos y propiedades de WSE, como SetClientCredential .

Terminé haciendo casi todo en código, en lugar de confiar en los archivos de configuración que se crean con mi C # DLL. El código terminó pareciéndose a esto:

FooBarHttpServiceWse wse = new FooBarHttpServiceWse(); wse.SetClientCredential(new UsernameToken( "username", "password", PasswordOption.SendPlainText)); wse.SetPolicy(new FooBarPolicy()); wse.CallSomeServerFunction(yourRequest)

Creé mi propia política, que se veía así:

using Microsoft.Web.Services3.Design; // ... public class FooBarPolicy : Policy { public FooBarPolicy() { this.Assertions.Add(new UsernameOverTransportAssertion()); } }

Finalmente, el servidor de WebSphere respondió que un encabezado requerido que representa una propiedad de direccionamiento de mensaje no está presente , e inspeccionando el mensaje de salida (usando la linda herramienta Fiddler ) Vi que la falla de SOAP del servidor indicaba que faltaba el encabezado de Acción.

Traté en vano de configurar el elemento de wsa:Action :

using Microsoft.Web.Services3.Addressing; // ... wse.RequestSoapContext.Addressing.Action = new Action("CallSomeServerFunction");

El problema era que incluso si establecí una acción, cuando se envió por el cable, estaba vacía. Resultó que tuve que abrir la clase de proxy de WSE y editar un atributo allí:

[System.Web.Services.Protocols.SoapDocumentMethodAttribute( "---Edit this to set wsa:Action---", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Bare)] // ... public SomeServerFunction(...)

Después de eso, todo salió bien.