/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.cxf.ws.security.wss4j;
import java.io.ByteArrayInputStream;
import java.util.List;
import java.util.Set;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.soap.SOAPMessage;
import javax.xml.stream.XMLStreamReader;
import org.w3c.dom.Document;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.helpers.CastUtils;
import org.apache.cxf.helpers.DOMUtils.NullResolver;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.ExchangeImpl;
import org.apache.cxf.message.MessageImpl;
import org.apache.cxf.phase.PhaseInterceptor;
import org.apache.cxf.staxutils.StaxUtils;
import org.apache.wss4j.dom.handler.WSHandlerConstants;
import org.apache.wss4j.dom.handler.WSHandlerResult;
/**
* This a test of the Signature Confirmation functionality that is contained in the
* WS-Security 1.1 specification. The requestor signs an outbound SOAP message and saves
* the signature. The responder processes the inbound SOAP message and saves the received
* signature. Then in the responding message the received signature is attached in the
* form of a wsse11:SignatureConfirmation blob. The requestor processes this blob and
* checks to make sure that the signature value contained therein matches the saved value.
*/
public class SignatureConfirmationTest extends AbstractSecurityTest {
public SignatureConfirmationTest() {
}
@org.junit.Test
public void testSignatureConfirmationRequest() throws Exception {
Document doc = readDocument("wsse-request-clean.xml");
WSS4JOutInterceptor ohandler = new WSS4JOutInterceptor();
PhaseInterceptor<SoapMessage> handler = ohandler.createEndingInterceptor();
SoapMessage msg = getSoapMessageForDom(doc);
msg.put(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE);
msg.put(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION, "true");
msg.put(WSHandlerConstants.SIG_PROP_FILE, "outsecurity.properties");
msg.put(WSHandlerConstants.USER, "myalias");
msg.put("password", "myAliasPassword");
//
// This is necessary to convince the WSS4JOutInterceptor that we're
// functioning as a requestor
//
msg.put(org.apache.cxf.message.Message.REQUESTOR_ROLE, true);
handler.handleMessage(msg);
SOAPMessage saajMsg = msg.getContent(SOAPMessage.class);
doc = saajMsg.getSOAPPart();
assertValid("//wsse:Security", doc);
assertValid("//wsse:Security/ds:Signature", doc);
byte[] docbytes = getMessageBytes(doc);
//
// Save the signature for future confirmation
//
Set<Integer> sigv = CastUtils.cast((Set<?>)msg.get(WSHandlerConstants.SEND_SIGV));
assertNotNull(sigv);
assertTrue(sigv.size() != 0);
XMLStreamReader reader = StaxUtils.createXMLStreamReader(new ByteArrayInputStream(docbytes));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
dbf.setIgnoringComments(false);
dbf.setIgnoringElementContentWhitespace(true);
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new NullResolver());
doc = StaxUtils.read(db, reader, false);
WSS4JInInterceptor inHandler = new WSS4JInInterceptor();
SoapMessage inmsg = new SoapMessage(new MessageImpl());
Exchange ex = new ExchangeImpl();
ex.setInMessage(inmsg);
inmsg.setContent(SOAPMessage.class, saajMsg);
inHandler.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.SIGNATURE);
inHandler.setProperty(WSHandlerConstants.SIG_VER_PROP_FILE, "insecurity.properties");
inHandler.setProperty(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION, "true");
inHandler.handleMessage(inmsg);
//
// Check that the inbound signature result was saved
//
List<WSHandlerResult> sigReceived =
CastUtils.cast((List<?>)inmsg.get(WSHandlerConstants.RECV_RESULTS));
assertNotNull(sigReceived);
assertTrue(sigReceived.size() != 0);
testSignatureConfirmationResponse(sigv, sigReceived);
}
private void testSignatureConfirmationResponse(
Set<Integer> sigSaved,
List<WSHandlerResult> sigReceived
) throws Exception {
Document doc = readDocument("wsse-request-clean.xml");
WSS4JOutInterceptor ohandler = new WSS4JOutInterceptor();
PhaseInterceptor<SoapMessage> handler = ohandler.createEndingInterceptor();
SoapMessage msg = getSoapMessageForDom(doc);
msg.put(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP);
msg.put(WSHandlerConstants.RECV_RESULTS, sigReceived);
handler.handleMessage(msg);
SOAPMessage saajMsg = msg.getContent(SOAPMessage.class);
doc = saajMsg.getSOAPPart();
assertValid("//wsse:Security", doc);
// assertValid("//wsse:Security/wsse11:SignatureConfirmation", doc);
byte[] docbytes = getMessageBytes(doc);
// System.out.println(new String(docbytes));
XMLStreamReader reader = StaxUtils.createXMLStreamReader(new ByteArrayInputStream(docbytes));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
dbf.setIgnoringComments(false);
dbf.setIgnoringElementContentWhitespace(true);
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new NullResolver());
doc = StaxUtils.read(db, reader, false);
WSS4JInInterceptor inHandler = new WSS4JInInterceptor();
SoapMessage inmsg = new SoapMessage(new MessageImpl());
Exchange ex = new ExchangeImpl();
ex.setInMessage(inmsg);
inmsg.setContent(SOAPMessage.class, saajMsg);
inHandler.setProperty(WSHandlerConstants.ACTION, WSHandlerConstants.TIMESTAMP);
inmsg.put(WSHandlerConstants.SEND_SIGV, sigSaved);
inHandler.handleMessage(inmsg);
}
}