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/Protocols.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,
90 #if defined (_MSC_VER)
91 #pragma warning( pop )
94 AttributeExtractor* SHIBSP_DLLLOCAL AssertionAttributeExtractorFactory(const DOMElement* const & e)
96 return new AssertionExtractor(e);
101 AssertionExtractor::AssertionExtractor(const DOMElement* e)
102 : m_authnAuthority(XMLHelper::getAttrString(e, nullptr, AuthenticatingAuthority::LOCAL_NAME)),
103 m_authnClass(XMLHelper::getAttrString(e, nullptr, AuthnContextClassRef::LOCAL_NAME)),
104 m_authnDecl(XMLHelper::getAttrString(e, nullptr, AuthnContextDeclRef::LOCAL_NAME)),
105 m_authnInstant(XMLHelper::getAttrString(e, nullptr, AuthnStatement::AUTHNINSTANT_ATTRIB_NAME)),
106 m_issuer(XMLHelper::getAttrString(e, nullptr, Issuer::LOCAL_NAME)),
107 m_notOnOrAfter(XMLHelper::getAttrString(e, nullptr, saml2::Conditions::NOTONORAFTER_ATTRIB_NAME)),
108 m_sessionIndex(XMLHelper::getAttrString(e, nullptr, AuthnStatement::SESSIONINDEX_ATTRIB_NAME)),
109 m_sessionNotOnOrAfter(XMLHelper::getAttrString(e, nullptr, AuthnStatement::SESSIONNOTONORAFTER_ATTRIB_NAME)),
110 m_subjectAddress(XMLHelper::getAttrString(e, nullptr, saml2::SubjectLocality::ADDRESS_ATTRIB_NAME)),
111 m_subjectDNS(XMLHelper::getAttrString(e, nullptr, saml2::SubjectLocality::DNSNAME_ATTRIB_NAME)),
112 m_consent(XMLHelper::getAttrString(e, nullptr, saml2p::StatusResponseType::CONSENT_ATTRIB_NAME))
116 void AssertionExtractor::extractAttributes(
117 const Application& application, const RoleDescriptor* issuer, const XMLObject& xmlObject, vector<shibsp::Attribute*>& attributes
120 const saml2p::StatusResponseType* srt = dynamic_cast<const saml2p::StatusResponseType*>(&xmlObject);
123 if (!m_consent.empty() && srt->getConsent()) {
124 auto_ptr_char temp(srt->getConsent());
125 if (temp.get() && *temp.get()) {
126 auto_ptr<SimpleAttribute> consent(new SimpleAttribute(vector<string>(1, m_consent)));
127 consent->getValues().push_back(temp.get());
128 attributes.push_back(consent.get());
135 const saml2::Assertion* saml2assertion = dynamic_cast<const saml2::Assertion*>(&xmlObject);
136 if (saml2assertion) {
138 if (!m_issuer.empty()) {
139 const Issuer* i = saml2assertion->getIssuer();
140 if (i && (!i->getFormat() || !*(i->getFormat()) || XMLString::equals(i->getFormat(), NameIDType::ENTITY))) {
141 auto_ptr_char temp(i->getName());
142 if (temp.get() && *temp.get()) {
143 auto_ptr<SimpleAttribute> issuer(new SimpleAttribute(vector<string>(1, m_issuer)));
144 issuer->getValues().push_back(temp.get());
145 attributes.push_back(issuer.get());
152 if (!m_notOnOrAfter.empty() && saml2assertion->getConditions() && saml2assertion->getConditions()->getNotOnOrAfter()) {
153 auto_ptr_char temp(saml2assertion->getConditions()->getNotOnOrAfter()->getRawData());
155 auto_ptr<SimpleAttribute> notonorafter(new SimpleAttribute(vector<string>(1, m_notOnOrAfter)));
156 notonorafter->getValues().push_back(temp.get());
157 attributes.push_back(notonorafter.get());
158 notonorafter.release();
165 const AuthnStatement* saml2statement = dynamic_cast<const AuthnStatement*>(&xmlObject);
166 if (saml2statement) {
168 if (!m_authnInstant.empty() && saml2statement->getAuthnInstant()) {
169 auto_ptr_char temp(saml2statement->getAuthnInstant()->getRawData());
171 auto_ptr<SimpleAttribute> authninstant(new SimpleAttribute(vector<string>(1, m_authnInstant)));
172 authninstant->getValues().push_back(temp.get());
173 attributes.push_back(authninstant.get());
174 authninstant.release();
179 if (!m_sessionIndex.empty() && saml2statement->getSessionIndex() && *(saml2statement->getSessionIndex())) {
180 auto_ptr_char temp(saml2statement->getSessionIndex());
182 auto_ptr<SimpleAttribute> sessionindex(new SimpleAttribute(vector<string>(1, m_sessionIndex)));
183 sessionindex->getValues().push_back(temp.get());
184 attributes.push_back(sessionindex.get());
185 sessionindex.release();
189 // SessionNotOnOrAfter
190 if (!m_sessionNotOnOrAfter.empty() && saml2statement->getSessionNotOnOrAfter()) {
191 auto_ptr_char temp(saml2statement->getSessionNotOnOrAfter()->getRawData());
193 auto_ptr<SimpleAttribute> sessionnotonorafter(new SimpleAttribute(vector<string>(1, m_sessionNotOnOrAfter)));
194 sessionnotonorafter->getValues().push_back(temp.get());
195 attributes.push_back(sessionnotonorafter.get());
196 sessionnotonorafter.release();
200 if (saml2statement->getSubjectLocality()) {
201 const saml2::SubjectLocality* locality = saml2statement->getSubjectLocality();
203 if (!m_subjectAddress.empty() && locality->getAddress() && *(locality->getAddress())) {
204 auto_ptr_char temp(locality->getAddress());
206 auto_ptr<SimpleAttribute> address(new SimpleAttribute(vector<string>(1, m_subjectAddress)));
207 address->getValues().push_back(temp.get());
208 attributes.push_back(address.get());
214 if (!m_subjectDNS.empty() && locality->getDNSName() && *(locality->getDNSName())) {
215 auto_ptr_char temp(locality->getDNSName());
217 auto_ptr<SimpleAttribute> dns(new SimpleAttribute(vector<string>(1, m_subjectDNS)));
218 dns->getValues().push_back(temp.get());
219 attributes.push_back(dns.get());
225 if (saml2statement->getAuthnContext()) {
226 const AuthnContext* ac = saml2statement->getAuthnContext();
227 // AuthnContextClassRef
228 if (!m_authnClass.empty() && ac->getAuthnContextClassRef() && ac->getAuthnContextClassRef()->getReference()) {
229 auto_ptr_char temp(ac->getAuthnContextClassRef()->getReference());
231 auto_ptr<SimpleAttribute> classref(new SimpleAttribute(vector<string>(1, m_authnClass)));
232 classref->getValues().push_back(temp.get());
233 attributes.push_back(classref.get());
238 // AuthnContextDeclRef
239 if (!m_authnDecl.empty() && ac->getAuthnContextDeclRef() && ac->getAuthnContextDeclRef()->getReference()) {
240 auto_ptr_char temp(ac->getAuthnContextDeclRef()->getReference());
242 auto_ptr<SimpleAttribute> declref(new SimpleAttribute(vector<string>(1, m_authnDecl)));
243 declref->getValues().push_back(temp.get());
244 attributes.push_back(declref.get());
249 // AuthenticatingAuthority
250 if (!m_authnAuthority.empty() && !ac->getAuthenticatingAuthoritys().empty()) {
251 auto_ptr<SimpleAttribute> attr(new SimpleAttribute(vector<string>(1, m_authnAuthority)));
252 const vector<AuthenticatingAuthority*>& authorities = ac->getAuthenticatingAuthoritys();
253 for (vector<AuthenticatingAuthority*>::const_iterator a = authorities.begin(); a != authorities.end(); ++a) {
254 auto_ptr_char temp((*a)->getID());
256 attr->getValues().push_back(temp.get());
258 if (attr->valueCount() > 0) {
259 attributes.push_back(attr.get());
268 const saml1::Assertion* saml1assertion = dynamic_cast<const saml1::Assertion*>(&xmlObject);
269 if (saml1assertion) {
271 if (!m_issuer.empty()) {
272 if (saml1assertion->getIssuer() && *(saml1assertion->getIssuer())) {
273 auto_ptr_char temp(saml1assertion->getIssuer());
275 auto_ptr<SimpleAttribute> issuer(new SimpleAttribute(vector<string>(1, m_issuer)));
276 issuer->getValues().push_back(temp.get());
277 attributes.push_back(issuer.get());
284 if (!m_notOnOrAfter.empty() && saml1assertion->getConditions() && saml1assertion->getConditions()->getNotOnOrAfter()) {
285 auto_ptr_char temp(saml1assertion->getConditions()->getNotOnOrAfter()->getRawData());
287 auto_ptr<SimpleAttribute> notonorafter(new SimpleAttribute(vector<string>(1, m_notOnOrAfter)));
288 notonorafter->getValues().push_back(temp.get());
289 attributes.push_back(notonorafter.get());
290 notonorafter.release();
297 const AuthenticationStatement* saml1statement = dynamic_cast<const AuthenticationStatement*>(&xmlObject);
298 if (saml1statement) {
300 if (!m_authnInstant.empty() && saml1statement->getAuthenticationInstant()) {
301 auto_ptr_char temp(saml1statement->getAuthenticationInstant()->getRawData());
303 auto_ptr<SimpleAttribute> authninstant(new SimpleAttribute(vector<string>(1, m_authnInstant)));
304 authninstant->getValues().push_back(temp.get());
305 attributes.push_back(authninstant.get());
306 authninstant.release();
310 // AuthenticationMethod
311 if (!m_authnClass.empty() && saml1statement->getAuthenticationMethod() && *(saml1statement->getAuthenticationMethod())) {
312 auto_ptr_char temp(saml1statement->getAuthenticationMethod());
314 auto_ptr<SimpleAttribute> authnmethod(new SimpleAttribute(vector<string>(1, m_authnClass)));
315 authnmethod->getValues().push_back(temp.get());
316 attributes.push_back(authnmethod.get());
317 authnmethod.release();
321 if (saml1statement->getSubjectLocality()) {
322 const saml1::SubjectLocality* locality = saml1statement->getSubjectLocality();
324 if (!m_subjectAddress.empty() && locality->getIPAddress() && *(locality->getIPAddress())) {
325 auto_ptr_char temp(locality->getIPAddress());
327 auto_ptr<SimpleAttribute> address(new SimpleAttribute(vector<string>(1, m_subjectAddress)));
328 address->getValues().push_back(temp.get());
329 attributes.push_back(address.get());
335 if (!m_subjectDNS.empty() && locality->getDNSAddress() && *(locality->getDNSAddress())) {
336 auto_ptr_char temp(locality->getDNSAddress());
338 auto_ptr<SimpleAttribute> dns(new SimpleAttribute(vector<string>(1, m_subjectDNS)));
339 dns->getValues().push_back(temp.get());
340 attributes.push_back(dns.get());
348 void AssertionExtractor::getAttributeIds(vector<string>& attributes) const
350 if (!m_authnAuthority.empty())
351 attributes.push_back(m_authnAuthority);
352 if (!m_authnClass.empty())
353 attributes.push_back(m_authnClass);
354 if (!m_authnDecl.empty())
355 attributes.push_back(m_authnDecl);
356 if (!m_authnInstant.empty())
357 attributes.push_back(m_authnInstant);
358 if (!m_issuer.empty())
359 attributes.push_back(m_issuer);
360 if (!m_notOnOrAfter.empty())
361 attributes.push_back(m_notOnOrAfter);
362 if (!m_sessionIndex.empty())
363 attributes.push_back(m_sessionIndex);
364 if (!m_sessionNotOnOrAfter.empty())
365 attributes.push_back(m_sessionNotOnOrAfter);
366 if (!m_subjectAddress.empty())
367 attributes.push_back(m_subjectAddress);
368 if (!m_subjectDNS.empty())
369 attributes.push_back(m_subjectDNS);
370 if (!m_consent.empty())
371 attributes.push_back(m_consent);