2010-01-26 56 views
7

He creado con éxito un cliente WS que funciona correctamente cuando NO uso la autenticación.Agregando SOAP: HEADER nombre de usuario y contraseña con WSE 3.0

Sin embargo, el servidor (WebSphere) ahora requiere agregar un token de nombre de usuario de seguridad ws, y estoy teniendo dificultades para hacerlo. El mensaje SOAP resultante se supone que debe ser algo como esto:

<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 el SDK de Microsoft WSE 3.0 y ha añadido una referencia a la DLL en mi proyecto de Visual Studio 2005.

Ahora tengo acceso a los espacios de nombres de Microsoft.Web.Services3. *, Pero actualmente estoy perplejo sobre cómo proceder.

El código de cliente se ha generado automáticamente por un web de referencia, por lo que sólo hacer 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); 

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

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

Gracias!

Respuesta

10

Lo he conseguido, lamentablemente antes de leer wsanville's great answer.

Para ayudar a los demás, les dejo todos los pasos que tenía que hacer para que funcione con Visual Studio 2005:

  • Instalar WSE 3.0, elija personalizada y seleccione todo
  • Leer Implementing direct authentication with username token in WSE 3.0 de sugerencias
  • Reinicie Visual Studio 2005, ahora haga clic derecho en su proyecto en el explorador de soluciones, y debe tener un WSE Settings 3.0 elemento del menú y usar eso si lo desea.
  • Actualice sus referencias web, esto debería crear una nueva clase proxy de servicio web HTTP, con un nombre diferente, p. Ej. 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ó con este aspecto:

FooBarHttpServiceWse wse = new FooBarHttpServiceWse(); 

wse.SetClientCredential(new UsernameToken(
    "username", 
    "password", 
    PasswordOption.SendPlainText)); 

wse.SetPolicy(new FooBarPolicy()); 
wse.CallSomeServerFunction(yourRequest) 

he creado 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()); 
    } 
} 

Por último, el servidor WebSphere respondió que Un encabezado requerido abarcando un Mensaje propiedad de direccionamiento es no presente, e inspeccionando el mensaje saliente (usando la herramienta agradable Fiddler) Vi ​​que la falla SOAP del servidor indicaba que faltaba el encabezado Acción.

me trataron en vano de establecer el elemento wsa:Action a mí mismo:

using Microsoft.Web.Services3.Addressing; 

// ... 

wse.RequestSoapContext.Addressing.Action = new Action("CallSomeServerFunction"); 

El problema era que, incluso si fijo una acción, cuando fue enviado a través del cable, que estaba vacío. Resultó que tenía que abrir la clase de proxy WSE y editar un atributo existe:

[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ó muy bien.

12

Asegúrate de que tu clase proxy hereda 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 interruptor /type:webClient.

entonces 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 he hecho en el pasado para obtener WSE3.0 ir en Studio 2008. Espero que ayude.

+0

¡Gracias, esto fue muy útil! – csl

+0

+1 muy útil. Tenía proxy de generación de problemas usando WseWsdl3.exe en VS2010, esto se solucionó al agregar una entrada en el registro. Agregue una clave de cadena llamada "sdkInstallRootv2.0" en HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ .NETFramework \ con el valor "C: \ Archivos de programa \ Microsoft SDKs \ Windows \ v6.0A" – Siva

Cuestiones relacionadas