2010-06-22 18 views
19

Tengo una línea de comando de la aplicación Java JAX-WS para probar una solicitud SOAP, pero el servidor espera que Password Type sea PasswordText y no sé cómo configurar esto. ..JAX-WS Tipo de contraseña PasswordText

el código es el siguiente manera:

@WebServiceRef 
private static final HelloService helloService = new HelloService(url, new QName(
     URL, "HelloService")); 

public static void main(final String... args) { 

    try { 
     final HelloPort helloPort = helloService.getHelloPort(); 
     final BindingProvider hB = ((BindingProvider) helloPort); 
     hB.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
            END_POINT_ADDRESS); 
     hB.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, 
            USERNAME); 
     hB.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, 
            PASSWORD); 
     ... 

he probado la solicitud utilizando SOAP-UI así que sé que está funcionando. Se agradecería cualquier ayuda para establecer el tipo de contraseña.

Gracias.

Respuesta

28

Eso configurará el nombre de usuario y la contraseña para la autenticación HTTP básica. Si lo has probado en SoapUI, supongo que el valor 'PasswordText' del que hablas es 'WSS-Password Type' en el panel de detalles de la solicitud. Eso establece la seguridad de WSS, no la seguridad de HTTP.

Con JAX-WS en Java6, debe conectar un manejador SOAP para inyectar WSS-Usertoken en el encabezado SOAP. Hay muchos detalles sobre esta red, pero no pude encontrar un solo enlace para publicar, así que aquí hay un código para ponerlo en marcha ...

Para agregar un controlador, necesita algo como:

final Binding binding = ((BindingProvider) servicePort).getBinding(); 
List<Handler> handlerList = binding.getHandlerChain(); 
if (handlerList == null) 
    handlerList = new ArrayList<Handler>(); 

handlerList.add(new SecurityHandler()); 
binding.setHandlerChain(handlerList); // <- important! 

A continuación, la clase SecurityHandler hará la escritura. Los manipuladores son cosas generales y reciben llamadas tanto para mensajes exitosos como para fallas, pero tal vez lo más importante sea que se llamen en ambas direcciones de mensajes - para la solicitud saliente y luego nuevamente para la respuesta entrante. Solo quieres gestionar los mensajes salientes. Por lo que tendrá algo como:

public final class SecurityHandler implements SOAPHandler<SOAPMessageContext> { 

    ... 

    @Override 
    public boolean handleMessage(final SOAPMessageContext msgCtx) { 

     // Indicator telling us which direction this message is going in 
     final Boolean outInd = (Boolean) msgCtx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 

     // Handler must only add security headers to outbound messages 
     if (outInd.booleanValue()) { 
      try { 
       // Get the SOAP Envelope 
       final SOAPEnvelope envelope = msgCtx.getMessage().getSOAPPart().getEnvelope(); 

       // Header may or may not exist yet 
       SOAPHeader header = envelope.getHeader(); 
       if (header == null) 
        header = envelope.addHeader(); 

       // Add WSS Usertoken Element Tree 
       final SOAPElement security = header.addChildElement("Security", "wsse", 
         "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); 
       final SOAPElement userToken = security.addChildElement("UsernameToken", "wsse"); 
       userToken.addChildElement("Username", "wsse").addTextNode("MyWSSUsername"); 
       userToken.addChildElement("Password", "wsse").addTextNode("MyWSSPassword"); 

      } catch (final Exception e) { 
       LOG.error(e); 
       return false; 
      } 
     } 
     return true; 
    } 

    ... 
    // Other required methods on interface need no guts 
} 

que he hecho algunas suposiciones aquí, pero espero que ponerlas a ir!

Saludos cordiales.

+1

Gracias. Esto funcionó perfectamente y su respuesta fue casi imposible de encontrar buscando en Google, así que permítanme agregar algunas palabras clave. JAX-WS WSSE – Jimmy2Times

+1

Al utilizar este código obtuve la siguiente excepción en el registro: 'com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl addChildElement SEVERE: SAAJ0101: el elemento principal de un SOAPBodyElement debe ser un SOAPBody'. – Vic

5

Si implementa la interfaz SOAPHandler, el método msgCtx.getMessage() representará todo el XML, y si está trabajando con archivos grandes, tendrá errores de falta de memoria. He probado con autenticación UsernameToken en el cliente JAX-WS y funciona:

String SECURITY_NS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; 
String PASSWORD_TYPE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"; 
String AUTH_PREFIX = "wss"; 

MyService service = new MyService(); 
MyServicePort port = service.getMyServicePort(); 

try { 
    SOAPFactory soapFactory = SOAPFactory.newInstance(); 
    SOAPElement security = soapFactory.createElement("Security", AUTH_PREFIX, SECURITY_NS); 
    SOAPElement uToken = soapFactory.createElement("UsernameToken", AUTH_PREFIX, SECURITY_NS); 
    SOAPElement username = soapFactory.createElement("Username", AUTH_PREFIX, SECURITY_NS); 
    username.addTextNode("username"); 

    SOAPElement pass = soapFactory.createElement("Password", AUTH_PREFIX, SECURITY_NS); 
    pass.addAttribute(new QName("Type"), PASSWORD_TYPE); 
    pass.addTextNode("password"); 

    uToken.addChildElement(username); 
    uToken.addChildElement(pass); 
    security.addChildElement(uToken); 

    Header header = Headers.create(security); 
    ((WSBindingProvider) port).setOutboundHeaders(header); 

    // now, call webservice 

} catch (SOAPException ex) { 
    ex.printStackTrace(); 
} 

Editar: debe agregar el "rt.jar" de JRE a la ruta de clase.

+0

Lo intento pero obtengo javax.xml.ws.WebServiceException: java.lang.ClassCastException: com.sun.xml.ws.message.DOMHeader no se puede convertir en com.sun.xml.ws.security.opt.impl. outgoing.SecurityHeader \t en com.sun.xml.wss.jaxws.impl.SecurityClientTube.processRequest (SecurityClientTube.java:250) \t en com.sun.xml.ws.api.pipe.Fiber .__ doRun (Fiber.java : 1063) – Steve

+0

Creo que está relacionado con tener el jar metro ws en el classpath, pero lo necesito – Steve

Cuestiones relacionadas