*
* <p>SAML 1.x identifiers will be promoted to the 2.0 type.
*
- * @return reference to a SAML 2.0 NameID
+ * @return a SAML 2.0 NameID associated with the session, if any
*/
- virtual const opensaml::saml2::NameID& getNameID() const=0;
+ virtual const opensaml::saml2::NameID* getNameID() const=0;
/**
* Returns the SessionIndex provided with the session.
* @param application reference to Application that owns the Session
* @param client_addr network address of client
* @param issuer issuing metadata of assertion issuer, if known
- * @param nameid principal identifier, normalized to SAML 2
- * @param authn_instant UTC timestamp of authentication at IdP
- * @param session_index index of session between principal and IdP
- * @param authncontext_class method/category of authentication event
- * @param authncontext_decl specifics of authentication event
+ * @param nameid principal identifier, normalized to SAML 2, if any
+ * @param authn_instant UTC timestamp of authentication at IdP, if known
+ * @param session_index index of session between principal and IdP, if any
+ * @param authncontext_class method/category of authentication event, if known
+ * @param authncontext_decl specifics of authentication event, if known
* @param tokens assertions to cache with session, if any
* @param attributes optional set of resolved Attributes to cache with session
* @return newly created session's key
virtual std::string insert(
time_t expires,
const Application& application,
- const char* client_addr,
- const opensaml::saml2md::EntityDescriptor* issuer,
- const opensaml::saml2::NameID& nameid,
+ const char* client_addr=NULL,
+ const opensaml::saml2md::EntityDescriptor* issuer=NULL,
+ const opensaml::saml2::NameID* nameid=NULL,
const char* authn_instant=NULL,
const char* session_index=NULL,
const char* authncontext_class=NULL,
* @param application reference to Application that owns the eventual Session
* @param client_addr network address of client
* @param issuer issuing metadata of assertion issuer, if known
- * @param nameid principal identifier, normalized to SAML 2
+ * @param nameid principal identifier, normalized to SAML 2, if any
* @param tokens assertions initiating the session, if any
* @return newly created ResolutionContext, owned by caller
*/
const Application& application,
const char* client_addr,
const opensaml::saml2md::EntityDescriptor* issuer,
- const opensaml::saml2::NameID& nameid,
+ const opensaml::saml2::NameID* nameid,
const std::vector<const opensaml::Assertion*>* tokens=NULL
) const=0;
*
* <p>SAML 1.x identifiers will be promoted to the 2.0 type.
*
- * @return reference to a SAML 2.0 NameID
+ * @return a SAML 2.0 NameID associated with the subject, if any
*/
- virtual const opensaml::saml2::NameID& getNameID() const=0;
+ virtual const opensaml::saml2::NameID* getNameID() const=0;
/**
* Returns unresolved tokens associated with the subject, if any.
const Application& application,\r
const char* client_addr,\r
const EntityDescriptor* issuer,\r
- const NameID& nameid,\r
+ const NameID* nameid,\r
const vector<const opensaml::Assertion*>* tokens=NULL\r
) : m_app(application), m_session(NULL), m_client_addr(client_addr), m_metadata(NULL), m_entity(issuer),\r
m_nameid(nameid), m_tokens(tokens) {\r
}\r
return NULL;\r
}\r
- const NameID& getNameID() const {\r
+ const NameID* getNameID() const {\r
return m_nameid;\r
}\r
const vector<const opensaml::Assertion*>* getTokens() const {\r
const char* m_client_addr;\r
mutable MetadataProvider* m_metadata;\r
mutable const EntityDescriptor* m_entity;\r
- const NameID& m_nameid;\r
+ const NameID* m_nameid;\r
const vector<const opensaml::Assertion*>* m_tokens;\r
vector<shibsp::Attribute*> m_attributes;\r
vector<opensaml::Assertion*> m_assertions;\r
const Application& application,\r
const char* client_addr,\r
const EntityDescriptor* issuer,\r
- const NameID& nameid,\r
+ const NameID* nameid,\r
const vector<const opensaml::Assertion*>* tokens=NULL\r
) const {\r
return new SimpleContext(application,client_addr,issuer,nameid,tokens);\r
map< pair<string,string>,pair<const AttributeDecoder*,string> >::const_iterator rule;\r
#endif\r
\r
- // Check the NameID based on the format.\r
const XMLCh* name;\r
- const XMLCh* format = ctx.getNameID().getFormat();\r
- if (!format || !*format)\r
- format = NameID::UNSPECIFIED;\r
+ const XMLCh* format;\r
+ \r
+ // Check the NameID based on the format.\r
+ if (ctx.getNameID()) {\r
+ format = ctx.getNameID()->getFormat();\r
+ if (!format || !*format)\r
+ format = NameID::UNSPECIFIED;\r
#ifdef HAVE_GOOD_STL\r
- if ((rule=m_attrMap.find(make_pair(format,xstring()))) != m_attrMap.end()) {\r
+ if ((rule=m_attrMap.find(make_pair(format,xstring()))) != m_attrMap.end()) {\r
#else\r
- auto_ptr_char temp(format);\r
- if ((rule=m_attrMap.find(make_pair(temp.get(),string()))) != m_attrMap.end()) {\r
+ auto_ptr_char temp(format);\r
+ if ((rule=m_attrMap.find(make_pair(temp.get(),string()))) != m_attrMap.end()) {\r
#endif\r
- if (aset.empty() || aset.count(rule->second.second)) {\r
- resolved.push_back(\r
- rule->second.first->decode(\r
- rule->second.second.c_str(), &ctx.getNameID(), assertingParty.get(), relyingParty\r
- )\r
- );\r
+ if (aset.empty() || aset.count(rule->second.second)) {\r
+ resolved.push_back(\r
+ rule->second.first->decode(\r
+ rule->second.second.c_str(), ctx.getNameID(), assertingParty.get(), relyingParty\r
+ )\r
+ );\r
+ }\r
}\r
}\r
\r
map< pair<string,string>,pair<const AttributeDecoder*,string> >::const_iterator rule;\r
#endif\r
\r
- // Check the NameID based on the format.\r
const XMLCh* name;\r
- const XMLCh* format = ctx.getNameID().getFormat();\r
- if (!format || !*format)\r
- format = NameID::UNSPECIFIED;\r
+ const XMLCh* format;\r
+ \r
+ // Check the NameID based on the format.\r
+ if (ctx.getNameID()) {\r
+ format = ctx.getNameID()->getFormat();\r
+ if (!format || !*format)\r
+ format = NameID::UNSPECIFIED;\r
#ifdef HAVE_GOOD_STL\r
- if ((rule=m_attrMap.find(make_pair(format,xstring()))) != m_attrMap.end()) {\r
+ if ((rule=m_attrMap.find(make_pair(format,xstring()))) != m_attrMap.end()) {\r
#else\r
- auto_ptr_char temp(format);\r
- if ((rule=m_attrMap.find(make_pair(temp.get(),string()))) != m_attrMap.end()) {\r
+ auto_ptr_char temp(format);\r
+ if ((rule=m_attrMap.find(make_pair(temp.get(),string()))) != m_attrMap.end()) {\r
#endif\r
- if (aset.empty() || aset.count(rule->second.second)) {\r
- resolved.push_back(\r
- rule->second.first->decode(\r
- rule->second.second.c_str(), &ctx.getNameID(), assertingParty.get(), relyingParty\r
- )\r
- );\r
+ if (aset.empty() || aset.count(rule->second.second)) {\r
+ resolved.push_back(\r
+ rule->second.first->decode(\r
+ rule->second.second.c_str(), ctx.getNameID(), assertingParty.get(), relyingParty\r
+ )\r
+ );\r
+ }\r
}\r
}\r
\r
\r
if (query) {\r
if (token1 && !token1->getAuthenticationStatements().empty()) {\r
- log.debug("attempting SAML 1.x attribute query");\r
- return m_impl->query(ctx, *(token1->getAuthenticationStatements().front()->getSubject()->getNameIdentifier()), attributes);\r
+ const AuthenticationStatement* statement = token1->getAuthenticationStatements().front();\r
+ if (statement && statement->getSubject() && statement->getSubject()->getNameIdentifier()) {\r
+ log.debug("attempting SAML 1.x attribute query");\r
+ return m_impl->query(ctx, *(statement->getSubject()->getNameIdentifier()), attributes);\r
+ }\r
+ }\r
+ else if (token2 && ctx.getNameID()) {\r
+ log.debug("attempting SAML 2.0 attribute query");\r
+ return m_impl->query(ctx, *ctx.getNameID(), attributes);\r
}\r
- log.debug("attempting SAML 2.0 attribute query");\r
- m_impl->query(ctx, ctx.getNameID(), attributes);\r
+ log.warn("can't attempt attribute query, no identifier in assertion subject");\r
}\r
}\r
\r
ResolutionContext* resolveAttributes(
const Application& application,
const opensaml::HTTPRequest& httpRequest,
- const opensaml::saml2md::EntityDescriptor* issuer,
- const opensaml::saml2::NameID& nameid,
+ const opensaml::saml2md::EntityDescriptor* issuer=NULL,
+ const opensaml::saml2::NameID* nameid=NULL,
const std::vector<const opensaml::Assertion*>* tokens=NULL
) const;
namespace shibsp {
SHIBSP_DLLLOCAL PluginManager<Handler,pair<const DOMElement*,const char*>>::Factory SAML1ConsumerFactory;
+ SHIBSP_DLLLOCAL PluginManager<Handler,pair<const DOMElement*,const char*>>::Factory SAML2ConsumerFactory;
};
void SHIBSP_API shibsp::registerHandlers()
SPConfig& conf=SPConfig::getConfig();
conf.AssertionConsumerServiceManager.registerFactory(SAML1_PROFILE_BROWSER_ARTIFACT, SAML1ConsumerFactory);
conf.AssertionConsumerServiceManager.registerFactory(SAML1_PROFILE_BROWSER_POST, SAML1ConsumerFactory);
+ conf.AssertionConsumerServiceManager.registerFactory(SAML20_BINDING_HTTP_ARTIFACT, SAML2ConsumerFactory);
+ conf.AssertionConsumerServiceManager.registerFactory(SAML20_BINDING_HTTP_POST, SAML2ConsumerFactory);
+ conf.AssertionConsumerServiceManager.registerFactory(SAML20_BINDING_HTTP_POST_SIMPLESIGN, SAML2ConsumerFactory);
}
AbstractHandler::AbstractHandler(
const Application& application,
const HTTPRequest& httpRequest,
const saml2md::EntityDescriptor* issuer,
- const saml2::NameID& nameid,
+ const saml2::NameID* nameid,
const vector<const Assertion*>* tokens
) const
{
// To complete processing, we need to resolve attributes and then create the session.
// First, normalize the SAML 1.x NameIdentifier...
- auto_ptr<NameID> nameid(NameIDBuilder::buildNameID());
NameIdentifier* n = ssoStatement->getSubject()->getNameIdentifier();
+ auto_ptr<NameID> nameid(n ? NameIDBuilder::buildNameID() : NULL);
if (n) {
nameid->setName(n->getName());
nameid->setFormat(n->getFormat());
const EntityDescriptor* issuerMetadata = dynamic_cast<const EntityDescriptor*>(policy.getIssuerMetadata()->getParent());
auto_ptr<ResolutionContext> ctx(
- resolveAttributes(application, httpRequest, issuerMetadata, *nameid.get(), &tokens)
+ resolveAttributes(application, httpRequest, issuerMetadata, nameid.get(), &tokens)
);
// Copy over any new tokens, but leave them in the context for cleanup.
application,
httpRequest.getRemoteAddr().c_str(),
issuerMetadata,
- *nameid.get(),
+ nameid.get(),
authnInstant.get(),
NULL,
authnMethod.get(),
RemotedSession(RemotedCache* cache, DDF& obj) : m_version(obj["version"].integer()), m_obj(obj),\r
m_nameid(NULL), m_expires(0), m_lastAccess(time(NULL)), m_cache(cache), m_lock(NULL) {\r
const char* nameid = obj["nameid"].string();\r
- if (!nameid)\r
- throw FatalProfileException("NameID missing from remotely cached session.");\r
- \r
- // Parse and bind the NameID into an XMLObject.\r
- istringstream instr(nameid);\r
- DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(instr); \r
- XercesJanitor<DOMDocument> janitor(doc);\r
- auto_ptr<saml2::NameID> n(saml2::NameIDBuilder::buildNameID());\r
- n->unmarshall(doc->getDocumentElement(), true);\r
- janitor.release();\r
+ if (nameid) {\r
+ // Parse and bind the NameID into an XMLObject.\r
+ istringstream instr(nameid);\r
+ DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(instr); \r
+ XercesJanitor<DOMDocument> janitor(doc);\r
+ auto_ptr<saml2::NameID> n(saml2::NameIDBuilder::buildNameID());\r
+ n->unmarshall(doc->getDocumentElement(), true);\r
+ janitor.release();\r
+ m_nameid = n.release();\r
+ }\r
\r
auto_ptr_XMLCh exp(m_obj["expires"].string());\r
if (exp.get()) {\r
}\r
\r
m_lock = Mutex::create();\r
- m_nameid = n.release();\r
}\r
\r
~RemotedSession() {\r
const char* getAuthnInstant() const {\r
return m_obj["authn_instant"].string();\r
}\r
- const opensaml::saml2::NameID& getNameID() const {\r
- return *m_nameid;\r
+ const opensaml::saml2::NameID* getNameID() const {\r
+ return m_nameid;\r
}\r
const char* getSessionIndex() const {\r
return m_obj["session_index"].string();\r
string insert(\r
time_t expires,\r
const Application& application,\r
- const char* client_addr,\r
- const saml2md::EntityDescriptor* issuer,\r
- const saml2::NameID& nameid,\r
+ const char* client_addr=NULL,\r
+ const saml2md::EntityDescriptor* issuer=NULL,\r
+ const saml2::NameID* nameid=NULL,\r
const char* authn_instant=NULL,\r
const char* session_index=NULL,\r
const char* authncontext_class=NULL,\r
const Application& application,\r
const char* client_addr,\r
const saml2md::EntityDescriptor* issuer,\r
- const saml2::NameID& nameid,\r
+ const saml2::NameID* nameid,\r
const char* authn_instant,\r
const char* session_index,\r
const char* authncontext_class,\r
in.addmember("expires").string(timebuf);\r
}\r
in.addmember("application_id").string(application.getId());\r
- in.addmember("client_addr").string(client_addr);\r
+ if (client_addr)\r
+ in.addmember("client_addr").string(client_addr);\r
if (issuer) {\r
auto_ptr_char provid(issuer->getEntityID());\r
in.addmember("entity_id").string(provid.get());\r
if (authncontext_decl)\r
in.addmember("authncontext_decl").string(authncontext_decl);\r
\r
- ostringstream namestr;\r
- namestr << nameid;\r
- in.addmember("nameid").string(namestr.str().c_str());\r
+ if (nameid) {\r
+ ostringstream namestr;\r
+ namestr << nameid;\r
+ in.addmember("nameid").string(namestr.str().c_str());\r
+ }\r
\r
if (tokens) {\r
in.addmember("assertions").list();\r
DDFJanitor jout(out);\r
if (out["key"].isstring()) {\r
// Transaction Logging\r
- auto_ptr_char name(nameid.getName());\r
+ auto_ptr_char name(nameid ? nameid->getName() : NULL);\r
const char* pid = in["entity_id"].string();\r
TransactionLog* xlog = application.getServiceProvider().getTransactionLog();\r
Locker locker(xlog);\r
") for principal from (IdP: " <<\r
(pid ? pid : "none") <<\r
") at (ClientAddress: " <<\r
- client_addr <<\r
+ (client_addr ? client_addr : "none") <<\r
") with (NameIdentifier: " <<\r
- name.get() <<\r
+ (name.get() ? name.get() : "none") <<\r
")";\r
\r
if (attributes) {\r
class StoredSession : public virtual Session\r
{\r
public:\r
- StoredSession(SSCache* cache, DDF& obj) : m_obj(obj), m_cache(cache) {\r
+ StoredSession(SSCache* cache, DDF& obj) : m_obj(obj), m_nameid(NULL), m_cache(cache) {\r
const char* nameid = obj["nameid"].string();\r
- if (!nameid)\r
- throw FatalProfileException("NameID missing from cached session.");\r
- \r
- // Parse and bind the document into an XMLObject.\r
- istringstream instr(nameid);\r
- DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(instr); \r
- XercesJanitor<DOMDocument> janitor(doc);\r
- auto_ptr<saml2::NameID> n(saml2::NameIDBuilder::buildNameID());\r
- n->unmarshall(doc->getDocumentElement(), true);\r
- janitor.release();\r
- m_nameid = n.release();\r
+ if (nameid) {\r
+ // Parse and bind the document into an XMLObject.\r
+ istringstream instr(nameid);\r
+ DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(instr); \r
+ XercesJanitor<DOMDocument> janitor(doc);\r
+ auto_ptr<saml2::NameID> n(saml2::NameIDBuilder::buildNameID());\r
+ n->unmarshall(doc->getDocumentElement(), true);\r
+ janitor.release();\r
+ m_nameid = n.release();\r
+ }\r
}\r
\r
~StoredSession();\r
const char* getAuthnInstant() const {\r
return m_obj["authn_instant"].string();\r
}\r
- const opensaml::saml2::NameID& getNameID() const {\r
- return *m_nameid;\r
+ const opensaml::saml2::NameID* getNameID() const {\r
+ return m_nameid;\r
}\r
const char* getSessionIndex() const {\r
return m_obj["session_index"].string();\r
string insert(\r
time_t expires,\r
const Application& application,\r
- const char* client_addr,\r
- const saml2md::EntityDescriptor* issuer,\r
- const saml2::NameID& nameid,\r
+ const char* client_addr=NULL,\r
+ const saml2md::EntityDescriptor* issuer=NULL,\r
+ const saml2::NameID* nameid=NULL,\r
const char* authn_instant=NULL,\r
const char* session_index=NULL,\r
const char* authncontext_class=NULL,\r
const Application& application,\r
const char* client_addr,\r
const saml2md::EntityDescriptor* issuer,\r
- const saml2::NameID& nameid,\r
+ const saml2::NameID* nameid,\r
const char* authn_instant,\r
const char* session_index,\r
const char* authncontext_class,\r
strftime(timebuf,32,"%Y-%m-%dT%H:%M:%SZ",ptime);\r
obj.addmember("expires").string(timebuf);\r
}\r
- obj.addmember("client_addr").string(client_addr);\r
+ if (client_addr)\r
+ obj.addmember("client_addr").string(client_addr);\r
if (issuer) {\r
auto_ptr_char entity_id(issuer->getEntityID());\r
obj.addmember("entity_id").string(entity_id.get());\r
if (authncontext_decl)\r
obj.addmember("authncontext_decl").string(authncontext_decl);\r
\r
- ostringstream namestr;\r
- namestr << nameid;\r
- obj.addmember("nameid").string(namestr.str().c_str());\r
- \r
+ if (nameid) {\r
+ ostringstream namestr;\r
+ namestr << nameid;\r
+ obj.addmember("nameid").string(namestr.str().c_str());\r
+ }\r
+\r
if (tokens) {\r
obj.addmember("assertions").list();\r
for (vector<const Assertion*>::const_iterator t = tokens->begin(); t!=tokens->end(); ++t) {\r
m_log.debug("new session created: SessionID (%s) IdP (%s) Address (%s)", key.get(), pid ? pid : "none", client_addr);\r
\r
// Transaction Logging\r
- auto_ptr_char name(nameid.getName());\r
+ auto_ptr_char name(nameid ? nameid->getName() : NULL);\r
TransactionLog* xlog = application.getServiceProvider().getTransactionLog();\r
Locker locker(xlog);\r
xlog->log.infoStream() <<\r
") for principal from (IdP: " <<\r
(pid ? pid : "none") <<\r
") at (ClientAddress: " <<\r
- client_addr <<\r
+ (client_addr ? client_addr : "none") <<\r
") with (NameIdentifier: " <<\r
- name.get() <<\r
+ (name.get() ? name.get() : "none") <<\r
")";\r
\r
if (attributes) {\r
RelativePath=".\handler\impl\SAML1Consumer.cpp"\r
>\r
</File>\r
+ <File\r
+ RelativePath=".\handler\impl\SAML2Consumer.cpp"\r
+ >\r
+ </File>\r
</Filter>\r
</Filter>\r
</Filter>\r