if (!policy.isAuthenticated())
throw SecurityPolicyException("Unable to establish security of incoming assertion.");
- saml1::NameIdentifier* saml1name=nullptr;
+ const saml1::NameIdentifier* saml1name=nullptr;
+ const saml1::AuthenticationStatement* saml1statement=nullptr;
saml2::NameID* saml2name=nullptr;
+ const saml2::AuthnStatement* saml2statement=nullptr;
const XMLCh* authMethod=nullptr;
const XMLCh* authInstant=nullptr;
time_t now = time(nullptr), sessionExp = 0;
// authnskew allows rejection of SSO if AuthnInstant is too old.
pair<bool,unsigned int> authnskew = sessionProps ? sessionProps->getUnsignedInt("maxTimeSinceAuthn") : pair<bool,unsigned int>(false,0);
- const saml1::AuthenticationStatement* ssoStatement=saml1token->getAuthenticationStatements().front();
- if (ssoStatement->getAuthenticationInstant()) {
- if (ssoStatement->getAuthenticationInstantEpoch() - XMLToolingConfig::getConfig().clock_skew_secs > now) {
+ saml1statement = saml1token->getAuthenticationStatements().front();
+ if (saml1statement->getAuthenticationInstant()) {
+ if (saml1statement->getAuthenticationInstantEpoch() - XMLToolingConfig::getConfig().clock_skew_secs > now) {
throw FatalProfileException("The login time at your identity provider was future-dated.");
}
- else if (authnskew.first && authnskew.second && ssoStatement->getAuthenticationInstantEpoch() <= now &&
- (now - ssoStatement->getAuthenticationInstantEpoch() > authnskew.second)) {
+ else if (authnskew.first && authnskew.second && saml1statement->getAuthenticationInstantEpoch() <= now &&
+ (now - saml1statement->getAuthenticationInstantEpoch() > authnskew.second)) {
throw FatalProfileException("The gap between now and the time you logged into your identity provider exceeds the allowed limit.");
}
}
}
// Address checking.
- saml1::SubjectLocality* locality = ssoStatement->getSubjectLocality();
+ saml1::SubjectLocality* locality = saml1statement->getSubjectLocality();
if (locality && locality->getIPAddress()) {
auto_ptr_char ip(locality->getIPAddress());
checkAddress(application, httpRequest, ip.get());
}
- saml1name = ssoStatement->getSubject()->getNameIdentifier();
- authMethod = ssoStatement->getAuthenticationMethod();
- if (ssoStatement->getAuthenticationInstant())
- authInstant = ssoStatement->getAuthenticationInstant()->getRawData();
+ saml1name = saml1statement->getSubject()->getNameIdentifier();
+ authMethod = saml1statement->getAuthenticationMethod();
+ if (saml1statement->getAuthenticationInstant())
+ authInstant = saml1statement->getAuthenticationInstant()->getRawData();
// Session expiration.
pair<bool,unsigned int> lifetime = sessionProps ? sessionProps->getUnsignedInt("lifetime") : pair<bool,unsigned int>(true,28800);
// authnskew allows rejection of SSO if AuthnInstant is too old.
pair<bool,unsigned int> authnskew = sessionProps ? sessionProps->getUnsignedInt("maxTimeSinceAuthn") : pair<bool,unsigned int>(false,0);
- const saml2::AuthnStatement* ssoStatement=saml2token->getAuthnStatements().front();
+ saml2statement = saml2token->getAuthnStatements().front();
if (authnskew.first && authnskew.second &&
- ssoStatement->getAuthnInstant() && (now - ssoStatement->getAuthnInstantEpoch() > authnskew.second))
+ saml2statement->getAuthnInstant() && (now - saml2statement->getAuthnInstantEpoch() > authnskew.second))
throw FatalProfileException("The gap between now and the time you logged into your identity provider exceeds the limit.");
// Address checking.
- saml2::SubjectLocality* locality = ssoStatement->getSubjectLocality();
+ saml2::SubjectLocality* locality = saml2statement->getSubjectLocality();
if (locality && locality->getAddress()) {
auto_ptr_char ip(locality->getAddress());
checkAddress(application, httpRequest, ip.get());
}
saml2name = saml2token->getSubject() ? saml2token->getSubject()->getNameID() : nullptr;
- if (ssoStatement->getAuthnContext() && ssoStatement->getAuthnContext()->getAuthnContextClassRef())
- authMethod = ssoStatement->getAuthnContext()->getAuthnContextClassRef()->getReference();
- if (ssoStatement->getAuthnInstant())
- authInstant = ssoStatement->getAuthnInstant()->getRawData();
+ if (saml2statement->getAuthnContext() && saml2statement->getAuthnContext()->getAuthnContextClassRef())
+ authMethod = saml2statement->getAuthnContext()->getAuthnContextClassRef()->getReference();
+ if (saml2statement->getAuthnInstant())
+ authInstant = saml2statement->getAuthnInstant()->getRawData();
// Session expiration for SAML 2.0 is jointly IdP- and SP-driven.
- sessionExp = ssoStatement->getSessionNotOnOrAfter() ? ssoStatement->getSessionNotOnOrAfterEpoch() : 0;
+ sessionExp = saml2statement->getSessionNotOnOrAfter() ? saml2statement->getSessionNotOnOrAfterEpoch() : 0;
pair<bool,unsigned int> lifetime = sessionProps ? sessionProps->getUnsignedInt("lifetime") : pair<bool,unsigned int>(true,28800);
if (!lifetime.first || lifetime.second == 0)
lifetime.second = 28800;
policy.getIssuerMetadata(),
m_protocol.get(),
saml1name,
+ saml1statement,
(saml1name ? nameid.get() : saml2name),
+ saml2statement,
authMethod,
nullptr,
&tokens
class SAML_API Assertion;
class SAML_API MessageDecoder;
namespace saml1 {
+ class SAML_API AuthenticationStatement;
class SAML_API NameIdentifier;
};
namespace saml2 {
+ class SAML_API AuthnStatement;
class SAML_API NameID;
};
namespace saml2md {
) const;
/**
+ * @deprecated
+ * Attempt SSO-initiated attribute resolution using the supplied information,
+ * including NameID and token extraction and filtering followed by
+ * secondary resolution.
+ *
+ * <p>The caller must free the returned context handle.
+ *
+ * @param application reference to application receiving message
+ * @param issuer source of SSO tokens
+ * @param protocol SSO protocol used
+ * @param v1nameid identifier of principal in SAML 1.x form, if any
+ * @param nameid identifier of principal in SAML 2.0 form
+ * @param authncontext_class method/category of authentication event, if known
+ * @param authncontext_decl specifics of authentication event, if known
+ * @param tokens available assertions, if any
+ */
+ ResolutionContext* resolveAttributes(
+ const Application& application,
+ const opensaml::saml2md::RoleDescriptor* issuer=nullptr,
+ const XMLCh* protocol=nullptr,
+ const opensaml::saml1::NameIdentifier* v1nameid=nullptr,
+ const opensaml::saml2::NameID* nameid=nullptr,
+ const XMLCh* authncontext_class=nullptr,
+ const XMLCh* authncontext_decl=nullptr,
+ const std::vector<const opensaml::Assertion*>* tokens=nullptr
+ ) const;
+
+ /**
+ * @deprecated
* Attempt SSO-initiated attribute resolution using the supplied information,
* including NameID and token extraction and filtering followed by
* secondary resolution.
const opensaml::saml2md::RoleDescriptor* issuer=nullptr,
const XMLCh* protocol=nullptr,
const opensaml::saml1::NameIdentifier* v1nameid=nullptr,
+ const opensaml::saml1::AuthenticationStatement* v1statement=nullptr,
const opensaml::saml2::NameID* nameid=nullptr,
+ const opensaml::saml2::AuthnStatement* statement=nullptr,
const XMLCh* authncontext_class=nullptr,
const XMLCh* authncontext_decl=nullptr,
const std::vector<const opensaml::Assertion*>* tokens=nullptr
const vector<const Assertion*>* tokens
) const
{
+ return resolveAttributes(
+ application,
+ issuer,
+ protocol,
+ v1nameid,
+ nullptr,
+ nameid,
+ nullptr,
+ authncontext_class,
+ authncontext_decl,
+ tokens
+ );
+}
+
+ResolutionContext* AssertionConsumerService::resolveAttributes(
+ const Application& application,
+ const saml2md::RoleDescriptor* issuer,
+ const XMLCh* protocol,
+ const saml1::NameIdentifier* v1nameid,
+ const saml1::AuthenticationStatement* v1statement,
+ const saml2::NameID* nameid,
+ const saml2::AuthnStatement* statement,
+ const XMLCh* authncontext_class,
+ const XMLCh* authncontext_decl,
+ const vector<const Assertion*>* tokens
+ ) const
+{
// First we do the extraction of any pushed information, including from metadata.
vector<Attribute*> resolvedAttributes;
AttributeExtractor* extractor = application.getAttributeExtractor();
}
}
}
+
m_log.debug("extracting pushed attributes...");
- if (v1nameid) {
+
+ if (v1nameid || nameid) {
try {
- extractor->extractAttributes(application, issuer, *v1nameid, resolvedAttributes);
+ if (v1nameid)
+ extractor->extractAttributes(application, issuer, *v1nameid, resolvedAttributes);
+ else
+ extractor->extractAttributes(application, issuer, *nameid, resolvedAttributes);
}
catch (exception& ex) {
m_log.error("caught exception extracting attributes: %s", ex.what());
}
}
- else if (nameid) {
+
+ if (v1statement || statement) {
try {
- extractor->extractAttributes(application, issuer, *nameid, resolvedAttributes);
+ if (v1statement)
+ extractor->extractAttributes(application, issuer, *v1statement, resolvedAttributes);
+ else
+ extractor->extractAttributes(application, issuer, *statement, resolvedAttributes);
}
catch (exception& ex) {
m_log.error("caught exception extracting attributes: %s", ex.what());
}
}
+
if (tokens) {
for (vector<const Assertion*>::const_iterator t = tokens->begin(); t!=tokens->end(); ++t) {
try {
(!response->getMinorVersion().first || response->getMinorVersion().second==1) ?
samlconstants::SAML11_PROTOCOL_ENUM : samlconstants::SAML10_PROTOCOL_ENUM,
n,
+ ssoStatement,
nameid.get(),
+ nullptr,
ssoStatement->getAuthenticationMethod(),
nullptr,
&tokens
policy.getIssuerMetadata(),
samlconstants::SAML20P_NS,
nullptr,
+ nullptr,
ssoName,
+ ssoStatement,
(authnContext && authnContext->getAuthnContextClassRef()) ? authnContext->getAuthnContextClassRef()->getReference() : nullptr,
(authnContext && authnContext->getAuthnContextDeclRef()) ? authnContext->getAuthnContextDeclRef()->getReference() : nullptr,
&tokens