Skip to content

Commit 072e496

Browse files
committed
Merge pull request #1419 from wandi34
* pr/1419: Polish "Support WSS4J subject cert constraints" Support WSS4J subject cert constraints Closes gh-1419
2 parents 4b13ab3 + 4a0daeb commit 072e496

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j2/Wss4jSecurityInterceptor.java

+16
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.util.ArrayList;
2323
import java.util.Collections;
2424
import java.util.List;
25+
import java.util.regex.Pattern;
2526

2627
import javax.security.auth.callback.Callback;
2728
import javax.security.auth.callback.CallbackHandler;
@@ -208,6 +209,8 @@ public class Wss4jSecurityInterceptor extends AbstractWsSecurityInterceptor impl
208209
// To maintain same behavior as default, this flag is set to true
209210
private boolean removeSecurityHeader = true;
210211

212+
private List<Pattern> signatureSubjectDnPatterns = Collections.emptyList();
213+
211214
/**
212215
* Create a {@link WSSecurityEngine} by default.
213216
*/
@@ -527,6 +530,17 @@ public void setValidationSignatureCrypto(Crypto signatureCrypto) {
527530
this.validationSignatureCrypto = signatureCrypto;
528531
}
529532

533+
/**
534+
* Certificate constraints which will be applied to the subject DN of the certificate
535+
* used for signature validation, after trust verification of the certificate chain
536+
* associated with the certificate.
537+
* @param patterns a list of regex patterns which will be applied to the subject DN.
538+
* @see ConfigurationConstants#SIG_SUBJECT_CERT_CONSTRAINTS
539+
*/
540+
public void setValidationSubjectDnConstraints(List<Pattern> patterns) {
541+
this.signatureSubjectDnPatterns = patterns;
542+
}
543+
530544
/**
531545
* Whether to enable signatureConfirmation or not. By default, signatureConfirmation
532546
* is enabled.
@@ -741,6 +755,7 @@ protected RequestData initializeRequestData(MessageContext messageContext) {
741755
// allow for qualified password types for .Net interoperability
742756
requestData.setAllowNamespaceQualifiedPasswordTypes(true);
743757

758+
requestData.setSubjectCertConstraints(this.signatureSubjectDnPatterns);
744759
return requestData;
745760
}
746761

@@ -780,6 +795,7 @@ protected RequestData initializeValidationRequestData(MessageContext messageCont
780795
// allow for qualified password types for .Net interoperability
781796
requestData.setAllowNamespaceQualifiedPasswordTypes(true);
782797

798+
requestData.setSubjectCertConstraints(this.signatureSubjectDnPatterns);
783799
return requestData;
784800
}
785801

spring-ws-security/src/test/java/org/springframework/ws/soap/security/wss4j2/Wss4jMessageInterceptorSignTest.java

+37
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
package org.springframework.ws.soap.security.wss4j2;
1818

19+
import java.util.List;
1920
import java.util.Properties;
21+
import java.util.regex.Pattern;
2022

2123
import org.junit.jupiter.api.Test;
2224
import org.w3c.dom.Document;
@@ -28,6 +30,8 @@
2830
import org.springframework.ws.soap.security.wss4j2.support.CryptoFactoryBean;
2931

3032
import static org.assertj.core.api.Assertions.assertThat;
33+
import static org.assertj.core.api.Assertions.assertThatCode;
34+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
3135

3236
public abstract class Wss4jMessageInterceptorSignTest extends Wss4jTest {
3337

@@ -123,4 +127,37 @@ public void testSignResponseWithSignatureUser() throws Exception {
123127
"/SOAP-ENV:Envelope/SOAP-ENV:Header/wsse:Security/ds:Signature", document);
124128
}
125129

130+
@Test
131+
public void testValidateCertificateSubjectDnConstraintsShouldMatchSubject() throws Exception {
132+
SoapMessage message = createSignedTestSoapMessage();
133+
MessageContext messageContext = getSoap11MessageContext(createSignedTestSoapMessage());
134+
this.interceptor.secureMessage(message, messageContext);
135+
136+
this.interceptor.setValidationActions("Signature");
137+
this.interceptor.setValidationSubjectDnConstraints(List.of(Pattern.compile(".*")));
138+
assertThatCode(() -> this.interceptor.validateMessage(message, messageContext)).doesNotThrowAnyException();
139+
}
140+
141+
@Test
142+
public void testValidateCertificateSubjectDnConstraintsShouldFailForNotMatchingSubject() throws Exception {
143+
SoapMessage message = createSignedTestSoapMessage();
144+
MessageContext messageContext = getSoap11MessageContext(createSignedTestSoapMessage());
145+
this.interceptor.secureMessage(message, messageContext);
146+
147+
this.interceptor.setValidationActions("Signature");
148+
this.interceptor.setValidationSubjectDnConstraints(List.of(Pattern.compile("O=Some Other Company")));
149+
assertThatExceptionOfType(Wss4jSecurityValidationException.class)
150+
.isThrownBy(() -> this.interceptor.validateMessage(message, messageContext))
151+
.withMessage("The security token could not be authenticated or authorized");
152+
}
153+
154+
private SoapMessage createSignedTestSoapMessage() throws Exception {
155+
this.interceptor.setSecurementActions("Signature");
156+
this.interceptor.setSecurementSignatureKeyIdentifier("DirectReference");
157+
this.interceptor.setUseSingleCertificate(false);
158+
this.interceptor.setSecurementPassword("123456");
159+
this.interceptor.setSecurementUsername("testkey");
160+
return loadSoap11Message("empty-soap.xml");
161+
}
162+
126163
}
Binary file not shown.

0 commit comments

Comments
 (0)