Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 11018
  • Last Modified:

How to add security header to SOAP webservice client on java

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



<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>"

Open in new window

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
        }

Open in new window

0
Risk_TI
Asked:
Risk_TI
  • 6
  • 3
1 Solution
 
Siva Prasanna KumarPrincipal Solutions ArchitectCommented:
/*

* 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();

Open in new window


This is a snippet from my blog, complete article here : http://soa2world.blogspot.com/2009/05/direct-web-service-client-using-java.html
0
 
Risk_TIAuthor Commented:
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
0
 
Siva Prasanna KumarPrincipal Solutions ArchitectCommented:
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.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
Risk_TIAuthor Commented:
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
0
 
Risk_TIAuthor Commented:
I have come to something like this
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-d\TH:i:s\Z'
            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);
        }

Open in new window

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
0
 
Siva Prasanna KumarPrincipal Solutions ArchitectCommented:
What JAX-WS Engine are you using?, Axis2 or Metro? Let me know I will try out a example and provide the actual solution.
0
 
Risk_TIAuthor Commented:
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.
0
 
Risk_TIAuthor Commented:
well I had come to a solution by myself but thanks for the help
0
 
Risk_TIAuthor Commented:
because no one else had an answer and I found it by myself
0
 
epochsCommented:
hi, can you please let us know how did you implement this. I have similar requirement, your solution can help me.
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 6
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now