diff --git a/spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j2/Wss4jSecurityInterceptor.java b/spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j2/Wss4jSecurityInterceptor.java index 01dad04dd..f198cd154 100644 --- a/spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j2/Wss4jSecurityInterceptor.java +++ b/spring-ws-security/src/main/java/org/springframework/ws/soap/security/wss4j2/Wss4jSecurityInterceptor.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.regex.Pattern; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.UnsupportedCallbackException; @@ -59,6 +60,9 @@ import org.springframework.ws.soap.security.callback.CleanupCallback; import org.springframework.ws.soap.security.wss4j2.callback.UsernameTokenPrincipalCallback; +import static java.util.Collections.emptyList; +import static java.util.Collections.unmodifiableList; + /** * A WS-Security endpoint interceptor based on Apache's WSS4J. This interceptor supports messages created by the {@link * org.springframework.ws.soap.axiom.AxiomSoapMessageFactory} and the {@link org.springframework.ws.soap.saaj.SaajSoapMessageFactory}. @@ -184,7 +188,21 @@ public void setSecurementActor(String securementActor) { public void setSecurementEncryptionCrypto(Crypto securementEncryptionCrypto) { handler.setSecurementEncryptionCrypto(securementEncryptionCrypto); } - + + /** + * Certificate constraints which will be applied to the subject DN of the certificate used for + * signature validation, after trust verification of the certificate chain associated with the + * certificate. + * + * @param patterns A comma separated String of regular expressions which will be applied to + * the subject DN. + * + * @see WSS4J configuration: SIG_SUBJECT_CERT_CONSTRAINTS + */ + public void setSignatureValidationSubjectCertificateConstraints(String patterns) { + handler.setOption(ConfigurationConstants.SIG_SUBJECT_CERT_CONSTRAINTS, patterns); + } + /** * Defines which key identifier type to use. The WS-Security specifications recommends to use the identifier type * {@code IssuerSerial}. For possible encryption key identifier types refer to {@link @@ -646,7 +664,8 @@ protected RequestData initializeValidationRequestData(MessageContext messageCont // allow for qualified password types for .Net interoperability requestData.setAllowNamespaceQualifiedPasswordTypes(true); - + requestData.setSubjectCertConstraints(getSubjectCertConstraints()); + return requestData; } @@ -754,12 +773,27 @@ protected void verifyCertificateTrust(WSHandlerResult result) throws WSSecurityE RequestData requestData = new RequestData(); requestData.setSigVerCrypto(validationSignatureCrypto); requestData.setEnableRevocation(enableRevocation); + requestData.setSubjectCertConstraints(getSubjectCertConstraints()); SignatureTrustValidator validator = new SignatureTrustValidator(); validator.validate(credential, requestData); } } + private List getSubjectCertConstraints() { + String commaSeparatedCertConstraintPatterns = handler.getStringOption(ConfigurationConstants.SIG_SUBJECT_CERT_CONSTRAINTS); + if (commaSeparatedCertConstraintPatterns != null && !commaSeparatedCertConstraintPatterns.isEmpty()) { + String[] patternStrings = commaSeparatedCertConstraintPatterns.split(","); + List constraintPatterns = new ArrayList<>(); + for (String pattern : patternStrings) { + constraintPatterns.add(Pattern.compile(pattern)); + } + return unmodifiableList(constraintPatterns); + } else { + return emptyList(); + } + } + /** Verifies the timestamp. * @param result*/ protected void verifyTimestamp(WSHandlerResult result) throws WSSecurityException {