Add ability to override Wss4j's addInclusivePrefixes.

Resolves #1300.
Related: #1212.
This commit is contained in:
Rob Leland
2022-11-29 17:05:23 -05:00
committed by Greg L. Turnquist
parent d43b25f475
commit bd7ba3be41
3 changed files with 135 additions and 0 deletions

View File

@@ -179,6 +179,7 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
private boolean bspCompliant;
private boolean addInclusivePrefixes = true;
private boolean securementUseDerivedKey;
private CallbackHandler samlCallbackHandler;
@@ -541,6 +542,15 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
this.bspCompliant = bspCompliant;
}
/**
* Sets whether to add an InclusiveNamespaces PrefixList as a CanonicalizationMethod child
* when generating Signatures using WSConstants.C14N_EXCL_OMIT_COMMENTS. Default is {@code true}.
*/
public void setAddInclusivePrefixes(boolean addInclusivePrefixes) {
this.handler.setOption(WSHandlerConstants.ADD_INCLUSIVE_PREFIXES, addInclusivePrefixes);
this.addInclusivePrefixes = addInclusivePrefixes;
}
/**
* Sets whether the RSA 1.5 key transport algorithm is allowed.
*/
@@ -676,6 +686,7 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
if (requestData.getBSPEnforcer() != null) {
requestData.getBSPEnforcer().setDisableBSPRules(!bspCompliant);
}
requestData.setAddInclusivePrefixes(addInclusivePrefixes);
// allow for qualified password types for .Net interoperability
requestData.setAllowNamespaceQualifiedPasswordTypes(true);

View File

@@ -84,4 +84,45 @@ public class SaajWss4jMessageInterceptorSignTest extends Wss4jMessageInterceptor
interceptor.validateMessage(message, messageContext);
}
@Test
public void testSignWithoutInclusivePrefixesAndValidate() throws Exception {
Transformer transformer = TransformerFactoryUtils.newInstance().newTransformer();
interceptor.setSecurementActions("Signature");
interceptor.setEnableSignatureConfirmation(false);
interceptor.setSecurementPassword("123456");
interceptor.setSecurementUsername("rsaKey");
interceptor.setAddInclusivePrefixes(false);
SOAPMessage saajMessage = saajSoap11MessageFactory.createMessage();
transformer.transform(new StringSource(PAYLOAD), new DOMResult(saajMessage.getSOAPBody()));
SoapMessage message = new SaajSoapMessage(saajMessage, saajSoap11MessageFactory);
MessageContext messageContext = new DefaultMessageContext(message, new SaajSoapMessageFactory(saajSoap11MessageFactory));
interceptor.secureMessage(message, messageContext);
SOAPHeader header = ((SaajSoapMessage) message).getSaajMessage().getSOAPHeader();
Iterator<?> iterator = header.getChildElements(
new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security"));
assertThat(iterator.hasNext()).isTrue();
SOAPHeaderElement securityHeader = (SOAPHeaderElement) iterator.next();
iterator = securityHeader.getChildElements(new QName("http://www.w3.org/2000/09/xmldsig#", "Signature"));
assertThat(iterator.hasNext()).isTrue();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
message.writeTo(bos);
MimeHeaders mimeHeaders = new MimeHeaders();
mimeHeaders.addHeader("Content-Type", "text/xml");
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
SOAPMessage signed = saajSoap11MessageFactory.createMessage(mimeHeaders, bis);
message = new SaajSoapMessage(signed, saajSoap11MessageFactory);
messageContext = new DefaultMessageContext(message, new SaajSoapMessageFactory(saajSoap11MessageFactory));
interceptor.validateMessage(message, messageContext);
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2005-2022 the original author or authors.
*
* Licensed 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.springframework.ws.soap.security.wss4j2;
import org.apache.wss4j.dom.handler.RequestData;
import org.junit.jupiter.api.Test;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.ws.context.DefaultMessageContext;
import org.springframework.ws.context.MessageContext;
import org.springframework.ws.soap.SoapMessage;
import org.springframework.ws.soap.saaj.SaajSoapMessage;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
import org.springframework.xml.transform.StringSource;
import org.springframework.xml.transform.TransformerFactoryUtils;
import jakarta.xml.soap.SOAPException;
import jakarta.xml.soap.SOAPMessage;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.dom.DOMResult;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.springframework.test.util.AssertionErrors.assertEquals;
public class SaajWss4jSecurityInterceptorDefaultsTest extends Wss4jTestCase {
private static final String PAYLOAD = "<tru:StockSymbol xmlns:tru=\"http://fabrikam123.com/payloads\">QQQ</tru:StockSymbol>";
@Test
public void testThatTheDefaultValueForAddInclusivePrefixesMatchesWss4JDefaultValue() {
Wss4jSecurityInterceptor subject = new Wss4jSecurityInterceptor();
RequestData requestData = new RequestData();
Boolean springDefault = (Boolean) ReflectionTestUtils.getField(subject, Wss4jSecurityInterceptor.class, "addInclusivePrefixes");
assertEquals("Spring-ws default for addInclusivePrefixes matches Wss4j default", requestData.isAddInclusivePrefixes(), springDefault);
}
@Test
public void testThatInitializeValidationRequestDataSetsInclusivePrefixesUsingDefaults() throws TransformerException, SOAPException {
Wss4jSecurityInterceptor subject = new Wss4jSecurityInterceptor();
Transformer transformer = TransformerFactoryUtils.newInstance().newTransformer();
SOAPMessage saajMessage = saajSoap11MessageFactory.createMessage();
transformer.transform(new StringSource(PAYLOAD), new DOMResult(saajMessage.getSOAPBody()));
SoapMessage message = new SaajSoapMessage(saajMessage, saajSoap11MessageFactory);
MessageContext messageContext = new DefaultMessageContext(message, new SaajSoapMessageFactory(saajSoap11MessageFactory));
RequestData validationData = ReflectionTestUtils.invokeMethod(subject, "initializeValidationRequestData", messageContext);
assertTrue(validationData.isAddInclusivePrefixes());
}
@Test
public void testThatInitializeValidationRequestDataSetsInclusivePrefixesUsingNotUsingInclusivePrefixes() throws TransformerException, SOAPException {
Wss4jSecurityInterceptor subject = new Wss4jSecurityInterceptor();
subject.setAddInclusivePrefixes(false);
Transformer transformer = TransformerFactoryUtils.newInstance().newTransformer();
SOAPMessage saajMessage = saajSoap11MessageFactory.createMessage();
transformer.transform(new StringSource(PAYLOAD), new DOMResult(saajMessage.getSOAPBody()));
SoapMessage message = new SaajSoapMessage(saajMessage, saajSoap11MessageFactory);
MessageContext messageContext = new DefaultMessageContext(message, new SaajSoapMessageFactory(saajSoap11MessageFactory));
RequestData validationData = ReflectionTestUtils.invokeMethod(subject, "initializeValidationRequestData", messageContext);
assertFalse(validationData.isAddInclusivePrefixes());
}
}