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_char temp(i->getName());
126 auto_ptr<SimpleAttribute> issuer(new SimpleAttribute(vector<string>(1, m_issuer)));
127 issuer->getValues().push_back(temp.get());
128 attributes.push_back(issuer.get());
135 if (!m_notOnOrAfter.empty() && saml2assertion->getConditions() && saml2assertion->getConditions()->getNotOnOrAfter()) {
136 auto_ptr_char temp(saml2assertion->getConditions()->getNotOnOrAfter()->getRawData());
138 auto_ptr<SimpleAttribute> notonorafter(new SimpleAttribute(vector<string>(1, m_notOnOrAfter)));
139 notonorafter->getValues().push_back(temp.get());
140 attributes.push_back(notonorafter.get());
141 notonorafter.release();
146 const AuthnStatement* saml2statement = dynamic_cast<const AuthnStatement*>(&xmlObject);
147 if (saml2statement) {
149 if (!m_authnInstant.empty() && saml2statement->getAuthnInstant()) {
150 auto_ptr_char temp(saml2statement->getAuthnInstant()->getRawData());
152 auto_ptr<SimpleAttribute> authninstant(new SimpleAttribute(vector<string>(1, m_authnInstant)));
153 authninstant->getValues().push_back(temp.get());
154 attributes.push_back(authninstant.get());
155 authninstant.release();
160 if (!m_sessionIndex.empty() && saml2statement->getSessionIndex() && *(saml2statement->getSessionIndex())) {
161 auto_ptr_char temp(saml2statement->getSessionIndex());
163 auto_ptr<SimpleAttribute> sessionindex(new SimpleAttribute(vector<string>(1, m_sessionIndex)));
164 sessionindex->getValues().push_back(temp.get());
165 attributes.push_back(sessionindex.get());
166 sessionindex.release();
170 // SessionNotOnOrAfter
171 if (!m_sessionNotOnOrAfter.empty() && saml2statement->getSessionNotOnOrAfter()) {
172 auto_ptr_char temp(saml2statement->getSessionNotOnOrAfter()->getRawData());
174 auto_ptr<SimpleAttribute> sessionnotonorafter(new SimpleAttribute(vector<string>(1, m_sessionNotOnOrAfter)));
175 sessionnotonorafter->getValues().push_back(temp.get());
176 attributes.push_back(sessionnotonorafter.get());
177 sessionnotonorafter.release();
181 if (saml2statement->getSubjectLocality()) {
182 const saml2::SubjectLocality* locality = saml2statement->getSubjectLocality();
184 if (!m_subjectAddress.empty() && locality->getAddress() && *(locality->getAddress())) {
185 auto_ptr_char temp(locality->getAddress());
187 auto_ptr<SimpleAttribute> address(new SimpleAttribute(vector<string>(1, m_subjectAddress)));
188 address->getValues().push_back(temp.get());
189 attributes.push_back(address.get());
195 if (!m_subjectDNS.empty() && locality->getDNSName() && *(locality->getDNSName())) {
196 auto_ptr_char temp(locality->getDNSName());
198 auto_ptr<SimpleAttribute> dns(new SimpleAttribute(vector<string>(1, m_subjectDNS)));
199 dns->getValues().push_back(temp.get());
200 attributes.push_back(dns.get());
206 if (saml2statement->getAuthnContext()) {
207 const AuthnContext* ac = saml2statement->getAuthnContext();
208 // AuthnContextClassRef
209 if (!m_authnClass.empty() && ac->getAuthnContextClassRef() && ac->getAuthnContextClassRef()->getReference()) {
210 auto_ptr_char temp(ac->getAuthnContextClassRef()->getReference());
212 auto_ptr<SimpleAttribute> classref(new SimpleAttribute(vector<string>(1, m_authnClass)));
213 classref->getValues().push_back(temp.get());
214 attributes.push_back(classref.get());
219 // AuthnContextDeclRef
220 if (!m_authnDecl.empty() && ac->getAuthnContextDeclRef() && ac->getAuthnContextDeclRef()->getReference()) {
221 auto_ptr_char temp(ac->getAuthnContextDeclRef()->getReference());
223 auto_ptr<SimpleAttribute> declref(new SimpleAttribute(vector<string>(1, m_authnDecl)));
224 declref->getValues().push_back(temp.get());
225 attributes.push_back(declref.get());
230 // AuthenticatingAuthority
231 if (!m_authnAuthority.empty() && !ac->getAuthenticatingAuthoritys().empty()) {
232 auto_ptr<SimpleAttribute> attr(new SimpleAttribute(vector<string>(1, m_authnAuthority)));
233 const vector<AuthenticatingAuthority*>& authorities = ac->getAuthenticatingAuthoritys();
234 for (vector<AuthenticatingAuthority*>::const_iterator a = authorities.begin(); a != authorities.end(); ++a) {
235 auto_ptr_char temp((*a)->getID());
237 attr->getValues().push_back(temp.get());
239 if (attr->valueCount() > 0) {
240 attributes.push_back(attr.get());
247 const saml1::Assertion* saml1assertion = dynamic_cast<const saml1::Assertion*>(&xmlObject);
248 if (saml1assertion) {
250 if (!m_issuer.empty()) {
251 if (saml1assertion->getIssuer() && *(saml1assertion->getIssuer())) {
252 auto_ptr_char temp(saml1assertion->getIssuer());
254 auto_ptr<SimpleAttribute> issuer(new SimpleAttribute(vector<string>(1, m_issuer)));
255 issuer->getValues().push_back(temp.get());
256 attributes.push_back(issuer.get());
263 if (!m_notOnOrAfter.empty() && saml1assertion->getConditions() && saml1assertion->getConditions()->getNotOnOrAfter()) {
264 auto_ptr_char temp(saml1assertion->getConditions()->getNotOnOrAfter()->getRawData());
266 auto_ptr<SimpleAttribute> notonorafter(new SimpleAttribute(vector<string>(1, m_notOnOrAfter)));
267 notonorafter->getValues().push_back(temp.get());
268 attributes.push_back(notonorafter.get());
269 notonorafter.release();
274 const AuthenticationStatement* saml1statement = dynamic_cast<const AuthenticationStatement*>(&xmlObject);
275 if (saml1statement) {
277 if (!m_authnInstant.empty() && saml1statement->getAuthenticationInstant()) {
278 auto_ptr_char temp(saml1statement->getAuthenticationInstant()->getRawData());
280 auto_ptr<SimpleAttribute> authninstant(new SimpleAttribute(vector<string>(1, m_authnInstant)));
281 authninstant->getValues().push_back(temp.get());
282 attributes.push_back(authninstant.get());
283 authninstant.release();
287 // AuthenticationMethod
288 if (!m_authnClass.empty() && saml1statement->getAuthenticationMethod() && *(saml1statement->getAuthenticationMethod())) {
289 auto_ptr_char temp(saml1statement->getAuthenticationMethod());
291 auto_ptr<SimpleAttribute> authnmethod(new SimpleAttribute(vector<string>(1, m_authnClass)));
292 authnmethod->getValues().push_back(temp.get());
293 attributes.push_back(authnmethod.get());
294 authnmethod.release();
298 if (saml1statement->getSubjectLocality()) {
299 const saml1::SubjectLocality* locality = saml1statement->getSubjectLocality();
301 if (!m_subjectAddress.empty() && locality->getIPAddress() && *(locality->getIPAddress())) {
302 auto_ptr_char temp(locality->getIPAddress());
304 auto_ptr<SimpleAttribute> address(new SimpleAttribute(vector<string>(1, m_subjectAddress)));
305 address->getValues().push_back(temp.get());
306 attributes.push_back(address.get());
312 if (!m_subjectDNS.empty() && locality->getDNSAddress() && *(locality->getDNSAddress())) {
313 auto_ptr_char temp(locality->getDNSAddress());
315 auto_ptr<SimpleAttribute> dns(new SimpleAttribute(vector<string>(1, m_subjectDNS)));
316 dns->getValues().push_back(temp.get());
317 attributes.push_back(dns.get());
328 void AssertionExtractor::getAttributeIds(vector<string>& attributes) const
330 if (!m_authnAuthority.empty())
331 attributes.push_back(m_authnAuthority);
332 if (!m_authnClass.empty())
333 attributes.push_back(m_authnClass);
334 if (!m_authnDecl.empty())
335 attributes.push_back(m_authnDecl);
336 if (!m_authnInstant.empty())
337 attributes.push_back(m_authnInstant);
338 if (!m_issuer.empty())
339 attributes.push_back(m_issuer);
340 if (!m_notOnOrAfter.empty())
341 attributes.push_back(m_notOnOrAfter);
342 if (!m_sessionIndex.empty())
343 attributes.push_back(m_sessionIndex);
344 if (!m_sessionNotOnOrAfter.empty())
345 attributes.push_back(m_sessionNotOnOrAfter);
346 if (!m_subjectAddress.empty())
347 attributes.push_back(m_subjectAddress);
348 if (!m_subjectDNS.empty())
349 attributes.push_back(m_subjectDNS);