/*
* SoapUI, Copyright (C) 2004-2016 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.impl.wsdl.submit.filters;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.wsdl.WsdlRequest;
import com.eviware.soapui.model.iface.SubmitContext;
import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.xml.XmlUtils;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.WSSecurityException;
import org.apache.ws.security.message.WSSecHeader;
import org.apache.ws.security.message.WSSecTimestamp;
import org.apache.ws.security.message.WSSecUsernameToken;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import java.io.IOException;
/**
* Modifies the request message to include WS-Securty Username and Timestamp
* tokens
*
* @author Ole.Matzura
*/
public class WssAuthenticationRequestFilter extends AbstractWssRequestFilter {
private static final String WSS_USERNAME_TOKEN = "WsSecurityAuthenticationRequestFilter@UsernameToken";
private static final String WSS_TIMESTAMP_TOKEN = "WsSecurityAuthenticationRequestFilter@TimestampToken";
public void filterWsdlRequest(SubmitContext context, WsdlRequest wsdlRequest) {
String pwType = PropertyExpander.expandProperties(context, wsdlRequest.getWssPasswordType());
String wsTimestamp = wsdlRequest.getWssTimeToLive();
if ((StringUtils.isNullOrEmpty(pwType) || WsdlRequest.PW_TYPE_NONE.equals(pwType))
&& (StringUtils.isNullOrEmpty(wsTimestamp))) {
return;
}
try {
String password = PropertyExpander.expandProperties(context, wsdlRequest.getPassword());
String username = PropertyExpander.expandProperties(context, wsdlRequest.getUsername());
setWssHeaders(context, username, password, pwType, wsTimestamp);
} catch (Throwable e) {
SoapUI.logError(e);
}
}
public static void setWssHeaders(SubmitContext context, String username, String password, String pwType,
String wsTimestamp) throws SAXException, IOException, WSSecurityException {
Document doc = getWssDocument(context);
// create username token?
if (StringUtils.hasContent(pwType) && !pwType.equals(WsdlRequest.PW_TYPE_NONE)
&& StringUtils.hasContent(username) && StringUtils.hasContent(password)) {
// remove if already set
Element elm = (Element) context.getProperty(WSS_USERNAME_TOKEN);
if (elm != null) {
Element parentNode = (Element) elm.getParentNode();
parentNode.removeChild(elm);
}
// save it so it can be removed..
context.setProperty(WSS_USERNAME_TOKEN, setWssUsernameToken(username, password, pwType, doc));
}
// remove if pwType is not null
else if (pwType != null && context.getProperty(WSS_USERNAME_TOKEN) != null) {
Element elm = (Element) context.getProperty(WSS_USERNAME_TOKEN);
context.removeProperty(WSS_USERNAME_TOKEN);
Element parentNode = (Element) elm.getParentNode();
parentNode.removeChild(elm);
if (XmlUtils.getChildElements(parentNode).getLength() == 0) {
parentNode.getParentNode().removeChild(parentNode);
}
}
// add timestamp?
if (StringUtils.hasContent(wsTimestamp)) {
// remove if already set
Element elm = (Element) context.getProperty(WSS_TIMESTAMP_TOKEN);
if (elm != null) {
Element parentNode = (Element) elm.getParentNode();
parentNode.removeChild(elm);
}
// save it so it can be removed..
context.setProperty(WSS_TIMESTAMP_TOKEN, setWsTimestampToken(wsTimestamp, doc));
}
// remove
else if (wsTimestamp != null && context.getProperty(WSS_TIMESTAMP_TOKEN) != null) {
Element elm = (Element) context.getProperty(WSS_TIMESTAMP_TOKEN);
context.removeProperty(WSS_TIMESTAMP_TOKEN);
Element parentNode = (Element) elm.getParentNode();
parentNode.removeChild(elm);
if (XmlUtils.getChildElements(parentNode).getLength() == 0) {
parentNode.getParentNode().removeChild(parentNode);
}
}
updateWssDocument(context, doc);
}
private static Element setWsTimestampToken(String ttl, Document doc) throws WSSecurityException {
WSSecTimestamp addTimestamp = new WSSecTimestamp();
addTimestamp.setTimeToLive(Integer.parseInt(ttl));
WSSConfig wsc = WSSConfig.getNewInstance();
wsc.setPrecisionInMilliSeconds(false);
wsc.setTimeStampStrict(false);
addTimestamp.setWsConfig(wsc);
WSSecHeader secHeader = new WSSecHeader();
secHeader.insertSecurityHeader(doc);
addTimestamp.build(doc, secHeader);
return addTimestamp.getElement();
}
private static Element setWssUsernameToken(String username, String password, String pwType, Document doc)
throws WSSecurityException {
WSSecUsernameToken wsa = new WSSecUsernameToken();
if (WsdlRequest.PW_TYPE_DIGEST.equals(pwType)) {
wsa.setPasswordType(WSConstants.PASSWORD_DIGEST);
} else {
wsa.setPasswordType(WSConstants.PASSWORD_TEXT);
}
wsa.setUserInfo(username, password);
wsa.addNonce();
wsa.addCreated();
WSSecHeader secHeader = new WSSecHeader();
secHeader.insertSecurityHeader(doc);
wsa.build(doc, secHeader);
return wsa.getUsernameTokenElement();
}
}