You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2016/02/01 12:41:10 UTC

[1/2] cxf git commit: Weaken SAML Bearer Subject Confirmation Requirements if the Response is signed

Repository: cxf
Updated Branches:
  refs/heads/3.0.x-fixes ad0f5f1a1 -> 0bdf4ebdc


Weaken SAML Bearer Subject Confirmation Requirements if the Response is signed


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/7a3816ef
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/7a3816ef
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/7a3816ef

Branch: refs/heads/3.0.x-fixes
Commit: 7a3816efdb97da722e435ed19cfd17461e1ea3f6
Parents: ad0f5f1
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Mon Feb 1 11:38:10 2016 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Mon Feb 1 11:39:51 2016 +0000

----------------------------------------------------------------------
 .../saml/sso/SAMLProtocolResponseValidator.java |  11 +-
 .../saml/sso/SamlSSOAssertionValidator.java     | 115 +++++++++++++++++++
 2 files changed, 121 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/7a3816ef/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLProtocolResponseValidator.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLProtocolResponseValidator.java b/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLProtocolResponseValidator.java
index ef2cda7..7f1d3f6 100644
--- a/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLProtocolResponseValidator.java
+++ b/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLProtocolResponseValidator.java
@@ -50,7 +50,6 @@ import org.apache.wss4j.dom.WSSConfig;
 import org.apache.wss4j.dom.handler.RequestData;
 import org.apache.wss4j.dom.saml.WSSSAMLKeyInfoProcessor;
 import org.apache.wss4j.dom.validate.Credential;
-import org.apache.wss4j.dom.validate.SamlAssertionValidator;
 import org.apache.wss4j.dom.validate.SignatureTrustValidator;
 import org.apache.wss4j.dom.validate.Validator;
 import org.apache.xml.security.encryption.XMLCipher;
@@ -79,7 +78,6 @@ public class SAMLProtocolResponseValidator {
 
     private static final Logger LOG = LogUtils.getL7dLogger(SAMLProtocolResponseValidator.class);
 
-    private Validator assertionValidator = new SamlAssertionValidator();
     private Validator signatureValidator = new SignatureTrustValidator();
     private boolean keyInfoMustBeAvailable = true;
 
@@ -141,7 +139,7 @@ public class SAMLProtocolResponseValidator {
         // Validate Assertions
         for (org.opensaml.saml2.core.Assertion assertion : samlResponse.getAssertions()) {
             SamlAssertionWrapper wrapper = new SamlAssertionWrapper(assertion);
-            validateAssertion(wrapper, sigCrypto, callbackHandler, doc);
+            validateAssertion(wrapper, sigCrypto, callbackHandler, doc, samlResponse.isSigned());
         }
     }
 
@@ -189,7 +187,8 @@ public class SAMLProtocolResponseValidator {
         for (org.opensaml.saml1.core.Assertion assertion : samlResponse.getAssertions()) {
             SamlAssertionWrapper wrapper = new SamlAssertionWrapper(assertion);
             validateAssertion(
-                wrapper, sigCrypto, callbackHandler, samlResponse.getDOM().getOwnerDocument()
+                wrapper, sigCrypto, callbackHandler, samlResponse.getDOM().getOwnerDocument(),
+                samlResponse.isSigned()
             );
         }
     }
@@ -370,7 +369,8 @@ public class SAMLProtocolResponseValidator {
         SamlAssertionWrapper assertion,
         Crypto sigCrypto,
         CallbackHandler callbackHandler,
-        Document doc
+        Document doc,
+        boolean signedResponse
     ) throws WSSecurityException {
         Credential credential = new Credential();
         credential.setSamlAssertion(assertion);
@@ -424,6 +424,7 @@ public class SAMLProtocolResponseValidator {
 
         // Validate the Assertion & verify trust in the signature
         try {
+            SamlSSOAssertionValidator assertionValidator = new SamlSSOAssertionValidator(signedResponse);
             assertionValidator.validate(credential, requestData);
         } catch (WSSecurityException ex) {
             LOG.log(Level.FINE, "Assertion validation failed: " + ex.getMessage(), ex);

http://git-wip-us.apache.org/repos/asf/cxf/blob/7a3816ef/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlSSOAssertionValidator.java
----------------------------------------------------------------------
diff --git a/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlSSOAssertionValidator.java b/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlSSOAssertionValidator.java
new file mode 100644
index 0000000..0cc8c19
--- /dev/null
+++ b/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SamlSSOAssertionValidator.java
@@ -0,0 +1,115 @@
+/**
+ * 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.rs.security.saml.sso;
+
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.wss4j.common.ext.WSSecurityException;
+import org.apache.wss4j.common.saml.OpenSAMLUtil;
+import org.apache.wss4j.common.saml.SamlAssertionWrapper;
+import org.apache.wss4j.common.saml.builder.SAML1Constants;
+import org.apache.wss4j.common.saml.builder.SAML2Constants;
+import org.apache.wss4j.dom.validate.SamlAssertionValidator;
+
+/**
+ * An extension of the WSS4J SamlAssertionValidator. We can weaken the subject confirmation method requirements a bit
+ * for SAML SSO. A Bearer Assertion does not have to be signed by default if the outer Response is signed.
+ */
+public class SamlSSOAssertionValidator extends SamlAssertionValidator {
+    
+    private static final Logger LOG = LogUtils.getL7dLogger(SamlSSOAssertionValidator.class);
+    
+    private final boolean signedResponse;
+    
+    public SamlSSOAssertionValidator(boolean signedResponse) {
+        this.signedResponse = signedResponse;
+    }
+    
+    /**
+     * Check the Subject Confirmation method requirements
+     */
+    protected void verifySubjectConfirmationMethod(
+        SamlAssertionWrapper samlAssertion
+    ) throws WSSecurityException {
+
+        List<String> methods = samlAssertion.getConfirmationMethods();
+        if (methods == null || methods.isEmpty()) {
+            if (super.getRequiredSubjectConfirmationMethod() != null) {
+                LOG.fine("A required subject confirmation method was not present");
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
+                                          "invalidSAMLsecurity");
+            } else if (super.isRequireStandardSubjectConfirmationMethod()) {
+                LOG.fine("A standard subject confirmation method was not present");
+                throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
+                                          "invalidSAMLsecurity");
+            }
+        }
+
+        boolean signed = samlAssertion.isSigned();
+        boolean requiredMethodFound = false;
+        boolean standardMethodFound = false;
+        for (String method : methods) {
+            if (OpenSAMLUtil.isMethodHolderOfKey(method)) {
+                if (samlAssertion.getSubjectKeyInfo() == null) {
+                    LOG.fine("There is no Subject KeyInfo to match the holder-of-key subject conf method");
+                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "noKeyInSAMLToken");
+                }
+
+                // The assertion must have been signed for HOK
+                if (!signed) {
+                    LOG.fine("A holder-of-key assertion must be signed");
+                    throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity");
+                }
+                standardMethodFound = true;
+            }
+
+            if (method != null) {
+                if (method.equals(super.getRequiredSubjectConfirmationMethod())) {
+                    requiredMethodFound = true;
+                }
+                if (SAML2Constants.CONF_BEARER.equals(method)
+                    || SAML1Constants.CONF_BEARER.equals(method)) {
+                    standardMethodFound = true;
+                    if (super.isRequireBearerSignature() && !signed && !signedResponse) {
+                        LOG.fine("A Bearer Assertion was not signed");
+                        throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
+                                                      "invalidSAMLsecurity");
+                    }
+                } else if (SAML2Constants.CONF_SENDER_VOUCHES.equals(method)
+                    || SAML1Constants.CONF_SENDER_VOUCHES.equals(method)) {
+                    standardMethodFound = true;
+                }
+            }
+        }
+
+        if (!requiredMethodFound && super.getRequiredSubjectConfirmationMethod() != null) {
+            LOG.fine("A required subject confirmation method was not present");
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
+                                          "invalidSAMLsecurity");
+        }
+
+        if (!standardMethodFound && super.isRequireStandardSubjectConfirmationMethod()) {
+            LOG.fine("A standard subject confirmation method was not present");
+            throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE,
+                                      "invalidSAMLsecurity");
+        }
+    }    
+}


[2/2] cxf git commit: Recording .gitmergeinfo Changes

Posted by co...@apache.org.
Recording .gitmergeinfo Changes


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/0bdf4ebd
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/0bdf4ebd
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/0bdf4ebd

Branch: refs/heads/3.0.x-fixes
Commit: 0bdf4ebdc3cd6b13f6eca64c27e41d8156bc3439
Parents: 7a3816e
Author: Colm O hEigeartaigh <co...@apache.org>
Authored: Mon Feb 1 11:39:52 2016 +0000
Committer: Colm O hEigeartaigh <co...@apache.org>
Committed: Mon Feb 1 11:39:52 2016 +0000

----------------------------------------------------------------------
 .gitmergeinfo | 1 +
 1 file changed, 1 insertion(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/0bdf4ebd/.gitmergeinfo
----------------------------------------------------------------------
diff --git a/.gitmergeinfo b/.gitmergeinfo
index 02845ee..f4d2582 100644
--- a/.gitmergeinfo
+++ b/.gitmergeinfo
@@ -824,6 +824,7 @@ M bc5e828cd8a25c4c4107c76e1582f807e75c9a77
 M bd1d31f195caab56fbe565fbfb63d9170a0c9406
 M bd7babd656fc06f3e5839bf11e186ec12fdeb6fa
 M bee82ba7d1766b555d965a75b3846ead4686239e
+M bfa97ebf03e8ab6b29129f31d76fa469b054f843
 M c1863fc29c037d01e827e3b2b1dca493fddf986d
 M c1c75b039df7bd1ca9f11ff21f16593fed0c8c16
 M c322ba957e09c58ccef0fe25b382497b031fdc06