如何根据以下 Web 服务客户端迭代所有 Child 元素 SOAP Headers
How to Iterate all Child Element SOAP Headers as per the below web service client
基本上我正在尝试根据下面的文章 link 编写 JAX-WS 服务端代码。
web服务客户端handleMessage中的代码(完整代码在http://informatictips.blogspot.com/2013/09/using-message-handler-to-alter-soap.html中)
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("TestUser");
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#PasswordText");
password.addTextNode("TestPassword"); ```
Now how to write relevant server side code for below input soap xml
<s:header>
<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>TestUser</wsse:username>
<wsse:password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPassword</wsse:password>
</wsse:usernametoken>
</wsse:security>
</s:header>
我能够编写用于验证 OASIS 的 WebService -Security Headers 的服务器端处理程序代码,PFB handlerMessage(.) 方法看起来像。
输入XML
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<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 >TestUser</wsse:username>
<wsse:password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPassword</wsse:password>
</wsse:usernametoken>
</wsse:security>
</SOAP-ENV:Header>
<S:Body>
<ns2:getAreaDeatilsByPinCode xmlns:ns2="http://contract.webservice.room/">
<arg0>12</arg0>
</ns2:getAreaDeatilsByPinCode>
</S:Body>
</S:Envelope>
@Override
public boolean handleMessage(SOAPMessageContext soapMessageContext) {
// WS-Security - Publisher - OASIS, Namespace URI
final String WSSE_NS_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
// Qualifier with header elements
final QName QNAME_WSSE_USERNAMETOKEN = new QName(WSSE_NS_URI, "usernametoken");
final QName QNAME_WSSE_USERNAME = new QName(WSSE_NS_URI, "username");
final QName QNAME_WSSE_PASSWORD = new QName(WSSE_NS_URI, "password");
String wsseUsername = null;
String wssePassword = null;
System.out.println("Handler trigger for " + MessageContext.MESSAGE_OUTBOUND_PROPERTY);
Boolean isRequest = (Boolean) soapMessageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (!isRequest) {
try {
SOAPHeader header = soapMessageContext.getMessage().getSOAPHeader();
if (header == null) {
header = soapMessageContext.getMessage().getSOAPPart().getEnvelope().addHeader();
generateSOAPErrMessage(soapMessageContext.getMessage(), "No SOA Header");
}
// Get client data from SOAP headers
Iterator<?> headerElements = header.examineAllHeaderElements();
while (headerElements.hasNext()) {
SOAPHeaderElement headerElement = (SOAPHeaderElement) headerElements.next();
if (headerElement.getElementName().getLocalName().equals("security")) {
System.out.println("inside security");
SOAPHeaderElement securityElement = headerElement;
Iterator<?> securityChildern = securityElement.getChildElements();
while (securityChildern.hasNext()) {
System.out.println("inside securityChildern");
Node node = (Node) securityChildern.next();
if (node instanceof SOAPElement) {
System.out.println("insdie node...");
SOAPElement element = (SOAPElement) node;
QName elementQname = element.getElementQName();
if (QNAME_WSSE_USERNAMETOKEN.equals(elementQname)) {
System.out.println("validating username and password...");
SOAPElement usernameTokenElement = element;
wsseUsername = getFirstChildElementValue(usernameTokenElement, QNAME_WSSE_USERNAME);
wssePassword = getFirstChildElementValue(usernameTokenElement, QNAME_WSSE_PASSWORD);
if(!wsseUsername.equals("TestUser") || !wssePassword.equals("TestPassword")){
generateSOAPErrMessage(soapMessageContext.getMessage(), "username and password are wrong....");
}
System.out.println("username::"+wsseUsername+ " , password::"+wssePassword);
break;
}
}
}
if (wsseUsername != null) {
break;
}
}
}
} catch (SOAPException e) {
e.printStackTrace();
}
}
return true;
}
private String getFirstChildElementValue(SOAPElement usernameTokenElement, QName qNAME_WSSE_USERNAME) {
System.out.println("get username and password");
String value = null;
Iterator<?> usernameTokenChilderen = usernameTokenElement.getChildElements(qNAME_WSSE_USERNAME);
while (usernameTokenChilderen.hasNext()) {
System.out.println("get the child elment for username and password");
SOAPElement childElement = (SOAPElement) usernameTokenChilderen.next();
value = childElement.getValue();
}
return value;
}
private void generateSOAPErrMessage(SOAPMessage message, String cause) {
try {
SOAPBody faultBody = message.getSOAPPart().getEnvelope().getBody();
SOAPFault soapFault = faultBody.addFault();
soapFault.setFaultString(cause);
throw new SOAPFaultException(soapFault);
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
有效请求
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getAreaDeatilsByPinCodeResponse xmlns:ns2="http://contract.webservice.room/">
<return>
<areaName>XXXXX</areaName>
<location>XXXXX</location>
<pincode>12</pincode>
<state>XX</state>
</return>
</ns2:getAreaDeatilsByPinCodeResponse>
</S:Body>
</S:Envelope>
未经授权的请求
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>username and password are wrong....</faultstring>
</S:Fault>
</S:Body>
</S:Envelope>
基本上我正在尝试根据下面的文章 link 编写 JAX-WS 服务端代码。
web服务客户端handleMessage中的代码(完整代码在http://informatictips.blogspot.com/2013/09/using-message-handler-to-alter-soap.html中)
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("TestUser");
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#PasswordText");
password.addTextNode("TestPassword"); ```
Now how to write relevant server side code for below input soap xml
<s:header>
<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>TestUser</wsse:username>
<wsse:password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPassword</wsse:password>
</wsse:usernametoken>
</wsse:security>
</s:header>
我能够编写用于验证 OASIS 的 WebService -Security Headers 的服务器端处理程序代码,PFB handlerMessage(.) 方法看起来像。
输入XML
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<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 >TestUser</wsse:username>
<wsse:password type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">TestPassword</wsse:password>
</wsse:usernametoken>
</wsse:security>
</SOAP-ENV:Header>
<S:Body>
<ns2:getAreaDeatilsByPinCode xmlns:ns2="http://contract.webservice.room/">
<arg0>12</arg0>
</ns2:getAreaDeatilsByPinCode>
</S:Body>
</S:Envelope>
@Override
public boolean handleMessage(SOAPMessageContext soapMessageContext) {
// WS-Security - Publisher - OASIS, Namespace URI
final String WSSE_NS_URI = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
// Qualifier with header elements
final QName QNAME_WSSE_USERNAMETOKEN = new QName(WSSE_NS_URI, "usernametoken");
final QName QNAME_WSSE_USERNAME = new QName(WSSE_NS_URI, "username");
final QName QNAME_WSSE_PASSWORD = new QName(WSSE_NS_URI, "password");
String wsseUsername = null;
String wssePassword = null;
System.out.println("Handler trigger for " + MessageContext.MESSAGE_OUTBOUND_PROPERTY);
Boolean isRequest = (Boolean) soapMessageContext.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (!isRequest) {
try {
SOAPHeader header = soapMessageContext.getMessage().getSOAPHeader();
if (header == null) {
header = soapMessageContext.getMessage().getSOAPPart().getEnvelope().addHeader();
generateSOAPErrMessage(soapMessageContext.getMessage(), "No SOA Header");
}
// Get client data from SOAP headers
Iterator<?> headerElements = header.examineAllHeaderElements();
while (headerElements.hasNext()) {
SOAPHeaderElement headerElement = (SOAPHeaderElement) headerElements.next();
if (headerElement.getElementName().getLocalName().equals("security")) {
System.out.println("inside security");
SOAPHeaderElement securityElement = headerElement;
Iterator<?> securityChildern = securityElement.getChildElements();
while (securityChildern.hasNext()) {
System.out.println("inside securityChildern");
Node node = (Node) securityChildern.next();
if (node instanceof SOAPElement) {
System.out.println("insdie node...");
SOAPElement element = (SOAPElement) node;
QName elementQname = element.getElementQName();
if (QNAME_WSSE_USERNAMETOKEN.equals(elementQname)) {
System.out.println("validating username and password...");
SOAPElement usernameTokenElement = element;
wsseUsername = getFirstChildElementValue(usernameTokenElement, QNAME_WSSE_USERNAME);
wssePassword = getFirstChildElementValue(usernameTokenElement, QNAME_WSSE_PASSWORD);
if(!wsseUsername.equals("TestUser") || !wssePassword.equals("TestPassword")){
generateSOAPErrMessage(soapMessageContext.getMessage(), "username and password are wrong....");
}
System.out.println("username::"+wsseUsername+ " , password::"+wssePassword);
break;
}
}
}
if (wsseUsername != null) {
break;
}
}
}
} catch (SOAPException e) {
e.printStackTrace();
}
}
return true;
}
private String getFirstChildElementValue(SOAPElement usernameTokenElement, QName qNAME_WSSE_USERNAME) {
System.out.println("get username and password");
String value = null;
Iterator<?> usernameTokenChilderen = usernameTokenElement.getChildElements(qNAME_WSSE_USERNAME);
while (usernameTokenChilderen.hasNext()) {
System.out.println("get the child elment for username and password");
SOAPElement childElement = (SOAPElement) usernameTokenChilderen.next();
value = childElement.getValue();
}
return value;
}
private void generateSOAPErrMessage(SOAPMessage message, String cause) {
try {
SOAPBody faultBody = message.getSOAPPart().getEnvelope().getBody();
SOAPFault soapFault = faultBody.addFault();
soapFault.setFaultString(cause);
throw new SOAPFaultException(soapFault);
} catch (SOAPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
有效请求
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<ns2:getAreaDeatilsByPinCodeResponse xmlns:ns2="http://contract.webservice.room/">
<return>
<areaName>XXXXX</areaName>
<location>XXXXX</location>
<pincode>12</pincode>
<state>XX</state>
</return>
</ns2:getAreaDeatilsByPinCodeResponse>
</S:Body>
</S:Envelope>
未经授权的请求
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Body>
<S:Fault xmlns:ns4="http://www.w3.org/2003/05/soap-envelope">
<faultcode>S:Server</faultcode>
<faultstring>username and password are wrong....</faultstring>
</S:Fault>
</S:Body>
</S:Envelope>