Move artifact generation to a per-instance parameter.
authorScott Cantor <cantor.2@osu.edu>
Fri, 25 May 2007 16:12:13 +0000 (16:12 +0000)
committerScott Cantor <cantor.2@osu.edu>
Fri, 25 May 2007 16:12:13 +0000 (16:12 +0000)
13 files changed:
saml/binding/MessageEncoder.h
saml/saml1/binding/impl/SAML1ArtifactEncoder.cpp
saml/saml1/binding/impl/SAML1POSTEncoder.cpp
saml/saml1/binding/impl/SAML1SOAPEncoder.cpp
saml/saml2/binding/impl/SAML2ArtifactEncoder.cpp
saml/saml2/binding/impl/SAML2POSTEncoder.cpp
saml/saml2/binding/impl/SAML2RedirectEncoder.cpp
saml/saml2/binding/impl/SAML2SOAPEncoder.cpp
samltest/saml1/binding/SAML1ArtifactTest.h
samltest/saml1/binding/SAML1POSTTest.h
samltest/saml2/binding/SAML2ArtifactTest.h
samltest/saml2/binding/SAML2POSTTest.h
samltest/saml2/binding/SAML2RedirectTest.h

index 7941e02..fa8218d 100644 (file)
@@ -93,17 +93,6 @@ namespace opensaml {
         };
 
         /**
-         * Provides an ArtifactGenerator implementation for the MessageEncoder to use.
-         * The implementation's lifetime must be longer than the lifetime of this object. 
-         * This method must be externally synchronized. 
-         * 
-         * @param artifactGenerator   an ArtifactGenerator implementation to use
-         */
-        void setArtifactGenerator(ArtifactGenerator* artifactGenerator) {
-            m_artifactGenerator = artifactGenerator;
-        }
-        
-        /**
          * Encodes an XML object/message into a binding- and transport-specific response.
          * The XML content cannot have a parent object, and any existing references to
          * the content will be invalidated if the encode method returns successfully.
@@ -120,6 +109,7 @@ namespace opensaml {
          * @param destination       destination URL for message
          * @param recipient         optional message recipient
          * @param relayState        optional RelayState value to accompany message
+         * @param artifactGenerator optional interface for generation of artifacts
          * @param credential        optional Credential to supply signing key
          * @param signatureAlg      optional signature algorithm identifier
          * @param digestAlg         optional reference digest algorithm identifier
@@ -130,16 +120,14 @@ namespace opensaml {
             const char* destination,
             const saml2md::EntityDescriptor* recipient=NULL,
             const char* relayState=NULL,
+            const ArtifactGenerator* artifactGenerator=NULL,
             const xmltooling::Credential* credential=NULL,
             const XMLCh* signatureAlg=NULL,
             const XMLCh* digestAlg=NULL
             ) const=0;
 
     protected:
-        MessageEncoder() : m_artifactGenerator(NULL) {}
-        
-        /** Pointer to an ArtifactGenerator implementation. */
-        const ArtifactGenerator* m_artifactGenerator;
+        MessageEncoder() {}
     };
 
     /**
index 3d05905..50b395f 100644 (file)
@@ -58,6 +58,7 @@ namespace opensaml {
                 const char* destination,
                 const EntityDescriptor* recipient=NULL,
                 const char* relayState=NULL,
+                const ArtifactGenerator* artifactGenerator=NULL,
                 const Credential* credential=NULL,
                 const XMLCh* signatureAlg=NULL,
                 const XMLCh* digestAlg=NULL
@@ -77,6 +78,7 @@ long SAML1ArtifactEncoder::encode(
     const char* destination,
     const EntityDescriptor* recipient,
     const char* relayState,
+    const ArtifactGenerator* artifactGenerator,
     const Credential* credential,
     const XMLCh* signatureAlg,
     const XMLCh* digestAlg
@@ -106,11 +108,11 @@ long SAML1ArtifactEncoder::encode(
         throw BindingException("SAML 1.x Artifact Encoder requires ArtifactMap be set in configuration.");
 
     // Obtain a fresh artifact.
-    if (!m_artifactGenerator)
+    if (!artifactGenerator)
         throw BindingException("SAML 1.x Artifact Encoder requires an ArtifactGenerator instance.");
     auto_ptr_char recipientID(recipient ? recipient->getEntityID() : NULL);
     log.debug("obtaining new artifact for relying party (%s)", recipientID.get() ? recipientID.get() : "unknown");
-    auto_ptr<SAMLArtifact> artifact(m_artifactGenerator->generateSAML1Artifact(recipient));
+    auto_ptr<SAMLArtifact> artifact(artifactGenerator->generateSAML1Artifact(recipient));
     
     // Store the assertion. Last step in storage will be to delete the XML.
     log.debug("storing artifact and content in map");
index 4525a18..a99bc74 100644 (file)
@@ -55,6 +55,7 @@ namespace opensaml {
                 const char* destination,
                 const EntityDescriptor* recipient=NULL,
                 const char* relayState=NULL,
+                const ArtifactGenerator* artifactGenerator=NULL,
                 const Credential* credential=NULL,
                 const XMLCh* signatureAlg=NULL,
                 const XMLCh* digestAlg=NULL
@@ -91,6 +92,7 @@ long SAML1POSTEncoder::encode(
     const char* destination,
     const EntityDescriptor* recipient,
     const char* relayState,
+    const ArtifactGenerator* artifactGenerator,
     const Credential* credential,
     const XMLCh* signatureAlg,
     const XMLCh* digestAlg
index 197ee0b..e031adf 100644 (file)
@@ -55,6 +55,7 @@ namespace opensaml {
                 const char* destination,
                 const EntityDescriptor* recipient=NULL,
                 const char* relayState=NULL,
+                const ArtifactGenerator* artifactGenerator=NULL,
                 const Credential* credential=NULL,
                 const XMLCh* signatureAlg=NULL,
                 const XMLCh* digestAlg=NULL
@@ -74,6 +75,7 @@ long SAML1SOAPEncoder::encode(
     const char* destination,
     const EntityDescriptor* recipient,
     const char* relayState,
+    const ArtifactGenerator* artifactGenerator,
     const Credential* credential,
     const XMLCh* signatureAlg,
     const XMLCh* digestAlg
index 749d83d..a7d7500 100644 (file)
@@ -58,6 +58,7 @@ namespace opensaml {
                 const char* destination,
                 const EntityDescriptor* recipient=NULL,
                 const char* relayState=NULL,
+                const ArtifactGenerator* artifactGenerator=NULL,
                 const Credential* credential=NULL,
                 const XMLCh* signatureAlg=NULL,
                 const XMLCh* digestAlg=NULL
@@ -97,6 +98,7 @@ long SAML2ArtifactEncoder::encode(
     const char* destination,
     const EntityDescriptor* recipient,
     const char* relayState,
+    const ArtifactGenerator* artifactGenerator,
     const Credential* credential,
     const XMLCh* signatureAlg,
     const XMLCh* digestAlg
@@ -129,11 +131,11 @@ long SAML2ArtifactEncoder::encode(
         throw BindingException("SAML 2.0 HTTP-Artifact Encoder requires ArtifactMap be set in configuration.");
 
     // Obtain a fresh artifact.
-    if (!m_artifactGenerator)
+    if (!artifactGenerator)
         throw BindingException("SAML 2.0 HTTP-Artifact Encoder requires an ArtifactGenerator instance.");
     auto_ptr_char recipientID(recipient ? recipient->getEntityID() : NULL);
     log.debug("obtaining new artifact for relying party (%s)", recipientID.get() ? recipientID.get() : "unknown");
-    auto_ptr<SAMLArtifact> artifact(m_artifactGenerator->generateSAML2Artifact(recipient));
+    auto_ptr<SAMLArtifact> artifact(artifactGenerator->generateSAML2Artifact(recipient));
 
     if (credential) {
         // Signature based on native XML signing.
index efa5a57..add0e2e 100644 (file)
@@ -55,6 +55,7 @@ namespace opensaml {
                 const char* destination,
                 const EntityDescriptor* recipient=NULL,
                 const char* relayState=NULL,
+                const ArtifactGenerator* artifactGenerator=NULL,
                 const Credential* credential=NULL,
                 const XMLCh* signatureAlg=NULL,
                 const XMLCh* digestAlg=NULL
@@ -96,6 +97,7 @@ long SAML2POSTEncoder::encode(
     const char* destination,
     const EntityDescriptor* recipient,
     const char* relayState,
+    const ArtifactGenerator* artifactGenerator,
     const Credential* credential,
     const XMLCh* signatureAlg,
     const XMLCh* digestAlg
index 9135c8d..4026e82 100644 (file)
@@ -60,6 +60,7 @@ namespace opensaml {
                 const char* destination,
                 const EntityDescriptor* recipient=NULL,
                 const char* relayState=NULL,
+                const ArtifactGenerator* artifactGenerator=NULL,
                 const Credential* credential=NULL,
                 const XMLCh* signatureAlg=NULL,
                 const XMLCh* digestAlg=NULL
@@ -79,6 +80,7 @@ long SAML2RedirectEncoder::encode(
     const char* destination,
     const EntityDescriptor* recipient,
     const char* relayState,
+    const ArtifactGenerator* artifactGenerator,
     const Credential* credential,
     const XMLCh* signatureAlg,
     const XMLCh* digestAlg
index fccae38..65e135b 100644 (file)
@@ -55,6 +55,7 @@ namespace opensaml {
                 const char* destination,
                 const EntityDescriptor* recipient=NULL,
                 const char* relayState=NULL,
+                const ArtifactGenerator* artifactGenerator=NULL,
                 const Credential* credential=NULL,
                 const XMLCh* signatureAlg=NULL,
                 const XMLCh* digestAlg=NULL
@@ -76,6 +77,7 @@ long SAML2SOAPEncoder::encode(
     const char* destination,
     const EntityDescriptor* recipient,
     const char* relayState,
+    const ArtifactGenerator* artifactGenerator,
     const Credential* credential,
     const XMLCh* signatureAlg,
     const XMLCh* digestAlg
index d7ddf2c..6f628a3 100644 (file)
@@ -61,10 +61,9 @@ public:
             auto_ptr<MessageEncoder> encoder(\r
                 SAMLConfig::getConfig().MessageEncoderManager.newPlugin(samlconstants::SAML1_PROFILE_BROWSER_ARTIFACT, NULL)\r
                 );\r
-            encoder->setArtifactGenerator(this);\r
             Locker locker(m_metadata);\r
             encoder->encode(\r
-                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",cred\r
+                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",this,cred\r
                 );\r
             toSend.release();\r
             \r
index 81c1d7e..7a89c92 100644 (file)
@@ -73,7 +73,7 @@ public:
 
             Locker locker(m_metadata);
             encoder->encode(
-                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",cred
+                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",NULL,cred
                 );
             toSend.release();
             
index 336e403..05d832c 100644 (file)
-/*\r
- *  Copyright 2001-2007 Internet2\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-#include "binding.h"\r
-\r
-#include <saml/binding/ArtifactMap.h>\r
-#include <saml/saml2/core/Protocols.h>\r
-#include <saml/saml2/binding/SAML2ArtifactType0004.h>\r
-#include <xmltooling/validation/ValidatorSuite.h>\r
-\r
-using namespace opensaml::saml2p;\r
-using namespace opensaml::saml2;\r
-\r
-class SAML2ArtifactTest : public CxxTest::TestSuite,\r
-        public SAMLBindingBaseTestCase, public MessageEncoder::ArtifactGenerator, public MessageDecoder::ArtifactResolver {\r
-public:\r
-    void setUp() {\r
-        SAMLBindingBaseTestCase::setUp();\r
-    }\r
-\r
-    void tearDown() {\r
-        SAMLBindingBaseTestCase::tearDown();\r
-    }\r
-\r
-    void testSAML2Artifact() {\r
-        try {\r
-            QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);\r
-            SecurityPolicy policy(m_rules2, m_metadata, &idprole, m_trust, false);\r
-\r
-            // Read message to use from file.\r
-            string path = data_path + "saml2/binding/SAML2Response.xml";\r
-            ifstream in(path.c_str());\r
-            DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);\r
-            XercesJanitor<DOMDocument> janitor(doc);\r
-            auto_ptr<Response> toSend(\r
-                dynamic_cast<Response*>(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(),true))\r
-                );\r
-            janitor.release();\r
-\r
-            CredentialCriteria cc;\r
-            cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL);\r
-            Locker clocker(m_creds);\r
-            const Credential* cred = m_creds->resolve(&cc);\r
-            TSM_ASSERT("Retrieved credential was null", cred!=NULL);\r
-\r
-            // Freshen timestamp.\r
-            toSend->setIssueInstant(time(NULL));\r
-\r
-            // Encode message.\r
-            auto_ptr<MessageEncoder> encoder(\r
-                SAMLConfig::getConfig().MessageEncoderManager.newPlugin(samlconstants::SAML20_BINDING_HTTP_ARTIFACT, NULL)\r
-                );\r
-            encoder->setArtifactGenerator(this);\r
+/*
+ *  Copyright 2001-2007 Internet2
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "binding.h"
+
+#include <saml/binding/ArtifactMap.h>
+#include <saml/saml2/core/Protocols.h>
+#include <saml/saml2/binding/SAML2ArtifactType0004.h>
+#include <xmltooling/validation/ValidatorSuite.h>
+
+using namespace opensaml::saml2p;
+using namespace opensaml::saml2;
+
+class SAML2ArtifactTest : public CxxTest::TestSuite,
+        public SAMLBindingBaseTestCase, public MessageEncoder::ArtifactGenerator, public MessageDecoder::ArtifactResolver {
+public:
+    void setUp() {
+        SAMLBindingBaseTestCase::setUp();
+    }
+
+    void tearDown() {
+        SAMLBindingBaseTestCase::tearDown();
+    }
+
+    void testSAML2Artifact() {
+        try {
+            QName idprole(samlconstants::SAML20MD_NS, IDPSSODescriptor::LOCAL_NAME);
+            SecurityPolicy policy(m_rules2, m_metadata, &idprole, m_trust, false);
+
+            // Read message to use from file.
+            string path = data_path + "saml2/binding/SAML2Response.xml";
+            ifstream in(path.c_str());
+            DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(in);
+            XercesJanitor<DOMDocument> janitor(doc);
+            auto_ptr<Response> toSend(
+                dynamic_cast<Response*>(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(),true))
+                );
+            janitor.release();
+
+            CredentialCriteria cc;
+            cc.setUsage(CredentialCriteria::SIGNING_CREDENTIAL);
+            Locker clocker(m_creds);
+            const Credential* cred = m_creds->resolve(&cc);
+            TSM_ASSERT("Retrieved credential was null", cred!=NULL);
+
+            // Freshen timestamp.
+            toSend->setIssueInstant(time(NULL));
+
+            // Encode message.
+            auto_ptr<MessageEncoder> encoder(
+                SAMLConfig::getConfig().MessageEncoderManager.newPlugin(samlconstants::SAML20_BINDING_HTTP_ARTIFACT, NULL)
+                );
             Locker locker(m_metadata);
             encoder->encode(
-                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",cred
+                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",this,cred
+                );
+            toSend.release();
+            
+            // Decode message.
+            string relayState;
+            auto_ptr<MessageDecoder> decoder(
+                SAMLConfig::getConfig().MessageDecoderManager.newPlugin(samlconstants::SAML20_BINDING_HTTP_ARTIFACT, NULL)
                 );
-            toSend.release();\r
-            \r
-            // Decode message.\r
-            string relayState;\r
-            auto_ptr<MessageDecoder> decoder(\r
-                SAMLConfig::getConfig().MessageDecoderManager.newPlugin(samlconstants::SAML20_BINDING_HTTP_ARTIFACT, NULL)\r
-                );\r
-            decoder->setArtifactResolver(this);\r
-            auto_ptr<Response> response(dynamic_cast<Response*>(decoder->decode(relayState,*this,policy)));\r
-            \r
-            // Test the results.\r
-            TSM_ASSERT_EQUALS("RelayState was not the expected result.", relayState, "state");\r
-            TSM_ASSERT("SAML Response not decoded successfully.", response.get());\r
-            TSM_ASSERT("Message was not verified.", policy.isSecure());\r
-            auto_ptr_char entityID(policy.getIssuer()->getName());\r
-            TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));\r
-            TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);\r
-\r
-            // Trigger a replay.\r
-            policy.reset();\r
-            TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);\r
-        }\r
-        catch (XMLToolingException& ex) {\r
-            TS_TRACE(ex.what());\r
-            throw;\r
-        }\r
-    }\r
-    \r
-    SAMLArtifact* generateSAML1Artifact(const EntityDescriptor* relyingParty) const {\r
-        throw BindingException("Not implemented.");\r
-    }\r
-    \r
-    saml2p::SAML2Artifact* generateSAML2Artifact(const EntityDescriptor* relyingParty) const {\r
-        return new SAML2ArtifactType0004(SAMLConfig::getConfig().hashSHA1("https://idp.example.org/"),1);\r
-    }\r
-    \r
-    saml1p::Response* resolve(\r
-        const vector<SAMLArtifact*>& artifacts,\r
-        const IDPSSODescriptor& idpDescriptor,\r
-        SecurityPolicy& policy\r
-        ) const {\r
-        throw BindingException("Not implemented.");\r
-    }\r
-\r
-    ArtifactResponse* resolve(\r
-        const SAML2Artifact& artifact,\r
-        const SSODescriptorType& ssoDescriptor,\r
-        SecurityPolicy& policy\r
-        ) const {\r
-        XMLObject* xmlObject =\r
-            SAMLConfig::getConfig().getArtifactMap()->retrieveContent(&artifact, "https://sp.example.org/");\r
-        Response* payload = dynamic_cast<Response*>(xmlObject);\r
-        TSM_ASSERT("Not a response.", payload!=NULL);\r
-\r
-        auto_ptr<ArtifactResponse> response(ArtifactResponseBuilder::buildArtifactResponse());\r
-        response->setPayload(payload);\r
-        Status* status = StatusBuilder::buildStatus();\r
-        response->setStatus(status);\r
-        StatusCode* sc = StatusCodeBuilder::buildStatusCode();\r
-        status->setStatusCode(sc);\r
-        sc->setValue(StatusCode::SUCCESS);\r
-        response->marshall();\r
-        SchemaValidators.validate(response.get());\r
-        policy.evaluate(*(response.get()), this);\r
-        return response.release();\r
-    }\r
-};\r
+            decoder->setArtifactResolver(this);
+            auto_ptr<Response> response(dynamic_cast<Response*>(decoder->decode(relayState,*this,policy)));
+            
+            // Test the results.
+            TSM_ASSERT_EQUALS("RelayState was not the expected result.", relayState, "state");
+            TSM_ASSERT("SAML Response not decoded successfully.", response.get());
+            TSM_ASSERT("Message was not verified.", policy.isSecure());
+            auto_ptr_char entityID(policy.getIssuer()->getName());
+            TSM_ASSERT("Issuer was not expected.", !strcmp(entityID.get(),"https://idp.example.org/"));
+            TSM_ASSERT_EQUALS("Assertion count was not correct.", response->getAssertions().size(), 1);
+
+            // Trigger a replay.
+            policy.reset();
+            TSM_ASSERT_THROWS("Did not catch the replay.", decoder->decode(relayState,*this,policy), BindingException);
+        }
+        catch (XMLToolingException& ex) {
+            TS_TRACE(ex.what());
+            throw;
+        }
+    }
+    
+    SAMLArtifact* generateSAML1Artifact(const EntityDescriptor* relyingParty) const {
+        throw BindingException("Not implemented.");
+    }
+    
+    saml2p::SAML2Artifact* generateSAML2Artifact(const EntityDescriptor* relyingParty) const {
+        return new SAML2ArtifactType0004(SAMLConfig::getConfig().hashSHA1("https://idp.example.org/"),1);
+    }
+    
+    saml1p::Response* resolve(
+        const vector<SAMLArtifact*>& artifacts,
+        const IDPSSODescriptor& idpDescriptor,
+        SecurityPolicy& policy
+        ) const {
+        throw BindingException("Not implemented.");
+    }
+
+    ArtifactResponse* resolve(
+        const SAML2Artifact& artifact,
+        const SSODescriptorType& ssoDescriptor,
+        SecurityPolicy& policy
+        ) const {
+        XMLObject* xmlObject =
+            SAMLConfig::getConfig().getArtifactMap()->retrieveContent(&artifact, "https://sp.example.org/");
+        Response* payload = dynamic_cast<Response*>(xmlObject);
+        TSM_ASSERT("Not a response.", payload!=NULL);
+
+        auto_ptr<ArtifactResponse> response(ArtifactResponseBuilder::buildArtifactResponse());
+        response->setPayload(payload);
+        Status* status = StatusBuilder::buildStatus();
+        response->setStatus(status);
+        StatusCode* sc = StatusCodeBuilder::buildStatusCode();
+        status->setStatusCode(sc);
+        sc->setValue(StatusCode::SUCCESS);
+        response->marshall();
+        SchemaValidators.validate(response.get());
+        policy.evaluate(*(response.get()), this);
+        return response.release();
+    }
+};
index aed926c..7d4cf7d 100644 (file)
@@ -72,7 +72,7 @@ public:
                 );
             Locker locker(m_metadata);
             encoder->encode(
-                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",cred
+                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",NULL,cred
                 );
             toSend.release();
             
@@ -142,7 +142,7 @@ public:
                 );
             Locker locker(m_metadata);
             encoder->encode(
-                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",cred
+                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",NULL,cred
                 );
             toSend.release();
             
index 31df7f7..4eae178 100644 (file)
@@ -62,7 +62,7 @@ public:
                 );
             Locker locker(m_metadata);
             encoder->encode(
-                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",cred
+                *this,toSend.get(),"https://sp.example.org/SAML/SSO",m_metadata->getEntityDescriptor("https://sp.example.org/"),"state",NULL,cred
                 );
             toSend.release();