SAML 1.x SSO assertion validator.
authorcantor <cantor@fb386ef7-a10c-0410-8ebf-fd3f8e989ab0>
Wed, 7 Mar 2007 18:38:58 +0000 (18:38 +0000)
committercantor <cantor@fb386ef7-a10c-0410-8ebf-fd3f8e989ab0>
Wed, 7 Mar 2007 18:38:58 +0000 (18:38 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-opensaml2/trunk@202 fb386ef7-a10c-0410-8ebf-fd3f8e989ab0

saml/Makefile.am
saml/saml.vcproj
saml/saml1/profile/BrowserSSOProfileValidator.cpp [new file with mode: 0644]
saml/saml1/profile/BrowserSSOProfileValidator.h [new file with mode: 0644]

index 9a7a5da..da8e6c7 100644 (file)
@@ -73,7 +73,8 @@ saml1bindinclude_HEADERS = \
        saml1/binding/SAML1SOAPClient.h
 
 saml1profinclude_HEADERS = \
-       saml1/profile/AssertionValidator.h
+       saml1/profile/AssertionValidator.h \
+       saml1/profile/BrowserSSOProfileValidator.h
 
 saml2coreinclude_HEADERS = \
        saml2/core/Assertions.h \
@@ -130,6 +131,7 @@ libsaml_la_SOURCES = \
        saml1/binding/impl/SAML1SOAPClient.cpp \
        saml1/binding/impl/SAML1MessageRule.cpp \
        saml1/profile/AssertionValidator.cpp \
+       saml1/profile/BrowserSSOProfileValidator.cpp \
        saml2/core/impl/Assertions20Impl.cpp \
        saml2/core/impl/Assertions20SchemaValidators.cpp \
        saml2/core/impl/Protocols20Impl.cpp \
index ec74261..fe706da 100644 (file)
                                                        />\r
                                                </FileConfiguration>\r
                                        </File>\r
+                                       <File\r
+                                               RelativePath=".\saml1\profile\BrowserSSOProfileValidator.cpp"\r
+                                               >\r
+                                       </File>\r
                                </Filter>\r
                        </Filter>\r
                        <Filter\r
                                                RelativePath=".\saml1\profile\AssertionValidator.h"\r
                                                >\r
                                        </File>\r
+                                       <File\r
+                                               RelativePath=".\saml1\profile\BrowserSSOProfileValidator.h"\r
+                                               >\r
+                                       </File>\r
                                </Filter>\r
                        </Filter>\r
                        <Filter\r
diff --git a/saml/saml1/profile/BrowserSSOProfileValidator.cpp b/saml/saml1/profile/BrowserSSOProfileValidator.cpp
new file mode 100644 (file)
index 0000000..e58068e
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * 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.
+ */
+
+/**
+ * BrowserSSOProfileValidator.cpp
+ * 
+ * SAML 1.x Browser SSO Profile Assertion Validator
+ */
+
+#include "internal.h"
+#include "saml1/core/Assertions.h"
+#include "saml1/profile/BrowserSSOProfileValidator.h"
+
+#include <log4cpp/Category.hh>
+#include <xmltooling/util/NDC.h>
+
+using namespace opensaml::saml1;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+namespace {
+    class SAML_DLLLOCAL _checkMethod : public unary_function<const SubjectStatement*,void>,
+        public unary_function<const ConfirmationMethod*,bool>
+    {
+    public:
+        void operator()(const SubjectStatement* s) const {
+            const Subject* sub = s->getSubject();
+            if (s) {
+                const SubjectConfirmation* sc = sub->getSubjectConfirmation();
+                if (sc) {
+                    const vector<ConfirmationMethod*>& methods = sc->getConfirmationMethods();
+                    if (find_if(methods.begin(), methods.end(), _checkMethod())!=methods.end())
+                        return;     // methods checked out
+                }
+            }
+            throw ValidationException("Assertion contained a statement without a supported ConfirmationMethod.");
+        }
+
+        bool operator()(const ConfirmationMethod* cm) const {
+            const XMLCh* m = cm->getMethod();
+            return (XMLString::equals(m,SubjectConfirmation::BEARER) ||
+                XMLString::equals(m,SubjectConfirmation::ARTIFACT) ||
+                XMLString::equals(m,SubjectConfirmation::ARTIFACT01));
+        }
+    };
+};
+
+void BrowserSSOProfileValidator::validateAssertion(const Assertion& assertion) const
+{
+#ifdef _DEBUG
+    xmltooling::NDC ndc("validate");
+#endif
+
+    // Make sure the assertion is bounded.
+    const Conditions* conds = assertion.getConditions();
+    if (!conds || !conds->getNotBefore() || !conds->getNotOnOrAfter())
+        throw ValidationException("SSO assertions MUST contain NotBefore/NotOnOrAfter attributes.");
+
+    // Each statement MUST have proper confirmation requirements.
+    const vector<AuthenticationStatement*>& authn = assertion.getAuthenticationStatements();
+    for_each(authn.begin(), authn.end(), _checkMethod());
+    const vector<AttributeStatement*>& attr = assertion.getAttributeStatements();
+    for_each(attr.begin(), attr.end(), _checkMethod());
+    const vector<SubjectStatement*>& sub = assertion.getSubjectStatements();
+    for_each(sub.begin(), sub.end(), _checkMethod());
+
+    // Pass up for additional checking.
+    AssertionValidator::validateAssertion(assertion);
+}
diff --git a/saml/saml1/profile/BrowserSSOProfileValidator.h b/saml/saml1/profile/BrowserSSOProfileValidator.h
new file mode 100644 (file)
index 0000000..6073a7a
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * 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.
+ */
+
+/**
+ * @file saml/saml1/profile/BrowserSSOProfileValidator.h
+ * 
+ * SAML 1.x Browser SSO Profile Assertion Validator 
+ */
+
+#ifndef __saml1_ssoval_h__
+#define __saml1_ssoval_h__
+
+#include <saml/saml1/profile/AssertionValidator.h>
+
+namespace opensaml {
+    namespace saml1 {
+        
+        /**
+         * SAML 1.x Browser SSO Profile Assertion Validator
+         *
+         * <p>In addition to standard core requirements for validity, SSO assertions
+         * <strong>MUST</strong> have NotBefore/NotOnOrAfter attributes and each subject statement
+         * <strong>MUST</strong> be confirmable via bearer or artifact method.
+         */
+        class SAML_API BrowserSSOProfileValidator : public AssertionValidator
+        {
+        public:
+            /**
+             * Constructor
+             * 
+             * @param audiences set of audience values representing recipient
+             * @param ts        timestamp to evaluate assertion conditions, or 0 to bypass check
+             */
+            BrowserSSOProfileValidator(const std::vector<const XMLCh*>& audiences, time_t ts=0)
+                : AssertionValidator(audiences, ts) {
+            }
+            virtual ~BrowserSSOProfileValidator() {}
+    
+            void validateAssertion(const Assertion& assertion) const;
+        };
+        
+    };
+};
+
+#endif /* __saml1_ssoval_h__ */