Monday, March 9, 2009

Creating WS-Security element using ws4j api

You can create WS Security element <wss:security> using wss4j api
Following code snippet describe how to attach Security header to SOAP message


import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.message.WSSecHeader;
import org.apache.ws.security.message.WSSecUsernameToken;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;


public class WSS4JSecurityUtil {

public static void main(String[] args) {

WSS4JSecurityUtil util = new WSS4JSecurityUtil();
// Create UsernameToken
object
WSSecUsernameToken wsSecUserNameToken = new
WSSecUsernameToken();
// Set user info to UsernameToken
wsSecUserNameToken.setUserInfo("wsuser", "wspwd");
// Set password Type
WSConstants.PASSWORD_DIGEST for digest password or
//
WSConstants.PASSWORD_TEST for plain text
password
//wsSecUserNameToken.setPasswordType(WSConstants.PASSWORD_TEXT);
wsSecUserNameToken.setPasswordType(
WSConstants.PASSWORD_DIGEST);
org.w3c.dom.Document doc = util.getSoapEnvelopeAsDocument();

// Create Header element
WSSecHeader secHeader = new WSSecHeader();
// Insert Security header to soap envelop document
secHeader.insertSecurityHeader(doc);
// build the soap envelope with
Security header with user token
Document elementWithDigest = wsSecUserNameToken.build(doc, secHeader);
printXMLDocument(elementWithDigest);

}
private org.w3c.dom.Document getSoapEnvelopeAsDocument() {
String
soapenvelopeString = "";
Document soapEnv = null;
try
{
DocumentBuilderFactory docBuilderFactory =
DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder =
docBuilderFactory.newDocumentBuilder();
soapEnv = docBuilder.parse (new
File("soapmessage.xml"));
//
// normalize text representation
// soapEnv.getDocumentElement ().normalize
();
// System.out.println ("Root element of the doc is " +
//
soapEnv.getDocumentElement().getNodeName());
//
// Transformer
transformer = TransformerFactory.newInstance().newTransformer();
//
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//
////
initialize StreamResult with File object to save to file
// StreamResult
result = new StreamResult(new StringWriter());
// DOMSource source = new
DOMSource(soapEnv);
// transformer.transform(source, result);
//
//
String xmlString = result.getWriter().toString();
//
System.out.println(xmlString);
} catch (ParserConfigurationException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch
(SAXException e) {
// TODO Auto-generated catch
block
e.printStackTrace();
} catch (IOException e) {
// TODO
Auto-generated catch block
e.printStackTrace();
}
return
soapEnv;
}
public static void printXMLDocument(org.w3c.dom.Document
document){
Transformer transformer;
try {
transformer =
TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT,
"yes");
// initialize StreamResult with File object to save to
file
StreamResult result = new StreamResult(new StringWriter());
DOMSource
source = new DOMSource(document);
transformer.transform(source,
result);
String xmlString =
result.getWriter().toString();
System.out.println(xmlString);
} catch
(TransformerConfigurationException e) {
// TODO Auto-generated catch
block
e.printStackTrace();
} catch (TransformerFactoryConfigurationError
e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch
(TransformerException e) {
// TODO Auto-generated catch
block
e.printStackTrace();
}
}
}

Blank Space or null String validation using XSD schema

Regarding null values:

The W3C Schema "nillable" and "nill" attributes can be used to indicate that an element has a null (nill) value in an XML instance document.
The "nillable" attribute is used in a schema, and the "nill" attribute is used in an XML instance document.

For example, the following schema declaration indicates that the element "SomeElement" is nillable (i.e. can be marked as null in an XML instance document):

<xsd:element name="SomeElement" type="xsd:string" nillable="true"/>



This declaration allows the following to appear in an XML instance document:

<SomeElement xsi:nill="true"></SomeElement>



For a "not null" specification (as you indicate below), simply set the "nillable" attribute in the schema to "false":

<xsd:element name="SomeElement" type="xsd:string" nillable="false"/>



Regarding whitespace:

The W3C Schema "whiteSpace" facet can be used to indicate to an XML processor how whitespace should be handled for an element of datatype string.

There are 3 possible values:
(1) preserve - do not normalize (i.e. preserve all whitespace)
(2) replace - all occurences of tab (#x9), linefeed (#xA), and carriage return (#xD) are replaced with space (#x20)
(3) collapse - performs the same processing as "replace", plus: collapses contiguous spaces (#x20) to a single space, and removes leading and trailing spaces.

An example is as follows:


<xsd:simpleType name="SomeType">

<xsd:restriction base="string">

<xsd:whiteSpace value="replace"/>

</xsd:restriction>

</xsd:simpleType>

To define type which allows only not null value you can define simple type as follows

<xsd:simpleType name="nonEmptyString">

<xsd:restriction base="xsd:string">

<xsd:minLength value="1"/>

<xsd:whiteSpace value="collapse"/>

</xsd:restriction>

</xsd:simpleType>