Back to index

nordugrid-arc-nox  1.1.0~rc6
SAML2SSO_AssertionConsumerSH.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <iostream>
00006 #include <fstream>
00007 
00008 #include <arc/message/PayloadSOAP.h>
00009 #include <arc/message/PayloadRaw.h>
00010 #include <arc/URL.h>
00011 #include <arc/DateTime.h>
00012 #include <arc/GUID.h>
00013 #include <arc/XMLNode.h>
00014 #include <arc/xmlsec/XmlSecUtils.h>
00015 #include <arc/xmlsec/saml_util.h>
00016 
00017 #include "SAML2SSO_AssertionConsumerSH.h"
00018 
00019 static Arc::Logger logger(Arc::Logger::rootLogger, "SAMLSSO_AssertionConsumerSH");
00020 
00021 Arc::Plugin* ArcSec::SAML2SSO_AssertionConsumerSH::get_sechandler(Arc::PluginArgument* arg) {
00022     ArcSec::SecHandlerPluginArgument* shcarg =
00023             arg?dynamic_cast<ArcSec::SecHandlerPluginArgument*>(arg):NULL;
00024     if(!shcarg) return NULL;
00025     return new ArcSec::SAML2SSO_AssertionConsumerSH((Arc::Config*)(*shcarg),(Arc::ChainContext*)(*shcarg));
00026 }
00027 
00028 /*
00029 sechandler_descriptors ARC_SECHANDLER_LOADER = {
00030     { "saml2ssoassertionconsumer.handler", 0, &get_sechandler},
00031     { NULL, 0, NULL }
00032 };
00033 */
00034 
00035 namespace ArcSec {
00036 using namespace Arc;
00037 
00038 SAML2SSO_AssertionConsumerSH::SAML2SSO_AssertionConsumerSH(Config *cfg,ChainContext*):SecHandler(cfg), SP_service_loader(NULL){
00039   if(!init_xmlsec()) return;
00040 }
00041 
00042 SAML2SSO_AssertionConsumerSH::~SAML2SSO_AssertionConsumerSH() {
00043   final_xmlsec();
00044   if(SP_service_loader) delete SP_service_loader;
00045 }
00046 
00047 bool SAML2SSO_AssertionConsumerSH::Handle(Arc::Message* msg) const {
00048   //Explaination: The SPService checks the authentication result (generated by IdP and sent by 
00049   //user agent) and records those successful authentication result into "SAMLAssertion". Since 
00050   //the real client (client to normal service) and user agent (client to SP service) share the 
00051   //same tcp/tls session (this is why only one copy of base class ClientTCP is needed in the 
00052   //ClientSAMLInterface), we can use the authentication result from user-agent/SPService for 
00053   //the decision-making in normal Client/Service interaction.
00054   //
00055   //Here the message which includes the endpoint "/saml2sp" is avoided, because
00056   //this specific endpoint is supposed to participate the SAML2 SSO prifile, check 
00057   //the authentication result from IdP and record the authentication information 
00058   //for later saml2ssp_serviceprovider handler, and itself should not be enforced 
00059   //the saml2sso_serviceprovider handler.
00060   std::string http_endpoint = msg->Attributes()->get("HTTP:ENDPOINT");
00061   std::size_t pos = http_endpoint.find("saml2sp");
00062   if(pos == std::string::npos) {  
00063     SecAttr* sattr = msg->Auth()->get("SAMLAssertion");
00064     if(!sattr) {
00065       logger.msg(ERROR, "Can not get SAMLAssertion SecAttr from message context");
00066       return false;
00067     }
00068 
00069     std::string str;
00070     XMLNode saml_assertion_nd;
00071     if(!(sattr->Export(SecAttr::SAML, saml_assertion_nd))) return false;
00072     saml_assertion_nd.GetXML(str);
00073     std::cout<<"SAML Assertion parsed by SP service: "<<str<<std::endl;
00074 
00075 
00076 
00077     return true;
00078   }
00079   else { return true; }
00080 
00081   return false;
00082 
00083   //TODO: Consume the saml assertion from client side (Push model): assertion inside soap message,
00084   //assertion inside x509 certificate as exention;
00085   //Or contact the IdP and get back the saml assertion related to the client(Pull model)
00086 
00087 }
00088 
00089 }
00090 
00091