Repository: cxf Updated Branches: refs/heads/master a892678e5 -> 42b3ae5ec
More work on using shared security constants in cxf-rt-rs-xml-security Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/42b3ae5e Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/42b3ae5e Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/42b3ae5e Branch: refs/heads/master Commit: 42b3ae5ec3ae398082e892d6c37acb0809876894 Parents: a892678 Author: Colm O hEigeartaigh <cohei...@apache.org> Authored: Thu Apr 16 13:36:22 2015 +0100 Committer: Colm O hEigeartaigh <cohei...@apache.org> Committed: Thu Apr 16 13:36:22 2015 +0100 ---------------------------------------------------------------------- .../rs/security/saml/AbstractSamlInHandler.java | 27 ++++++++++++++------ .../SecurityContextProviderImpl.java | 17 ++++++++++++ .../security/xml/AbstractXmlSigInHandler.java | 24 ++++++++++++++--- .../rs/security/xml/XmlEncOutInterceptor.java | 5 ++++ .../rs/security/xml/XmlSecInInterceptor.java | 21 ++++++++++++++- .../cxf/rt/security/SecurityConstants.java | 7 ++--- .../cxf/ws/security/SecurityConstants.java | 20 +++++---------- .../jaxrs/security/saml/secureServer.xml | 9 +++++++ 8 files changed, 102 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/42b3ae5e/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java index 7fbe571..02e3835 100644 --- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java +++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/AbstractSamlInHandler.java @@ -47,6 +47,7 @@ import org.apache.cxf.rs.security.saml.authorization.SecurityContextProvider; import org.apache.cxf.rs.security.saml.authorization.SecurityContextProviderImpl; import org.apache.cxf.rs.security.xml.AbstractXmlSecInHandler; import org.apache.cxf.rt.security.SecurityConstants; +import org.apache.cxf.rt.security.utils.SecurityUtils; import org.apache.cxf.security.SecurityContext; import org.apache.cxf.security.transport.TLSSessionInfo; import org.apache.cxf.staxutils.StaxUtils; @@ -221,15 +222,25 @@ public abstract class AbstractSamlInHandler implements ContainerRequestFilter { } protected void checkSubjectConfirmationData(Message message, SamlAssertionWrapper assertion) { - Certificate[] tlsCerts = getTLSCertificates(message); - if (!checkHolderOfKey(message, assertion, tlsCerts)) { - throwFault("Holder Of Key claim fails", null); + String valSAMLSubjectConf = + (String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.VALIDATE_SAML_SUBJECT_CONFIRMATION, + message); + boolean validateSAMLSubjectConf = true; + if (valSAMLSubjectConf != null) { + validateSAMLSubjectConf = Boolean.parseBoolean(valSAMLSubjectConf); } - if (!checkSenderVouches(message, assertion, tlsCerts)) { - throwFault("Sender vouchers claim fails", null); - } - if (!checkBearer(assertion, tlsCerts)) { - throwFault("Bearer claim fails", null); + + if (validateSAMLSubjectConf) { + Certificate[] tlsCerts = getTLSCertificates(message); + if (!checkHolderOfKey(message, assertion, tlsCerts)) { + throwFault("Holder Of Key claim fails", null); + } + if (!checkSenderVouches(message, assertion, tlsCerts)) { + throwFault("Sender vouchers claim fails", null); + } + if (!checkBearer(assertion, tlsCerts)) { + throwFault("Bearer claim fails", null); + } } } http://git-wip-us.apache.org/repos/asf/cxf/blob/42b3ae5e/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/SecurityContextProviderImpl.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/SecurityContextProviderImpl.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/SecurityContextProviderImpl.java index 9899085..9c71bfa 100644 --- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/SecurityContextProviderImpl.java +++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/saml/authorization/SecurityContextProviderImpl.java @@ -24,10 +24,12 @@ import java.util.Set; import org.w3c.dom.Element; import org.apache.cxf.message.Message; import org.apache.cxf.rs.security.saml.assertion.Subject; +import org.apache.cxf.rt.security.SecurityConstants; import org.apache.cxf.rt.security.claims.ClaimCollection; import org.apache.cxf.rt.security.saml.claims.SAMLClaim; import org.apache.cxf.rt.security.saml.claims.SAMLSecurityContext; import org.apache.cxf.rt.security.saml.utils.SAMLUtils; +import org.apache.cxf.rt.security.utils.SecurityUtils; import org.apache.cxf.security.SecurityContext; import org.apache.wss4j.common.saml.SamlAssertionWrapper; import org.apache.wss4j.common.saml.builder.SAML2Constants; @@ -39,6 +41,17 @@ public class SecurityContextProviderImpl implements SecurityContextProvider { public SecurityContext getSecurityContext(Message message, SamlAssertionWrapper wrapper) { + // First check to see if we are allowed to set up a security context + // The SAML Assertion must be signed, or we must explicitly allow unsigned + String allowUnsigned = + (String)SecurityUtils.getSecurityPropertyValue( + SecurityConstants.ENABLE_UNSIGNED_SAML_ASSERTION_PRINCIPAL, message + ); + boolean allowUnsignedSamlPrincipals = Boolean.parseBoolean(allowUnsigned); + if (!(wrapper.isSigned() || allowUnsignedSamlPrincipals)) { + return null; + } + ClaimCollection claims = getClaims(wrapper); Subject subject = getSubject(message, wrapper, claims); SecurityContext securityContext = doGetSecurityContext(message, subject, claims); @@ -61,6 +74,10 @@ public class SecurityContextProviderImpl implements SecurityContextProvider { Message message, Subject subject, ClaimCollection claims ) { String defaultRoleName = (String)message.getContextualProperty(ROLE_QUALIFIER_PROPERTY); + if (defaultRoleName == null) { + defaultRoleName = + (String)message.getContextualProperty(SecurityConstants.SAML_ROLE_ATTRIBUTENAME); + } String defaultNameFormat = (String)message.getContextualProperty(ROLE_NAMEFORMAT_PROPERTY); String subjectPrincipalName = getSubjectPrincipalName(subject, claims); http://git-wip-us.apache.org/repos/asf/cxf/blob/42b3ae5e/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java index 3e7e93c..48161f9 100644 --- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java +++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/AbstractXmlSigInHandler.java @@ -38,6 +38,7 @@ import org.apache.cxf.rs.security.common.CryptoLoader; import org.apache.cxf.rs.security.common.RSSecurityUtils; import org.apache.cxf.rs.security.common.TrustValidator; import org.apache.cxf.rt.security.SecurityConstants; +import org.apache.cxf.rt.security.utils.SecurityUtils; import org.apache.cxf.security.SecurityContext; import org.apache.cxf.staxutils.W3CDOMStreamReader; import org.apache.wss4j.common.crypto.Crypto; @@ -60,7 +61,7 @@ public class AbstractXmlSigInHandler extends AbstractXmlSecInHandler { /** * a collection of compiled regular expression patterns for the subject DN */ - private Collection<Pattern> subjectDNPatterns = new ArrayList<>(); + private final Collection<Pattern> subjectDNPatterns = new ArrayList<>(); public void setRemoveSignature(boolean remove) { this.removeSignature = remove; @@ -151,7 +152,7 @@ public class AbstractXmlSigInHandler extends AbstractXmlSecInHandler { } // validate trust - new TrustValidator().validateTrust(crypto, cert, publicKey, subjectDNPatterns); + new TrustValidator().validateTrust(crypto, cert, publicKey, getSubjectContraints(message)); if (valid && persistSignature) { if (signature.getKeyInfo() != null) { message.put(SIGNING_CERT, signature.getKeyInfo().getX509Certificate()); @@ -315,7 +316,7 @@ public class AbstractXmlSigInHandler extends AbstractXmlSecInHandler { */ public void setSubjectConstraints(List<String> constraints) { if (constraints != null) { - subjectDNPatterns = new ArrayList<>(); + subjectDNPatterns.clear(); for (String constraint : constraints) { try { subjectDNPatterns.add(Pattern.compile(constraint.trim())); @@ -326,4 +327,21 @@ public class AbstractXmlSigInHandler extends AbstractXmlSecInHandler { } } + private Collection<Pattern> getSubjectContraints(Message msg) throws PatternSyntaxException { + String certConstraints = + (String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SUBJECT_CERT_CONSTRAINTS, msg); + // Check the message property first. If this is not null then use it. Otherwise pick up + // the constraints set as a property + if (certConstraints != null) { + String[] certConstraintsList = certConstraints.split(","); + if (certConstraintsList != null) { + subjectDNPatterns.clear(); + for (String certConstraint : certConstraintsList) { + subjectDNPatterns.add(Pattern.compile(certConstraint.trim())); + } + } + } + return subjectDNPatterns; + } + } http://git-wip-us.apache.org/repos/asf/cxf/blob/42b3ae5e/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncOutInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncOutInterceptor.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncOutInterceptor.java index 814e1c5..142a909 100644 --- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncOutInterceptor.java +++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlEncOutInterceptor.java @@ -119,6 +119,11 @@ public class XmlEncOutInterceptor extends AbstractXmlSecOutInterceptor { receiverCert = (X509Certificate)message.getExchange().getInMessage().get( AbstractXmlSecInHandler.SIGNING_CERT); + if (receiverCert == null) { + receiverCert = + (X509Certificate)message.getExchange().getInMessage().get( + SecurityConstants.ENCRYPT_CERT); + } } else { CryptoLoader loader = new CryptoLoader(); Crypto crypto = loader.getCrypto(message, http://git-wip-us.apache.org/repos/asf/cxf/blob/42b3ae5e/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java ---------------------------------------------------------------------- diff --git a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java index c4e1b18..d533a36 100644 --- a/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java +++ b/rt/rs/security/xml/src/main/java/org/apache/cxf/rs/security/xml/XmlSecInInterceptor.java @@ -50,6 +50,7 @@ import org.apache.cxf.rs.security.common.CryptoLoader; import org.apache.cxf.rs.security.common.RSSecurityUtils; import org.apache.cxf.rs.security.common.TrustValidator; import org.apache.cxf.rt.security.SecurityConstants; +import org.apache.cxf.rt.security.utils.SecurityUtils; import org.apache.cxf.staxutils.StaxUtils; import org.apache.wss4j.common.crypto.Crypto; import org.apache.wss4j.common.crypto.CryptoType; @@ -297,7 +298,8 @@ public class XmlSecInInterceptor extends AbstractPhaseInterceptor<Message> { // validate trust try { - new TrustValidator().validateTrust(sigCrypto, cert, publicKey, subjectDNPatterns); + new TrustValidator().validateTrust(sigCrypto, cert, publicKey, + getSubjectContraints(msg)); } catch (WSSecurityException e) { throw new XMLSecurityException("empty", "Error during Signature Trust " + "validation: " + e.getMessage()); @@ -376,6 +378,23 @@ public class XmlSecInInterceptor extends AbstractPhaseInterceptor<Message> { } } + private Collection<Pattern> getSubjectContraints(Message msg) throws PatternSyntaxException { + String certConstraints = + (String)SecurityUtils.getSecurityPropertyValue(SecurityConstants.SUBJECT_CERT_CONSTRAINTS, msg); + // Check the message property first. If this is not null then use it. Otherwise pick up + // the constraints set as a property + if (certConstraints != null) { + String[] certConstraintsList = certConstraints.split(","); + if (certConstraintsList != null) { + subjectDNPatterns.clear(); + for (String certConstraint : certConstraintsList) { + subjectDNPatterns.add(Pattern.compile(certConstraint.trim())); + } + } + } + return subjectDNPatterns; + } + /** * This interceptor handles parsing the StaX results (events) + checks to see whether the * required (if any) Actions (signature or encryption) were fulfilled. http://git-wip-us.apache.org/repos/asf/cxf/blob/42b3ae5e/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java ---------------------------------------------------------------------- diff --git a/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java b/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java index 4ad1e1b..345c7da 100644 --- a/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java +++ b/rt/security/src/main/java/org/apache/cxf/rt/security/SecurityConstants.java @@ -188,7 +188,7 @@ public class SecurityConstants { /** * A comma separated String of regular expressions 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. + * chain associated with the certificate. */ public static final String SUBJECT_CERT_CONSTRAINTS = "security.subject.cert.constraints"; @@ -198,9 +198,10 @@ public class SecurityConstants { Set<String> s = new HashSet<>(Arrays.asList(new String[] { USERNAME, PASSWORD, SIGNATURE_USERNAME, ENCRYPT_USERNAME, CALLBACK_HANDLER, SAML_CALLBACK_HANDLER, SIGNATURE_PROPERTIES, - SIGNATURE_CRYPTO, ENCRYPT_PROPERTIES, ENCRYPT_CRYPTO, + SIGNATURE_CRYPTO, ENCRYPT_PROPERTIES, ENCRYPT_CRYPTO, ENCRYPT_CERT, ENABLE_REVOCATION, SUBJECT_CERT_CONSTRAINTS, ENABLE_UNSIGNED_SAML_ASSERTION_PRINCIPAL, - AUDIENCE_RESTRICTION_VALIDATION + AUDIENCE_RESTRICTION_VALIDATION, SAML_ROLE_ATTRIBUTENAME, + ENABLE_UNSIGNED_SAML_ASSERTION_PRINCIPAL, SC_FROM_JAAS_SUBJECT })); COMMON_PROPERTIES = Collections.unmodifiableSet(s); } http://git-wip-us.apache.org/repos/asf/cxf/blob/42b3ae5e/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java ---------------------------------------------------------------------- diff --git a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java index 4080167..e5e7d9c 100644 --- a/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java +++ b/rt/ws/security/src/main/java/org/apache/cxf/ws/security/SecurityConstants.java @@ -493,19 +493,14 @@ public final class SecurityConstants extends org.apache.cxf.rt.security.Security static { Set<String> s = new HashSet<String>(Arrays.asList(new String[] { - USERNAME, PASSWORD, SIGNATURE_USERNAME, ENCRYPT_USERNAME, ACTOR, - CALLBACK_HANDLER, SAML_CALLBACK_HANDLER, SIGNATURE_PROPERTIES, - SIGNATURE_CRYPTO, ENCRYPT_PROPERTIES, ENCRYPT_CRYPTO, - VALIDATE_TOKEN, ENABLE_REVOCATION, ALWAYS_ENCRYPT_UT, IS_BSP_COMPLIANT, - ENABLE_NONCE_CACHE, ENABLE_TIMESTAMP_CACHE, - TIMESTAMP_TTL, TIMESTAMP_FUTURE_TTL, SAML_ROLE_ATTRIBUTENAME, + ACTOR, VALIDATE_TOKEN, ALWAYS_ENCRYPT_UT, IS_BSP_COMPLIANT, ENABLE_NONCE_CACHE, + ENABLE_TIMESTAMP_CACHE, TIMESTAMP_TTL, TIMESTAMP_FUTURE_TTL, KERBEROS_CLIENT, SPNEGO_CLIENT_ACTION, KERBEROS_JAAS_CONTEXT_NAME, KERBEROS_SPN, NONCE_CACHE_INSTANCE, TIMESTAMP_CACHE_INSTANCE, CACHE_CONFIG_FILE, - TOKEN_STORE_CACHE_INSTANCE, SUBJECT_CERT_CONSTRAINTS, - USERNAME_TOKEN_VALIDATOR, SAML1_TOKEN_VALIDATOR, SAML2_TOKEN_VALIDATOR, - TIMESTAMP_TOKEN_VALIDATOR, SIGNATURE_TOKEN_VALIDATOR, BST_TOKEN_VALIDATOR, - SCT_TOKEN_VALIDATOR, STS_CLIENT, STS_APPLIES_TO, STS_TOKEN_USE_CERT_FOR_KEYINFO, - STS_TOKEN_DO_CANCEL, CACHE_ISSUED_TOKEN_IN_ENDPOINT, + TOKEN_STORE_CACHE_INSTANCE, USERNAME_TOKEN_VALIDATOR, SAML1_TOKEN_VALIDATOR, + SAML2_TOKEN_VALIDATOR, TIMESTAMP_TOKEN_VALIDATOR, SIGNATURE_TOKEN_VALIDATOR, + BST_TOKEN_VALIDATOR, SCT_TOKEN_VALIDATOR, STS_CLIENT, STS_APPLIES_TO, + STS_TOKEN_USE_CERT_FOR_KEYINFO, STS_TOKEN_DO_CANCEL, CACHE_ISSUED_TOKEN_IN_ENDPOINT, DISABLE_STS_CLIENT_WSMEX_CALL_USING_EPR_ADDRESS, STS_TOKEN_CRYPTO, STS_TOKEN_PROPERTIES, STS_TOKEN_USERNAME, STS_TOKEN_ACT_AS, STS_TOKEN_ON_BEHALF_OF, TOKEN, TOKEN_ID, SUBJECT_ROLE_CLASSIFIER, SUBJECT_ROLE_CLASSIFIER_TYPE, MUST_UNDERSTAND, @@ -514,8 +509,7 @@ public final class SecurityConstants extends org.apache.cxf.rt.security.Security CACHE_IDENTIFIER, CACHE_ISSUED_TOKEN_IN_ENDPOINT, PREFER_WSMEX_OVER_STS_CLIENT_CONFIG, DELEGATED_CREDENTIAL, KERBEROS_USE_CREDENTIAL_DELEGATION, KERBEROS_IS_USERNAME_IN_SERVICENAME_FORM, STS_TOKEN_IMMINENT_EXPIRY_VALUE, - KERBEROS_REQUEST_CREDENTIAL_DELEGATION, ENABLE_UNSIGNED_SAML_ASSERTION_PRINCIPAL, - AUDIENCE_RESTRICTION_VALIDATION, POLICY_VALIDATOR_MAP + KERBEROS_REQUEST_CREDENTIAL_DELEGATION, POLICY_VALIDATOR_MAP })); for (String commonProperty : COMMON_PROPERTIES) { s.add(commonProperty); http://git-wip-us.apache.org/repos/asf/cxf/blob/42b3ae5e/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/secureServer.xml ---------------------------------------------------------------------- diff --git a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/secureServer.xml b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/secureServer.xml index 07dcf6d..1ee3d3d 100644 --- a/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/secureServer.xml +++ b/systests/rs-security/src/test/java/org/apache/cxf/systest/jaxrs/security/saml/secureServer.xml @@ -57,6 +57,9 @@ under the License. <ref bean="samlEnvHandler"/> <ref bean="rolesHandler"/> </jaxrs:providers> + <jaxrs:properties> + <entry key="security.enable.unsigned-saml-assertion.principal" value="true"/> + </jaxrs:properties> <!-- If default role qualifier and format are not supported: <jaxrs:properties> @@ -91,6 +94,9 @@ under the License. <ref bean="samlEnvHandlerWithCustomProvider"/> <ref bean="rolesHandlerWithUserMap"/> </jaxrs:providers> + <jaxrs:properties> + <entry key="security.enable.unsigned-saml-assertion.principal" value="true"/> + </jaxrs:properties> </jaxrs:server> <jaxrs:server address="https://localhost:${testutil.ports.jaxrs-saml}/saml-claims"> <jaxrs:serviceBeans> @@ -100,5 +106,8 @@ under the License. <ref bean="samlEnvHandler"/> <ref bean="claimsHandler"/> </jaxrs:providers> + <jaxrs:properties> + <entry key="security.enable.unsigned-saml-assertion.principal" value="true"/> + </jaxrs:properties> </jaxrs:server> </beans>