RetailerAppWS appWS = new RetailerAppWS();
RetailerAppWSPortType retailerAppWSPortType = appWS.getRetailerAppWSHttpsSoap11Endpoint();
BindingProvider bindingProvider = (BindingProvider) retailerAppWSPortType;
@SuppressWarnings("rawtypes")
List
handlerChain.add(new WSSecurityHeaderSOAPHandler("Retailer", "Retailer123"));
bindingProvider.getBinding().setHandlerChain(handlerChain);
PayBill payBill = new PayBill();
payBill.setAmount(1.0);
payBill.setPin("9834");
payBill.setReceiver("1234567890");
payBill.setUser("sujith");
PayBillResponse pbr = retailerAppWSPortType.payBill(payBill);
In the above code, it is created a WSSecurityHeaderSOAPHandler to manipulate the SOAP message to add security token to SOAP header.
WSSecurityHeaderSOAPHandler is shown below. This code will re-generate the SOAP message.
public class WSSecurityHeaderSOAPHandler implements SOAPHandler
private static final String SOAP_ELEMENT_PASSWORD = "Password";
private static final String SOAP_ELEMENT_NONCE = "Nonce";
private static final String SOAP_ELEMENT_USERNAME = "Username";
private static final String SOAP_ELEMENT_Created = "Created";
private static final String SOAP_ELEMENT_Expires = "Expires";
private static final String SOAP_ELEMENT_USERNAME_TOKEN = "UsernameToken";
private static final String SOAP_ELEMENT_Timestamp_TOKEN = "Timestamp";
private static final String SOAP_ELEMENT_SECURITY = "Security";
private static final String NAMESPACE_SECURITY = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private static final String PREFIX_SECURITY = "wsse";
private static final String NAMESPACE_WSU = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
private static final String PREFIX_WSU = "wsu";
private static final String NAMESPACE_TYPE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText";
private static final String ATTRIBUTE_TYPE = "Type";
private static final String NAMESPACE_EncodingType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary";
private static final String ATTRIBUTE_EncodingType = "EncodingType";
private static final String ATTRIBUTE_MustUnderstand ="mustUnderstand";
private String usernameText;
private String passwordText;
public WSSecurityHeaderSOAPHandler(String usernameText, String passwordText) {
this.usernameText = usernameText;
this.passwordText = passwordText;
}
public boolean handleMessage(SOAPMessageContext soapMessageContext) {
Boolean outboundProperty = (Boolean) soapMessageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outboundProperty.booleanValue()) {
try {
SOAPEnvelope soapEnvelope = soapMessageContext.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = soapEnvelope.getHeader();
if (header == null) {
header = soapEnvelope.addHeader();
}
SOAPElement soapElementSecurityHeader = header.addChildElement(SOAP_ELEMENT_SECURITY, PREFIX_SECURITY,
NAMESPACE_SECURITY);
soapElementSecurityHeader.addAttribute(soapEnvelope.createName(ATTRIBUTE_MustUnderstand), "1");
soapElementSecurityHeader.addNamespaceDeclaration(PREFIX_WSU, NAMESPACE_WSU);
SOAPElement soapElementUsernameToken = soapElementSecurityHeader.addChildElement(SOAP_ELEMENT_USERNAME_TOKEN, PREFIX_SECURITY);
SOAPElement soapElementUsername = soapElementUsernameToken.addChildElement(SOAP_ELEMENT_USERNAME, PREFIX_SECURITY);
soapElementUsername.addTextNode(usernameText);
SOAPElement soapElementPassword = soapElementUsernameToken.addChildElement(SOAP_ELEMENT_PASSWORD, PREFIX_SECURITY);
soapElementPassword.addAttribute(soapEnvelope.createName(ATTRIBUTE_TYPE), NAMESPACE_TYPE);
soapElementPassword.addTextNode(passwordText);
SOAPElement soapElementUserCreated = soapElementUsernameToken.addChildElement(SOAP_ELEMENT_Created, PREFIX_WSU);
long created = System.currentTimeMillis();
TimeZone timeZone = TimeZone.getTimeZone("UTC");
Calendar calendar = Calendar.getInstance(timeZone);
SimpleDateFormat sdfu
= new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
sdfu.setTimeZone(timeZone);
String dateu = sdfu.format(calendar.getTime());
soapElementUserCreated.addTextNode(dateu);
SOAPElement soapElementNonce = soapElementUsernameToken.addChildElement(SOAP_ELEMENT_NONCE, PREFIX_SECURITY);
soapElementNonce.addAttribute(soapEnvelope.createName(ATTRIBUTE_EncodingType), NAMESPACE_EncodingType);
soapElementNonce.addTextNode(createNonce(created));
SOAPElement soapElementTimestampToken = soapElementSecurityHeader.addChildElement(SOAP_ELEMENT_Timestamp_TOKEN, PREFIX_WSU);
SOAPElement soapElementCreated = soapElementTimestampToken.addChildElement(SOAP_ELEMENT_Created, PREFIX_WSU);
soapElementCreated.addTextNode(dateu);
calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) + 2);
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
String date2 = sdf2.format(calendar.getTime());
SOAPElement soapElementExpires = soapElementTimestampToken.addChildElement(SOAP_ELEMENT_Expires, PREFIX_WSU);
soapElementExpires.addTextNode(date2);
} catch (Exception e) {
throw new RuntimeException("Error on wsSecurityHandler: " + e.getMessage());
}
}
return true;
}
@Override
public void close(MessageContext context) {
// TODO Auto-generated method stub
}
@Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return true;
}
@Override
public Set
final QName securityHeader = new QName(
NAMESPACE_SECURITY, SOAP_ELEMENT_SECURITY, PREFIX_SECURITY);
final HashSet headers = new HashSet();
headers.add(securityHeader);
return headers;
}
public String createNonce(long value) throws Exception {
java.security.SecureRandom random = java.security.SecureRandom.getInstance("SHA1PRNG");
random.setSeed(value);
byte[] nonceBytes = new byte[16];
random.nextBytes(nonceBytes);
String nonce = new String(org.apache.commons.codec.binary.Base64.encodeBase64(nonceBytes), "UTF-8");
return nonce;
}
}
This is really helpful. Thank you
ReplyDelete