/** * 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); } }