2 * Licensed to the University Corporation for Advanced Internet
3 * Development, Inc. (UCAID) under one or more contributor license
4 * agreements. See the NOTICE file distributed with this work for
5 * additional information regarding copyright ownership.
7 * UCAID licenses this file to you under the Apache License,
8 * Version 2.0 (the "License"); you may not use this file except
9 * in compliance with the License. You may obtain a copy of the
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17 * either express or implied. See the License for the specific
18 * language governing permissions and limitations under the License.
22 * AssertionValidator.cpp
24 * SAML 1.x basic assertion validator
28 #include "saml1/core/Assertions.h"
29 #include "saml1/profile/AssertionValidator.h"
31 #include <boost/bind.hpp>
32 #include <xmltooling/logging.h>
33 #include <xmltooling/XMLToolingConfig.h>
34 #include <xmltooling/util/NDC.h>
36 using namespace opensaml::saml1;
37 using namespace xmltooling::logging;
38 using namespace xmltooling;
39 using namespace boost;
42 AssertionValidator::AssertionValidator(const XMLCh* recipient, const vector<const XMLCh*>* audiences, time_t ts)
43 : m_recipient(recipient), m_audiences(audiences), m_ts(ts)
47 AssertionValidator::~AssertionValidator()
51 void AssertionValidator::validate(const xmltooling::XMLObject* xmlObject) const
53 const Assertion* a=dynamic_cast<const Assertion*>(xmlObject);
55 throw ValidationException("Validator only applies to SAML 1.x Assertion objects.");
56 validateAssertion(*a);
59 void AssertionValidator::validateAssertion(const Assertion& assertion) const
62 xmltooling::NDC ndc("validate");
65 const Conditions* conds = assertion.getConditions();
69 // First verify the time conditions, using the specified timestamp, if non-zero.
71 unsigned int skew = XMLToolingConfig::getConfig().clock_skew_secs;
72 time_t t=conds->getNotBeforeEpoch();
74 throw ValidationException("Assertion is not yet valid.");
75 t=conds->getNotOnOrAfterEpoch();
77 throw ValidationException("Assertion is no longer valid.");
80 // Now we process conditions, starting with the known types and then extensions.
82 const vector<AudienceRestrictionCondition*>& acvec = conds->getAudienceRestrictionConditions();
83 for_each(acvec.begin(), acvec.end(), boost::bind(&AssertionValidator::validateCondition, this, _1));
85 const vector<DoNotCacheCondition*>& dncvec = conds->getDoNotCacheConditions();
86 for_each(dncvec.begin(), dncvec.end(), boost::bind(&AssertionValidator::validateCondition, this, _1));
88 const vector<Condition*>& convec = conds->getConditions();
89 for_each(convec.begin(), convec.end(), boost::bind(&AssertionValidator::validateCondition, this, _1));
92 void AssertionValidator::validateCondition(const Condition* c) const
94 const AudienceRestrictionCondition* ac=dynamic_cast<const AudienceRestrictionCondition*>(c);
96 Category::getInstance(SAML_LOGCAT".AssertionValidator").error("unrecognized Condition in assertion (%s)",
97 c->getSchemaType() ? c->getSchemaType()->toString().c_str() : c->getElementQName().toString().c_str());
98 throw ValidationException("Assertion contains an unrecognized condition.");
102 const vector<Audience*>& auds1 = ac->getAudiences();
103 for (vector<Audience*>::const_iterator a = auds1.begin(); !found && a!=auds1.end(); ++a) {
104 if (XMLString::equals(m_recipient, (*a)->getAudienceURI())) {
107 else if (m_audiences) {
108 for (vector<const XMLCh*>::const_iterator a2 = m_audiences->begin(); !found && a2!=m_audiences->end(); ++a2) {
109 found = XMLString::equals((*a)->getAudienceURI(), *a2);
117 Category::getInstance(SAML_LOGCAT".AssertionValidator").error(
118 "unacceptable AudienceRestrictionCondition in assertion (%s)", os.str().c_str()
120 throw ValidationException("Assertion contains an unacceptable AudienceRestrictionCondition.");