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 * AssertionAttributeExtractor.cpp
24 * AttributeExtractor for SAML assertion content.
28 #include "Application.h"
29 #include "ServiceProvider.h"
30 #include "attribute/SimpleAttribute.h"
31 #include "attribute/resolver/AttributeExtractor.h"
33 #include <saml/saml1/core/Assertions.h>
34 #include <saml/saml2/core/Assertions.h>
35 #include <saml/saml2/metadata/Metadata.h>
36 #include <xmltooling/util/DateTime.h>
37 #include <xmltooling/util/XMLHelper.h>
38 #include <xercesc/util/XMLUniDefs.hpp>
40 using namespace shibsp;
41 using namespace opensaml::saml2;
42 using namespace opensaml::saml2md;
43 using namespace opensaml::saml1;
44 using namespace opensaml;
45 using namespace xmltooling;
50 #if defined (_MSC_VER)
51 #pragma warning( push )
52 #pragma warning( disable : 4250 )
55 class AssertionExtractor : public AttributeExtractor
58 AssertionExtractor(const DOMElement* e);
59 ~AssertionExtractor() {}
68 void extractAttributes(
69 const Application& application,
70 const RoleDescriptor* issuer,
71 const XMLObject& xmlObject,
72 vector<shibsp::Attribute*>& attributes
74 void getAttributeIds(vector<string>& attributes) const;
77 string m_authnAuthority,
84 m_sessionNotOnOrAfter,
89 #if defined (_MSC_VER)
90 #pragma warning( pop )
93 AttributeExtractor* SHIBSP_DLLLOCAL AssertionAttributeExtractorFactory(const DOMElement* const & e)
95 return new AssertionExtractor(e);
100 AssertionExtractor::AssertionExtractor(const DOMElement* e)
101 : m_authnAuthority(XMLHelper::getAttrString(e, nullptr, AuthenticatingAuthority::LOCAL_NAME)),
102 m_authnClass(XMLHelper::getAttrString(e, nullptr, AuthnContextClassRef::LOCAL_NAME)),
103 m_authnDecl(XMLHelper::getAttrString(e, nullptr, AuthnContextDeclRef::LOCAL_NAME)),
104 m_authnInstant(XMLHelper::getAttrString(e, nullptr, AuthnStatement::AUTHNINSTANT_ATTRIB_NAME)),
105 m_issuer(XMLHelper::getAttrString(e, nullptr, Issuer::LOCAL_NAME)),
106 m_notOnOrAfter(XMLHelper::getAttrString(e, nullptr, saml2::Conditions::NOTONORAFTER_ATTRIB_NAME)),
107 m_sessionIndex(XMLHelper::getAttrString(e, nullptr, AuthnStatement::SESSIONINDEX_ATTRIB_NAME)),
108 m_sessionNotOnOrAfter(XMLHelper::getAttrString(e, nullptr, AuthnStatement::SESSIONNOTONORAFTER_ATTRIB_NAME)),
109 m_subjectAddress(XMLHelper::getAttrString(e, nullptr, saml2::SubjectLocality::ADDRESS_ATTRIB_NAME)),
110 m_subjectDNS(XMLHelper::getAttrString(e, nullptr, saml2::SubjectLocality::DNSNAME_ATTRIB_NAME))
114 void AssertionExtractor::extractAttributes(
115 const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<shibsp::Attribute*>& attributes
118 const saml2::Assertion* saml2assertion = dynamic_cast<const saml2::Assertion*>(&xmlObject);
119 if (saml2assertion) {
121 if (!m_issuer.empty()) {
122 const Issuer* i = saml2assertion->getIssuer();
123 if (i && (!i->getFormat() || !*(i->getFormat()) || XMLString::equals(i->getFormat(), NameIDType::ENTITY))) {
124 auto_ptr<SimpleAttribute> issuer(new SimpleAttribute(vector<string>(1, m_issuer)));
125 auto_ptr_char temp(i->getName());
127 issuer->getValues().push_back(temp.get());
128 attributes.push_back(issuer.release());
134 if (!m_notOnOrAfter.empty() && saml2assertion->getConditions() && saml2assertion->getConditions()->getNotOnOrAfter()) {
135 auto_ptr<SimpleAttribute> notonorafter(new SimpleAttribute(vector<string>(1, m_notOnOrAfter)));
136 auto_ptr_char temp(saml2assertion->getConditions()->getNotOnOrAfter()->getRawData());
138 notonorafter->getValues().push_back(temp.get());
139 attributes.push_back(notonorafter.release());
144 const AuthnStatement* saml2statement = dynamic_cast<const AuthnStatement*>(&xmlObject);
145 if (saml2statement) {
147 if (!m_authnInstant.empty() && saml2statement->getAuthnInstant()) {
148 auto_ptr<SimpleAttribute> authninstant(new SimpleAttribute(vector<string>(1, m_authnInstant)));
149 auto_ptr_char temp(saml2statement->getAuthnInstant()->getRawData());
151 authninstant->getValues().push_back(temp.get());
152 attributes.push_back(authninstant.release());
157 if (!m_sessionIndex.empty() && saml2statement->getSessionIndex() && *(saml2statement->getSessionIndex())) {
158 auto_ptr<SimpleAttribute> sessionindex(new SimpleAttribute(vector<string>(1, m_sessionIndex)));
159 auto_ptr_char temp(saml2statement->getSessionIndex());
161 sessionindex->getValues().push_back(temp.get());
162 attributes.push_back(sessionindex.release());
166 // SessionNotOnOrAfter
167 if (!m_sessionNotOnOrAfter.empty() && saml2statement->getSessionNotOnOrAfter()) {
168 auto_ptr<SimpleAttribute> sessionnotonorafter(new SimpleAttribute(vector<string>(1, m_sessionNotOnOrAfter)));
169 auto_ptr_char temp(saml2statement->getSessionNotOnOrAfter()->getRawData());
171 sessionnotonorafter->getValues().push_back(temp.get());
172 attributes.push_back(sessionnotonorafter.release());
176 if (saml2statement->getSubjectLocality()) {
177 const saml2::SubjectLocality* locality = saml2statement->getSubjectLocality();
179 if (!m_subjectAddress.empty() && locality->getAddress() && *(locality->getAddress())) {
180 auto_ptr<SimpleAttribute> address(new SimpleAttribute(vector<string>(1, m_subjectAddress)));
181 auto_ptr_char temp(locality->getAddress());
183 address->getValues().push_back(temp.get());
184 attributes.push_back(address.release());
189 if (!m_subjectDNS.empty() && locality->getDNSName() && *(locality->getDNSName())) {
190 auto_ptr<SimpleAttribute> dns(new SimpleAttribute(vector<string>(1, m_subjectDNS)));
191 auto_ptr_char temp(locality->getDNSName());
193 dns->getValues().push_back(temp.get());
194 attributes.push_back(dns.release());
199 if (saml2statement->getAuthnContext()) {
200 const AuthnContext* ac = saml2statement->getAuthnContext();
201 // AuthnContextClassRef
202 if (!m_authnClass.empty() && ac->getAuthnContextClassRef() && ac->getAuthnContextClassRef()->getReference()) {
203 auto_ptr<SimpleAttribute> classref(new SimpleAttribute(vector<string>(1, m_authnClass)));
204 auto_ptr_char temp(ac->getAuthnContextClassRef()->getReference());
206 classref->getValues().push_back(temp.get());
207 attributes.push_back(classref.release());
211 // AuthnContextDeclRef
212 if (!m_authnDecl.empty() && ac->getAuthnContextDeclRef() && ac->getAuthnContextDeclRef()->getReference()) {
213 auto_ptr<SimpleAttribute> declref(new SimpleAttribute(vector<string>(1, m_authnDecl)));
214 auto_ptr_char temp(ac->getAuthnContextDeclRef()->getReference());
216 declref->getValues().push_back(temp.get());
217 attributes.push_back(declref.release());
221 // AuthenticatingAuthority
222 if (!m_authnAuthority.empty() && !ac->getAuthenticatingAuthoritys().empty()) {
223 auto_ptr<SimpleAttribute> attr(new SimpleAttribute(vector<string>(1, m_authnAuthority)));
224 const vector<AuthenticatingAuthority*>& authorities = ac->getAuthenticatingAuthoritys();
225 for (vector<AuthenticatingAuthority*>::const_iterator a = authorities.begin(); a != authorities.end(); ++a) {
226 auto_ptr_char temp((*a)->getID());
228 attr->getValues().push_back(temp.get());
230 if (attr->valueCount() > 0) {
231 attributes.push_back(attr.release());
237 const saml1::Assertion* saml1assertion = dynamic_cast<const saml1::Assertion*>(&xmlObject);
238 if (saml1assertion) {
240 if (!m_issuer.empty()) {
241 if (saml1assertion->getIssuer() && *(saml1assertion->getIssuer())) {
242 auto_ptr<SimpleAttribute> issuer(new SimpleAttribute(vector<string>(1, m_issuer)));
243 auto_ptr_char temp(saml1assertion->getIssuer());
245 issuer->getValues().push_back(temp.get());
246 attributes.push_back(issuer.release());
252 if (!m_notOnOrAfter.empty() && saml1assertion->getConditions() && saml1assertion->getConditions()->getNotOnOrAfter()) {
253 auto_ptr<SimpleAttribute> notonorafter(new SimpleAttribute(vector<string>(1, m_notOnOrAfter)));
254 auto_ptr_char temp(saml1assertion->getConditions()->getNotOnOrAfter()->getRawData());
256 notonorafter->getValues().push_back(temp.get());
257 attributes.push_back(notonorafter.release());
262 const AuthenticationStatement* saml1statement = dynamic_cast<const AuthenticationStatement*>(&xmlObject);
263 if (saml1statement) {
265 if (!m_authnInstant.empty() && saml1statement->getAuthenticationInstant()) {
266 auto_ptr<SimpleAttribute> authninstant(new SimpleAttribute(vector<string>(1, m_authnInstant)));
267 auto_ptr_char temp(saml1statement->getAuthenticationInstant()->getRawData());
269 authninstant->getValues().push_back(temp.get());
270 attributes.push_back(authninstant.release());
274 // AuthenticationMethod
275 if (!m_authnClass.empty() && saml1statement->getAuthenticationMethod() && *(saml1statement->getAuthenticationMethod())) {
276 auto_ptr<SimpleAttribute> authnmethod(new SimpleAttribute(vector<string>(1, m_authnClass)));
277 auto_ptr_char temp(saml1statement->getAuthenticationMethod());
279 authnmethod->getValues().push_back(temp.get());
280 attributes.push_back(authnmethod.release());
284 if (saml1statement->getSubjectLocality()) {
285 const saml1::SubjectLocality* locality = saml1statement->getSubjectLocality();
287 if (!m_subjectAddress.empty() && locality->getIPAddress() && *(locality->getIPAddress())) {
288 auto_ptr<SimpleAttribute> address(new SimpleAttribute(vector<string>(1, m_subjectAddress)));
289 auto_ptr_char temp(locality->getIPAddress());
291 address->getValues().push_back(temp.get());
292 attributes.push_back(address.release());
297 if (!m_subjectDNS.empty() && locality->getDNSAddress() && *(locality->getDNSAddress())) {
298 auto_ptr<SimpleAttribute> dns(new SimpleAttribute(vector<string>(1, m_subjectDNS)));
299 auto_ptr_char temp(locality->getDNSAddress());
301 dns->getValues().push_back(temp.get());
302 attributes.push_back(dns.release());
311 /*auto_ptr<SimpleAttribute> attr(new SimpleAttribute(vector<string>(1,m_attributeId)));
313 if (!(*s)->getAuthnContext() || (*s)->getAuthnContext()->getAuthenticatingAuthoritys().empty())
316 const vector<AuthenticatingAuthority*>& authorities =
317 const_cast<const AuthnContext*>((*s)->getAuthnContext())->getAuthenticatingAuthoritys();
318 for (vector<AuthenticatingAuthority*>::const_iterator a = authorities.begin(); a != authorities.end(); ++a) {
319 const XMLCh* n = (*a)->getID();
321 auto_ptr_char temp(n);
322 attr->getValues().push_back(temp.get());
326 if (attr->valueCount() > 0) {
327 attributes.push_back(attr.release());
334 void AssertionExtractor::getAttributeIds(vector<string>& attributes) const
336 if (!m_authnAuthority.empty())
337 attributes.push_back(m_authnAuthority);
338 if (!m_authnClass.empty())
339 attributes.push_back(m_authnClass);
340 if (!m_authnDecl.empty())
341 attributes.push_back(m_authnDecl);
342 if (!m_authnInstant.empty())
343 attributes.push_back(m_authnInstant);
344 if (!m_issuer.empty())
345 attributes.push_back(m_issuer);
346 if (!m_notOnOrAfter.empty())
347 attributes.push_back(m_notOnOrAfter);
348 if (!m_sessionIndex.empty())
349 attributes.push_back(m_sessionIndex);
350 if (!m_sessionNotOnOrAfter.empty())
351 attributes.push_back(m_sessionNotOnOrAfter);
352 if (!m_subjectAddress.empty())
353 attributes.push_back(m_subjectAddress);
354 if (!m_subjectDNS.empty())
355 attributes.push_back(m_subjectDNS);