Clicky

Greetings to all,

I have been developing a Client in netbeans 6.7.1 for a web service using Oasis UsernameToken security, I managed to create the client and the classes from the tool and  the consumer method goes like this


and returns the following Exception:

Error: javax.xml.ws.soap.SOAPFaultException: Security requirements are not satisfied because the security header is not present in the incoming message


I found an example on how to create a Header Handler and I implemented it, but for some reason the function is not called properly and fails to attach the header.


The header has to be something like this:



So my questions are:

Does anybody know a way to successfully append a security header to an outgoing SOAP request?

is there an interface for doing such thing? (in my research i found that a plugin for Glassfish called Access Manager that did all this handling,  but it has been removed for some reason)

What is the proper way to develop a Webservice Client with UsernameToken authentication?

Thanks in advance


1:
2:
3:
4:
5:
6:
7:
8:
<wsse:Security xmlns:wsse=$"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd$">" +
                <wsse:UsernameToken xmlns:wsu=$"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd$">" +
                      <wsse:Username>" + user + "</wsse:Username>" +
                      <wsse:Password Type=$"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest$">password</wsse:Password>" +
                      <wsse:Nonce>" + noncepack + "</wsse:Nonce>" +
                      <wsu:Created>" + sdf.format(c1.getTime()) + "</wsu:Created>" +
              </wsse:UsernameToken>" +
          </wsse:Security>"
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
try { // Call Web Service Operation
            xxxxxx.Service service = new xxxxxxx.Service();

            xxxxx.ServiceSoap port = service.getServiceSoap();
            // TODO initialize WS operation arguments here
            java.lang.String subscriberID = "ClientID";
            java.lang.String identity = "Client Identity";
            // TODO process result here
            xxxxxxx.SubscriberRetrieve result = port.retrieveSubscriber(subscriberID, identity);
            info("Result = " + result);
        } catch (Exception ex) {
            error("Error: " + ex);
            // TODO handle custom exceptions here
        }

asked 04/18/2011 03:44

Risk_TI's gravatar image

Risk_TI ♦♦


9 Answers:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
/*

* This is where you can add your custom SOAP headers if required.

* Example: WS-Security Username token etc, below shown is a custom

* Authentication header(not required for this service). just added

* for example

*/

SOAPHeader soapHeader = soapMessage.getSOAPHeader();

Name userName = soapEnvelope.createName("username", "",

"http://MyUserCredentials");

SOAPHeaderElement userNameElement = soapHeader

.addHeaderElement(userName);

userNameElement.setValue("SHIVA");

Name password = soapEnvelope.createName("password", "",

"http://MyUserCredentials");

SOAPHeaderElement passwordElement = soapHeader

.addHeaderElement(password);

passwordElement.setValue("OMMMMMMMMMMM");

//Constructing SOAP Body.

SOAPBody soapBody = soapMessage.getSOAPBody();


This is a snippet from my blog, complete article here : http://soa2world.blogspot.com/2009/05/direct-web-service-client-using-java.html
link
shivaspk's gravatar image

shivaspk

thanks shivaspk for your answer, I just want to ask a couple of questions more, that works for a password digest with nonce and timestamp? and once the hearder is create how do I append it to the outgoing SOAP message that JAX-WS sends?

Namaste
link
Risk_TI's gravatar image

Risk_TI

You can do it as shown here: http://www.java.net/node/712962

Ya this approach can work for both nonce and timestamp. A nonce is a random value that the sender creates to include in each UsernameToken that it sends. A creation time is added to combine nonces to a "freshness" time period.
link
shivaspk's gravatar image

shivaspk

ok I'm trying to implement the second link you provided me, if successful I give you the points, thank you so much for the response
link
Risk_TI's gravatar image

Risk_TI

I have come to something like this
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
try { // Call Web Service Operation
            com.comverse_in.prepaid.ccws.Service service = 
            new com.comverse_in.prepaid.ccws.Service();
            com.comverse_in.prepaid.ccws.ServiceSoap port = service.getServiceSoap();
//             TODO initialize WS operation arguments here
            WSBindingProvider bp = (WSBindingProvider) port;
            SOAPMessage message = null;
            message = javax.xml.soap.MessageFactory.newInstance().createMessage();
            SOAPHeader header = message.getSOAPHeader();
            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");
            //setting up the password Digest
            String unique = UniqId.getInstance().getUniqID();
            BASE64Encoder encoder = new BASE64Encoder();
            String NotEvenOnce = encoder.encode(unique.getBytes());
            //2011-04-05T19:51:46Z Format timestamp 'Y-m-dTH:i:s'
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
            Calendar c1 = Calendar.getInstance();
            c1.add(Calendar.HOUR_OF_DAY, 6);
            String creaDate = sdf.format(c1.getTime());
            String Hash = hash;
            try {
                 Hash = getHash(NotEvenOnce + creaDate + "C@pt1v0");
            } catch (NoSuchAlgorithmException ex) {
                error("hash error " + ex);
            }

            // PACKING
            byte[] b = new BigInteger(Hash, 16).toByteArray(); //maybe other
//        constructor to implement other formats of pack()
            String pack = new String(b, "UTF-8").substring(1); //first char is sign
            String PassDigest = encoder.encode(pack.getBytes());
            password.addTextNode(PassDigest);

            SOAPElement nonce =
                    usernameToken.addChildElement("Nonce", "wsse");
//                        nonce.setAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
            nonce.addTextNode(NotEvenOnce);

            SOAPElement created =
                    usernameToken.addChildElement("Created", "wsu");
            created.addTextNode(creaDate);

            //SOAP HEADER Building finished

            bp.setOutboundHeaders(header);


            java.lang.String subscriberID = "phoneNo";
            java.lang.String identity = "Id";
//             TODO process result here
            com.comverse_in.prepaid.ccws.SubscriberRetrieveLite result = port.retrieveSubscriberLite(subscriberID, identity);
            info("Result = " + result.getBalance());
            try {
                handleMessage((SOAPMessageContext) message);
            } catch (Exception e) {
                info("Excepcion " + e);
            }

        } catch (Exception ex) {
            error("Error calling the WebService: " + ex);
        }

Based on the second example given, and that gives me the following error.

javax.xml.ws.WebServiceException: com.sun.istack.XMLStreamException2: javax.xml.bind.MarshalException - with linked exception: [com.sun.istack.SAXException2: unable to marshal type "com.sun.xml.messaging.saaj.soap.ver1_1.Header1_1Impl" as an element because it is missing an @XmlRootElement annotation]

What at this time I don't undestand
link
Risk_TI's gravatar image

Risk_TI

What JAX-WS Engine are you using?, Axis2 or Metro? Let me know I will try out a example and provide the actual solution.
link
shivaspk's gravatar image

shivaspk

Thank you Shivaspk, the server I'm using is Apache Tomcat, so I take the guess that is axis the engine. I have been battling with this issue for a while

very much appreciated.
link
Risk_TI's gravatar image

Risk_TI

well I had come to a solution by myself but thanks for the help
link
Risk_TI's gravatar image

Risk_TI

because no one else had an answer and I found it by myself
link
Risk_TI's gravatar image

Risk_TI

Your answer
[hide preview]

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Tags:

×6
×2
×4
×141
×5
×13

Asked: 04/18/2011 03:44

Seen: 17183 times

Last updated: 05/06/2011 09:17