X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=shibsp%2Fhandler%2Fimpl%2FSAML2SessionInitiator.cpp;h=2fc3cd9c33d46f21dd903352ea43b52ae6bd3b1d;hb=e4d0de20ceb5754ef302d74c6276164fbd259fb4;hp=600f45eda5dea6bea8a09bda6a27130f9e447a51;hpb=d0d35cedf14334057f56b2c2293c4cdabe2fefa5;p=shibboleth%2Fsp.git diff --git a/shibsp/handler/impl/SAML2SessionInitiator.cpp b/shibsp/handler/impl/SAML2SessionInitiator.cpp index 600f45e..2fc3cd9 100644 --- a/shibsp/handler/impl/SAML2SessionInitiator.cpp +++ b/shibsp/handler/impl/SAML2SessionInitiator.cpp @@ -74,8 +74,10 @@ namespace shibsp { HTTPResponse& httpResponse, const char* entityID, const XMLCh* acsIndex, - const XMLCh* acsLocation, + const char* acsLocation, const XMLCh* acsBinding, + bool isPassive, + bool forceAuthn, string& relayState ) const; @@ -165,6 +167,9 @@ pair SAML2SessionInitiator::run(SPRequest& request, const char* entit string target; const Handler* ACS=NULL; const char* option; + pair acClass; + pair acComp; + bool isPassive=false,forceAuthn=false; const Application& app=request.getApplication(); pair acsByIndex = getBool("acsByIndex"); @@ -181,11 +186,34 @@ pair SAML2SessionInitiator::run(SPRequest& request, const char* entit // so we'll need the target resource for real. recoverRelayState(request.getApplication(), request, target, false); } + + option = request.getParameter("isPassive"); + isPassive = (option && (*option=='1' || *option=='t')); + if (!isPassive) { + option = request.getParameter("forceAuthn"); + forceAuthn = (option && (*option=='1' || *option=='t')); + } + + acClass.second = request.getParameter("authnContextClassRef"); + acClass.first = (acClass.second!=NULL); + acComp.second = request.getParameter("authnContextComparison"); + acComp.first = (acComp.second!=NULL); } else { // We're running as a "virtual handler" from within the filter. // The target resource is the current one and everything else is defaulted. target=request.getRequestURL(); + const PropertySet* settings = request.getRequestSettings().first; + + pair flag = settings->getBool("isPassive"); + isPassive = flag.first && flag.second; + if (!isPassive) { + flag = settings->getBool("forceAuthn"); + forceAuthn = flag.first && flag.second; + } + + acClass = settings->getString("authnContextClassRef"); + acComp = settings->getString("authnContextComparison"); } m_log.debug("attempting to initiate session using SAML 2.0 with provider (%s)", entityID); @@ -205,7 +233,9 @@ pair SAML2SessionInitiator::run(SPRequest& request, const char* entit if (option) target = option; } - return doRequest(app, request, entityID, ACS ? ACS->getXMLString("index").second : NULL, NULL, NULL, target); + return doRequest( + app, request, entityID, ACS ? ACS->getXMLString("index").second : NULL, NULL, NULL, isPassive, forceAuthn, target + ); } // Since we're not passing by index, we need to fully compute the return URL and binding. @@ -226,8 +256,9 @@ pair SAML2SessionInitiator::run(SPRequest& request, const char* entit target = option; } - auto_ptr_XMLCh wideloc(ACSloc.c_str()); - return doRequest(app, request, entityID, NULL, wideloc.get(), ACS ? ACS->getXMLString("Binding").second : NULL, target); + return doRequest( + app, request, entityID, NULL, ACSloc.c_str(), ACS ? ACS->getXMLString("Binding").second : NULL, isPassive, forceAuthn, target + ); } // Remote the call. @@ -235,6 +266,14 @@ pair SAML2SessionInitiator::run(SPRequest& request, const char* entit DDFJanitor jin(in), jout(out); in.addmember("application_id").string(app.getId()); in.addmember("entity_id").string(entityID); + if (isPassive) + in.addmember("isPassive").integer(1); + else if (forceAuthn) + in.addmember("forceAuthn").integer(1); + if (acClass.first) + in.addmember("authnContextClassRef").string(acClass.second); + if (acComp.first) + in.addmember("authnContextComparison").string(acComp.second); if (acsByIndex.first && acsByIndex.second) { if (ACS) in.addmember("acsIndex").string(ACS->getString("index").second); @@ -291,7 +330,6 @@ void SAML2SessionInitiator::receive(DDF& in, ostream& out) auto_ptr http(getResponse(ret)); auto_ptr_XMLCh index(in["acsIndex"].string()); - auto_ptr_XMLCh loc(in["acsLocation"].string()); auto_ptr_XMLCh bind(in["acsBinding"].string()); string relayState(in["RelayState"].string() ? in["RelayState"].string() : ""); @@ -299,7 +337,12 @@ void SAML2SessionInitiator::receive(DDF& in, ostream& out) // Since we're remoted, the result should either be a throw, which we pass on, // a false/0 return, which we just return as an empty structure, or a response/redirect, // which we capture in the facade and send back. - doRequest(*app, *http.get(), entityID, index.get(), loc.get(), bind.get(), relayState); + doRequest( + *app, *http.get(), entityID, + index.get(), in["acsLocation"].string(), bind.get(), + in["isPassive"].integer()==1, in["forceAuthn"].integer()==1, + relayState + ); out << ret; } @@ -308,8 +351,10 @@ pair SAML2SessionInitiator::doRequest( HTTPResponse& httpResponse, const char* entityID, const XMLCh* acsIndex, - const XMLCh* acsLocation, + const char* acsLocation, const XMLCh* acsBinding, + bool isPassive, + bool forceAuthn, string& relayState ) const { @@ -351,10 +396,16 @@ pair SAML2SessionInitiator::doRequest( req->setDestination(ep->getLocation()); if (acsIndex) req->setAssertionConsumerServiceIndex(acsIndex); - if (acsLocation) - req->setAssertionConsumerServiceURL(acsLocation); + if (acsLocation) { + auto_ptr_XMLCh wideloc(acsLocation); + req->setAssertionConsumerServiceURL(wideloc.get()); + } if (acsBinding) req->setProtocolBinding(acsBinding); + if (isPassive) + req->IsPassive(isPassive); + else if (forceAuthn) + req->ForceAuthn(forceAuthn); Issuer* issuer = IssuerBuilder::buildIssuer(); req->setIssuer(issuer); issuer->setName(app.getXMLString("providerId").second);