2012-01-12 14 views
5

Sto tentando di accedere a un servizio Web di terzi che richiede per creare un'intestazione di sicurezza che trasmetta informazioni temporali, nome utente e password. Ho setacciato il web per esempi di lavoro e ho provato numerosi modi. Sto cercando di farlo con ciò che è integrato in Java 6. Non sono sicuro di cosa sto facendo male. Dopo aver generato le mie classi client del servizio Web dal WSDL, ho creato il Gestore di seguito.com.sun.xml.ws.message.saaj.SAAJHeader non può essere lanciato su 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; 
    } 
} 

Poi, ho codificato il mio programma di test per fissare il conduttore e provare a chiamare il servizio 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()); 
} 
} 

Quando eseguo questo, ottengo il seguente errore sulla linea di cui faccio 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) 

Ogni approccio cerco finisce nello stesso punto. Come faccio a evitare questo? Non riesco a capire come creare SecurityHeader da inserire nell'intestazione. Qualsiasi aiuto sarebbe molto apprezzato. Un esempio funzionante sarebbe fantastico.

Grazie!

risposta

1

Quando stavo risolvendo un problema simile, this thread really mi ha aiutato.

Il problema è quando si dispone di librerie Metro (stack WS Oracle) su classpath, vengono rilevate automaticamente e incluse nell'elaborazione WS. Una funzionalità è l'autenticazione trasparente/la gestione della sicurezza, quando la politica dell'endpoint è presente in WSDL. Purtroppo questa gestione della sicurezza non è

Non è stato possibile modificare il WSDL. La soluzione per me stava rimuovendo il JAR indesiderato (wsit-rt) dal classpath.

0

Vecchia domanda, ma al momento avevo lo stesso problema. La soluzione era rimuovere le intestazioni di sicurezza aggiuntive che avevo incluso manualmente. Quindi, se si incontra questo problema, controlla se ci sono gestori (SOAPHandler) che scrivono qualsiasi intestazione nella tua parte di intestazione del messaggio soap <Security>.

Problemi correlati