• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

Help regarding web service security

 
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi
I am working on WS-Security and new in WS . I want to use WSS4j (web service security for java) API to implement WS-Security. Following is a code which performs the required task. But the problem is that here soap message (mentioned in bold text) is taken as a string. I have to take the soap message generated by my web service. How can i get this soap message generated by my service. Please help me.

package abc;

/**
*
* @author user
*/
import org.apache.ws.security.components.crypto.Merlin;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.apache.xml.security.c14n.Canonicalizer;
import org.w3c.dom.Document;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.dom.DOMSource;
import java.io.ByteArrayInputStream;

//import org.apache.ws.security.crypto.BouncyCastle;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.SOAPPart;
import org.apache.axis.client.AxisClient;
import org.apache.axis.configuration.NullProvider;
import org.apache.axis.message.SOAPEnvelope;
import org.apache.axis.utils.XMLUtils;
//import org.apache.ws.axis.security.util.AxisUtil;
import org.apache.ws.security.util.WSSecurityUtil;
import org.apache.ws.axis.security.WSDoAllReceiver;
import org.apache.ws.axis.security.WSDoAllSender;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.CryptoFactory;
import org.apache.ws.security.message.WSSignEnvelope;
import org.apache.ws.security.message.WSEncryptBody;
import org.apache.ws.security.message.WSSAddUsernameToken;
import org.apache.ws.security.message.token.SecurityTokenReference;
import org.apache.ws.security.message.token.Reference;
import org.apache.ws.security.WSSecurityEngine;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.util.WSSecurityUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.PrintWriter;

/**
* Enter description here.
*
* @author <a href="mailto:jeff@jeffhanson.com">Jeff Hanson</a>
* @version $Revision: 1.1 $
* <p/>
* <p><b>Revisions:</b>
* <p/>
* <p><b>Jul 26, 2005 jhanson:</b>
* <ul>
* <li> Created file.
* </ul>
*/

public class WSSecuritySample
{
[b] private static final String soapMsg =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
"<SOAP-ENV:Envelope" +
" xmlns:SOAP-ENV=\"http://www.w3.org/2003/05/soap-envelope\"\n" +
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
" <SOAP-ENV:Body>" +
" <sayHello xmlns=\"http://jeffhanson.com/services/helloworld\">" +
" <value xmlns=\"\">Hello world!</value>" +
" </sayHello>" +
" </SOAP-ENV:Body>" +
"</SOAP-ENV:Envelope>";
[/b] // The following initializes the security engine to the
// default WS-Security settings
private static final WSSecurityEngine secEngine = new WSSecurityEngine();

// The following creates a crypto provider according to the
// class name specified by the system property:
// org.apache.ws.security.crypto.provider
//
// If the provider property is not set, the default class,
// org.apache.ws.security.components.crypto.BouncyCastle, is
// used.
//
// The provider is initialized to the values specified in
// the crypto.properties file. The crypto.properties file
// found in the wss4j jar file specifies
// org.apache.ws.security.components.crypto.Merlin
// as the provider class.
private static final Crypto crypto = CryptoFactory.getInstance();
//private static final CryptoFactory crypto1 = (CryptoFactory) CryptoFactory.getInstance();

private AxisClient engine = null;
private MessageContext msgContext = null;


/**
* Main method
*/
public static void main(String[] args)
{
try
{
WSSecuritySample app = new WSSecuritySample();

Message axisMessage = app.getAxisMessage(soapMsg);
SOAPEnvelope unsignedEnvelope = axisMessage.getSOAPEnvelope();

System.out.println("<<<<<< Unsigned and Unencrypted >>>>>>");
XMLUtils.PrettyElementToWriter(unsignedEnvelope.getAsDOM(), new PrintWriter(System.out));


//

Message samlMsg = app.addUserTokens(unsignedEnvelope);
System.out.println("\n<<<<<< User Tokens >>>>>>");
XMLUtils.PrettyElementToWriter(samlMsg.getSOAPEnvelope().getAsDOM(),new PrintWriter(System.out));


Message encryptedMsg = app.encryptSOAPEnvelope(unsignedEnvelope,
axisMessage);
System.out.println("\n<<<<<< Encrypted >>>>>>");
XMLUtils.PrettyElementToWriter(encryptedMsg.getSOAPEnvelope().getAsDOM(),
new PrintWriter(System.out));
//
Message signedMsg = app.signSOAPEnvelope(unsignedEnvelope);
System.out.println("\n<<<<<< Signed >>>>>>");
XMLUtils.PrettyElementToWriter(signedMsg.getSOAPEnvelope().getAsDOM(), new PrintWriter(System.out));
}
catch (Exception e)
{
e.printStackTrace();
}
}

/**
* WSSecuritySample constructor
*/
public WSSecuritySample()
{
engine = new AxisClient(new NullProvider());
msgContext = new MessageContext(engine);
}

/**
* Creates and returns an Axis message from a
* SOAP envelope string.
*
* @param unsignedEnvelope a string containing a SOAP
* envelope
* @return <code>Message</code> the Axis message
*/
private Message getAxisMessage(String unsignedEnvelope)
{
InputStream inStream = new ByteArrayInputStream(unsignedEnvelope.getBytes());
Message axisMessage = new Message(inStream);
axisMessage.setMessageContext(msgContext);
return axisMessage;
}


//
public static class SOAPUtil {

/**
* Convert a DOM Document into a soap message.
* <p/>
*
* @param doc
* @return
* @throws Exception
*/
public static SOAPMessage toSOAPMessage(Document doc) throws Exception {
Canonicalizer c14n =Canonicalizer.getInstance(Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS);
byte[] canonicalMessage = c14n.canonicalizeSubtree(doc);
ByteArrayInputStream in = new ByteArrayInputStream(canonicalMessage);
MessageFactory factory = MessageFactory.newInstance();
return factory.createMessage(null, in);
}

}
//




/**
* Creates a signed SOAP message in compliance with WS-Security.
*
* @return <code>Message</code> the signed SOAP envelope
* as an Axis message
* @throws Exception on error
*/


public static Message signSOAPEnvelope(SOAPEnvelope unsignedEnvelope)
throws Exception
{
// WSSignEnvelope signs a SOAP envelope according to the
// WS Specification (X509 profile) and adds the signature data
// to the envelope.
WSSignEnvelope signer = new WSSignEnvelope();

String alias = "16c73ab6-b892-458f-abf5-2f875f74882e";
String password = "security";
signer.setUserInfo(alias, password);

Document doc = unsignedEnvelope.getAsDocument();

// The "build" method, creates the signed SOAP envelope.
// It takes a SOAP Envelope as a W3C Document and adds
// a WSS Signature header to it. The signed elements
// depend on the signature parts that are specified by
// the WSBaseMessage.setParts(java.util.Vector parts)
// method. By default, SOAP Body is signed.
// The "crypto" parameter is the object that implements
// access to the keystore and handling of certificates.
// A default implementation is included:
// org.apache.ws.security.components.crypto.Merlin
Document signedDoc = signer.build(doc, crypto);

// Convert the signed document into a SOAP message.
//Message signedSOAPMsg =(org.apache.axis.Message)AxisUtil.toSOAPMessage(signedDoc);
// Message signedMsg = (Message) SOAPUtil.toSOAPMessage(signedDoc);

Message signedSOAPMsg =(Message)SOAPUtil.toSOAPMessage(signedDoc);

return signedSOAPMsg;
}

/**
* Adds user tokens to a SOAP envelope in compliance with WS-Security.
*
* @return <code>Message</code> the signed SOAP envelope
* as an Axis message
* @throws Exception on error
*/


public Message addUserTokens(SOAPEnvelope unsignedEnvelope)
throws Exception
{
WSEncryptBody wsEncrypt = new WSEncryptBody();

// Get the message as document
Document doc = unsignedEnvelope.getAsDocument();

String username = "joedoe";
String password = "this is a lot of foobar ";
byte[] key = password.getBytes();

// Add the UserNameToken.
WSSAddUsernameToken builder =
new WSSAddUsernameToken("", false);
builder.setPasswordType(WSConstants.PASSWORD_TEXT);
builder.build(doc, username, password);

// Add an Id to it.
Element usrEle =
(Element)(doc.getElementsByTagNameNS(WSConstants.WSSE_NS, "UsernameToken").item(0));
String idValue = "7654";
usrEle.setAttribute("Id", idValue);

// Create a Reference to the UserNameToken.
Reference ref = new Reference(doc);
//Reference ref = new Reference(WSSConfig.getDefaultWSConfig());
ref.setURI("#" + idValue);
ref.setValueType("UsernameToken");
SecurityTokenReference secRef = new SecurityTokenReference(doc);
secRef.setReference(ref);

// adding the namespace
WSSecurityUtil.setNamespace(secRef.getElement(),
WSConstants.WSSE_NS,
WSConstants.WSSE_PREFIX);

// Setting necessary parameters in WSEncryptBody.
wsEncrypt.setKeyIdentifierType(WSConstants.EMBED_SECURITY_TOKEN_REF);
wsEncrypt.setSecurityTokenReference(secRef);
wsEncrypt.setKey(key);

// Encrypt using the using the key
Document encDoc = wsEncrypt.build(doc, crypto);

// Convert the document into a SOAP message.
Message signedMsg = (Message)SOAPUtil.toSOAPMessage(encDoc);

return signedMsg;
}

/**
* Encrypts a SOAP envelope in compliance with WS-Security.
*
* @return <code>Message</code> the signed SOAP envelope
* as an Axis message
* @throws Exception on error
*/
public Message encryptSOAPEnvelope(SOAPEnvelope unsignedEnvelope,
Message axisMessage)
throws Exception
{
WSEncryptBody encrypt = new WSEncryptBody();
encrypt.setUserInfo("16c73ab6-b892-458f-abf5-2f875f74882e");

// Before Encryption
Document doc = unsignedEnvelope.getAsDocument();
Document encryptedDoc = encrypt.build(doc, crypto);

// Convert the document into a SOAP message.
Message encryptedMsg = (Message) SOAPUtil.toSOAPMessage(encryptedDoc);
String soapPart = encryptedMsg.getSOAPPartAsString();
((SOAPPart)axisMessage.getSOAPPart()).setCurrentMessage(soapPart,
SOAPPart.FORM_STRING);

encryptedDoc = axisMessage.getSOAPEnvelope().getAsDocument();

// Convert the document into a SOAP message.
Message encryptedSOAPMsg =
(Message)SOAPUtil.toSOAPMessage(encryptedDoc);

return encryptedSOAPMsg;
}
}

 
Ranch Hand
Posts: 2198
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi!
Have you considered adding the WS-Security headers in a handler?
Best wishes!
 
somia razzaq
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Ivan Krizsan wrote:Hi!
Have you considered adding the WS-Security headers in a handler?
Best wishes!



Thanks for reply Ivan. Sorry i couldn't understand your answer. I simply want to save my genetrated soap messages in a string variable or some kind of SOAPEnvelope. So that i can use these messages further to secure them using WS-Security and then send them. Actually i have to implement a WS transportation system for an organization where i need message level security. Anything else which is better by which i can do this work, kindly suggest me in detail because i am new in this field.

Best Wishes!
 
Ivan Krizsan
Ranch Hand
Posts: 2198
1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi!
If you look at the sample code that you posted yourself, then you can see that none of the processing done by WSS4J is applied to a SOAP message in text form. In fact, in order for signing and checksum of a SOAP message to be consistent, it needs to be on canonical form. This is done to a DOM tree, not a string.
Before you embark on the journey of web service security, you should read up on SOAP message handlers. See the interface javax.xml.ws.handler.soap.SOAPHandler and, for instance, the following link: http://java.sun.com/mailers/techtips/enterprise/2006/TechTips_June06.html#1
Best wishes!
 
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Generally security is implemented in JAX-WS web services by embedding security information in the SOAP header. You'd typically use a username token along with a time-stamp and a nonce to sign every SOAP message sent to a web service.

To add this information to the header (if you're writing a client) or to read the username token from the header (if you're building the web service), you'd need to write JAX-WS Handlers. Handlers intercept the SOAP message and give you a handle over the SOAP message where you can add or read the security information to or from the header.

I hope it makes sense!
 
somia razzaq
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Pramod Chris wrote:Generally security is implemented in JAX-WS web services by embedding security information in the SOAP header. You'd typically use a username token along with a time-stamp and a nonce to sign every SOAP message sent to a web service.

To add this information to the header (if you're writing a client) or to read the username token from the header (if you're building the web service), you'd need to write JAX-WS Handlers. Handlers intercept the SOAP message and give you a handle over the SOAP message where you can add or read the security information to or from the header.

I hope it makes sense!



Thanks Ivan and Pramod. I understood the issue. I have found many articles regarding creating and using SOAP Message Handler. But i found them difficult in the sense how i use these handlers in my service and client code. Which thing i add at client side and which one at service side. Can you people send me an example or link which clearly show how handlers can be implemented in web service and client code. Thanks for cooperation.

Regards
 
Rancher
Posts: 43081
77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please edit your post to UseCodeTags. It's unnecessarily hard to read the code as it is, making it less likely that people will bother to do so.
 
Pramod Chris
Greenhorn
Posts: 21
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

somia razzaq wrote:..But i found them difficult in the sense how i use these handlers in my service and client code. Which thing i add at client side and which one at service side. Can you people send me an example or link which clearly show how handlers can be implemented in web service and client code.



If you could elaborate a little more on what you're trying to do, (whether you're building a web service client for an external web service and you need to implement security as specified or you're building a new web service which needs to have the security feature etc) then I guess I could take a look.
 
somia razzaq
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Pramod Chris wrote:

somia razzaq wrote:..But i found them difficult in the sense how i use these handlers in my service and client code. Which thing i add at client side and which one at service side. Can you people send me an example or link which clearly show how handlers can be implemented in web service and client code.



If you could elaborate a little more on what you're trying to do, (whether you're building a web service client for an external web service and you need to implement security as specified or you're building a new web service which needs to have the security feature etc) then I guess I could take a look.



I have to build a new web service which needs security features.

Best Regards
 
somia razzaq
Ranch Hand
Posts: 44
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

somia razzaq wrote:

Pramod Chris wrote:

somia razzaq wrote:..But i found them difficult in the sense how i use these handlers in my service and client code. Which thing i add at client side and which one at service side. Can you people send me an example or link which clearly show how handlers can be implemented in web service and client code.



If you could elaborate a little more on what you're trying to do, (whether you're building a web service client for an external web service and you need to implement security as specified or you're building a new web service which needs to have the security feature etc) then I guess I could take a look.



I have to build a new web service which needs security features.

Best Regards



Hi
Pramod i am waiting for help from your side. Because i have surfed many sites to solve the problem but couldn't do it.

Best Regards
 
These are the worst of times and these are the best of times. And this is the best tiny ad:
Gift giving made easy with the permaculture playing cards
https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
reply
    Bookmark Topic Watch Topic
  • New Topic