2

这是我在这里的第一篇文章,所以请耐心等待。我有一个 WSDL,我使用 SOAP UI 来生成 Java 客户端。我将客户端插入测试项目并使用客户端访问 Web 服务。Web 服务需要安全标头(这不是 wsdl 策略的一部分),因此我必须使用处理程序才能将安全标头添加到创建的 SOAP 信封中。在运行我的程序时,它会引发以下错误......当我通过 SOAP UI 运行相同的 SOAP 请求时,它似乎处理得很好。我注意到的另一件有趣的事情是,虽然我在客户端处理它之后(在抛出错误之后)在 SOAP UI 中运行相同的请求(包括安全标头的随机数),但它似乎仍然处理得很好。但是当我尝试在 SOAP UI 中运行相同的请求两次时,它会引发一个异常,即不能多次使用相同的 Nonce 值(这是预期的行为)。这让我认为运行我的客户端后生成的错误甚至没有到达运行 Web 服务的服务器,否则 nonce 将被缓存在那里,我将无法在 SOAP UI 中运行它。我在 Error 块下面附加了我的 Handler 类方法。我倾向于相信安全标头很好,因为消息在 SOAP UI 中处理得很好。任何帮助表示赞赏。这让我认为运行我的客户端后生成的错误甚至没有到达运行 Web 服务的服务器,否则 nonce 将被缓存在那里,我将无法在 SOAP UI 中运行它。我在 Error 块下面附加了我的 Handler 类方法。我倾向于相信安全标头很好,因为消息在 SOAP UI 中处理得很好。任何帮助表示赞赏。这让我认为运行我的客户端后生成的错误甚至没有到达运行 Web 服务的服务器,否则 nonce 将被缓存在那里,我将无法在 SOAP UI 中运行它。我在 Error 块下面附加了我的 Handler 类方法。我倾向于相信安全标头很好,因为消息在 SOAP UI 中处理得很好。任何帮助表示赞赏。

javax.xml.ws.soap.SOAPFaultException:必须理解标头:[{ http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd}Security] 在 com.sun.xml.internal.ws.protocol.soap.ClientMUTube.processResponse(Unknown Source) 的 com.sun.xml.internal.ws.protocol.soap.MUTube.createMUSOAPFaultException(Unknown Source) 不理解在 com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Unknown Source) 在 com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Unknown Source) 在 com.sun.xml .internal.ws.api.pipe.Fiber.doRun(Unknown Source) at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Unknown Source) at com.sun.xml.internal.ws.client .Stub.process(Unknown Source) at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(Unknown Source) at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(Unknown来源)在 com.sun.xml.internal.ws.client.sei.SEIStub 的 com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(未知来源)。在 com.sun.proxy.$Proxy34.searchDemographics(Unknown Source) 在 com.douglas.client.Client.main(Client.java:50) 调用(未知来源)

公共布尔句柄消息(SOAPMessageContext smc){

    Boolean outboundProperty = (Boolean) smc.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);

    if (outboundProperty.booleanValue()) {

        SOAPMessage message = smc.getMessage();


        try {
             //message.writeTo(System.out);
             //System.out.println("\n");
            String nonce = getNonce();
            String password1 = "password01";
            SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
            String messageCrTime = ft.format(new Date());
            String passwordDigest = SHAsum(nonce, password1, messageCrTime);

            SOAPEnvelope envelope = smc.getMessage().getSOAPPart().getEnvelope();
            SOAPHeader header = envelope.addHeader();

            SOAPElement security =
                    header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

            SOAPElement usernameToken =
                    security.addChildElement("UsernameToken", "wsse");
            usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

            SOAPElement username =
                    usernameToken.addChildElement("Username", "wsse");
            username.addTextNode("USERNAME");

            SOAPElement password =
                    usernameToken.addChildElement("Password", "wsse");
            password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest");
           password.addTextNode(passwordDigest);

           SOAPElement nonceElem =
                   usernameToken.addChildElement("Nonce", "wsse");
           //password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
           nonceElem.addTextNode(Base64.encodeBytes(nonce.getBytes()));

           SOAPElement created =
                   usernameToken.addChildElement("Created", "wsu");
           //password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
           created.addTextNode(messageCrTime);

            //Print out the outbound SOAP message to System.out
            message.writeTo(System.out);
            System.out.println("");

        } catch (Exception e) {
            e.printStackTrace();
        }

    } else {
        try {

            //This handler does nothing with the response from the Web Service so
            //we just print out the SOAP message.
            SOAPMessage message = smc.getMessage();
            message.writeTo(System.out);
            System.out.println("");

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


    return outboundProperty;

}
4

1 回答 1

1

找到了解决方案。客户端抛出这些错误的原因是,当它从 Web 服务接收到响应时,mustUnderstand 设置为“1”。现在,由于 WSDL 策略不包括安全组件,客户端不知道如何处理它。解决方法是在 HeaderHandler.java 类中添加以下方法。

 public Set getHeaders() {
        final QName securityHeader = new QName(  
                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd",  
                "Security", "wsse");  

        final HashSet<QName> headers = new HashSet<QName>();  
        headers.add(securityHeader);  
        return headers;  

        //throw new UnsupportedOperationException("Not supported yet.");
    }
于 2014-04-09T19:16:28.283 回答