2012-01-12 32 views
5

Estoy intentando acceder a un servicio web de terceros que requiere para crear un encabezado de seguridad que transmita información de tiempo, nombre de usuario y contraseña. He buscado en la web ejemplos de trabajo y he intentado de varias maneras. Intento hacer esto con lo que está integrado en Java 6. No estoy seguro de lo que estoy haciendo mal. Después de generar mis clases de cliente del servicio web desde WSDL, creé el controlador a continuación.com.sun.xml.ws.message.saaj.SAAJHeader no se puede convertir a com.sun.xml.ws.security.opt.impl.outgoing.SecurityHeader

import java.util.Set; 
import java.util.TimeZone; 
import javax.xml.namespace.QName; 
import javax.xml.soap.Node; 
import javax.xml.soap.SOAPElement; 
import javax.xml.soap.SOAPEnvelope; 
import javax.xml.soap.SOAPFactory; 
import javax.xml.soap.SOAPHeader; 
import javax.xml.soap.SOAPMessage; 
import javax.xml.soap.Text; 
import javax.xml.ws.handler.MessageContext; 
import javax.xml.ws.handler.soap.SOAPHandler; 
import javax.xml.ws.handler.soap.SOAPMessageContext; 

public class MyHeaderHandler implements SOAPHandler<SOAPMessageContext> 
{ 
    public boolean handleMessage(SOAPMessageContext context) 
    { 
    String prefixUri = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-"; 
    String uri = prefixUri + "wssecurity-secext-1.0.xsd"; 
    String uta = prefixUri + "wssecurity-utility-1.0.xsd"; 
    String ta = prefixUri + "username-token-profile-1.0#PasswordText"; 
    Boolean isRequest = (Boolean)context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); 
    if(isRequest) 
    { 
     try 
     { 
     SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:dd.SSS'Z'"); 
     formatter.setTimeZone(TimeZone.getTimeZone("GMT")); 
     java.util.Date created = new java.util.Date(); 
     java.util.Date expires = new java.util.Date(created.getTime() + (5l * 60l * 1000l)); 
     SOAPMessage soapMsg = context.getMessage(); 
     SOAPEnvelope soapEnv = soapMsg.getSOAPPart().getEnvelope(); 
     SOAPHeader soapHeader = soapEnv.getHeader(); 
     if (soapHeader == null) 
      soapHeader = soapEnv.addHeader(); 
     SOAPFactory factory = SOAPFactory.newInstance(); 
     SOAPElement securityElem = factory.createElement("Security", "o", uri); 
     securityElem.addAttribute(QName.valueOf("s:mustUnderstand"), "0"); 
     SOAPElement timestampElem = factory.createElement("Timestamp", "u", uta); 
     timestampElem.addAttribute(QName.valueOf("xmlns:u"), uta); 
     timestampElem.addAttribute(QName.valueOf("Id"), "_0"); 
     SOAPElement elem = factory.createElement("Created", "u", uta); 
     elem.addTextNode(formatter.format(created)); 
     timestampElem.addChildElement(elem); 
     elem = factory.createElement("Expires", "u", uta); 
     elem.addTextNode(formatter.format(expires)); 
     timestampElem.addChildElement(elem); 
     securityElem.addChildElement(timestampElem); 
     SOAPElement usernameElem = factory.createElement("UsernameToken", "o", uri); 
     elem = factory.createElement("Username", "o", uri); 
     elem.addTextNode("xxxxx"); 
     usernameElem.addChildElement(elem); 
     elem = factory.createElement("Password", "o", uri); 
     elem.addTextNode("xxxxx"); 
     elem.addAttribute(QName.valueOf("Type"), ta); 
     usernameElem.addChildElement(elem); 
     securityElem.addChildElement(usernameElem); 
     soapHeader.addChildElement(securityElem); 
     } 
     catch(Exception e) 
     { 
     System.out.println("Handler error!!!! - " + e); 
     } 
    } 
    return true; 
    } 

public boolean handleFault(SOAPMessageContext context) 
    { 
    return true; 
    } 

public void close(MessageContext context) 
    { 
    } 

public Set<QName> getHeaders() 
    { 
    return null; 
    } 
} 

A continuación, codifiqué mi programa de prueba para adjuntar el controlador e intentar llamar al servicio web.

import java.util.ArrayList; 
import java.util.List; 
import javax.xml.namespace.QName; 
import javax.xml.ws.handler.Handler; 
import javax.xml.ws.handler.HandlerResolver; 
import javax.xml.ws.handler.PortInfo; 
import org.tempuri.ServiceName; 
import org.tempuri.IServiceName; 


public class test 
{ 
public static void main(String[] args) 
throws Exception 
{ 
    ServiceName service = new ServiceName(new URL("https://url.to.service/services/ServiceName.svc?wsdl"), new QName("http://org.tempuri/", "ServiceName")); 
    service.setHandlerResolver(new HandlerResolver() 
    { 
    public List<Handler> getHandlerChain(PortInfo portInfo) 
    { 
     List<Handler> handlerList = new ArrayList<Handler>(); 
     handlerList.add(new MyHeaderHandler()); 
     return handlerList; 
    } 
    }); 
    IServiceName binding = service.getBasicHttpBindingIServiceName(); 
    ArrayLiist results = binding.getMyData("my parm"); 
    System.out.println("Size: " + results.size()); 
} 
} 

Cuando ejecuto esto, me sale el siguiente error en la línea en la que hago binding.getMyData():

Exception in thread "main" java.lang.ClassCastException: com.sun.xml.ws.message.saaj.SAAJHeader cannot be cast to com.sun.xml.ws.security.opt.impl.outgoing.SecurityHeader 
at com.sun.xml.ws.security.opt.impl.JAXBFilterProcessingContext.setJAXWSMessage(JAXBFilterProcessingContext.java:140) 
at com.sun.xml.wss.jaxws.impl.SecurityPipeBase.secureOutboundMessage(SecurityPipeBase.java:389) 
at com.sun.xml.wss.jaxws.impl.SecurityClientPipe.process(SecurityClientPipe.java:196) 
at com.sun.xml.ws.api.pipe.helper.PipeAdapter.processRequest(PipeAdapter.java:115) 
at com.sun.xml.ws.api.pipe.Fiber.__doRun(Fiber.java:595) 
at com.sun.xml.ws.api.pipe.Fiber._doRun(Fiber.java:554) 
at com.sun.xml.ws.api.pipe.Fiber.doRun(Fiber.java:539) 
at com.sun.xml.ws.api.pipe.Fiber.runSync(Fiber.java:436) 
at com.sun.xml.ws.client.Stub.process(Stub.java:248) 
at com.sun.xml.ws.client.sei.SEIStub.doProcess(SEIStub.java:135) 
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:109) 
at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:89) 
at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:118) 
at $Proxy40.getM(Unknown Source) 
at test.main(test.java:30) 

Cada enfoque que intento termina en el mismo punto. ¿Cómo puedo evitar esto? No puedo encontrar la manera de crear SecurityHeader para colocar en el encabezado. Cualquier ayuda sería muy apreciada. Un ejemplo de trabajo sería genial.

Gracias!

Respuesta

1

Cuando estaba resolviendo un problema similar, this thread really me ayudó.

El problema es que cuando tienes bibliotecas de Metro (pila de WS de Oracle) en classpath, se detectan automáticamente y se incluyen en el procesamiento de WS. Una funcionalidad es el manejo transparente de autenticación/seguridad, cuando la política de punto final está presente en WSDL. Desafortunadamente este manejo de seguridad no es

No pude cambiar el WSDL. La solución para mí fue eliminar el JAR no deseado (wsit-rt) del classpath.

0

Pregunta anterior, pero ahora tenía el mismo problema. La solución fue eliminar encabezados de seguridad adicionales que había incluido manualmente. Por lo tanto, si se encuentra con este problema, verifique si tiene controladores (SOAPHandler) escribiendo encabezados en la parte del encabezado <Security> del mensaje de jabón.

Cuestiones relacionadas