saml1/binding/SAML1ArtifactEncoder.h \
saml1/binding/SAML1POSTDecoder.h \
saml1/binding/SAML1POSTEncoder.h \
- saml1/binding/SAML1SOAPDecoder.h
+ saml1/binding/SAML1SOAPDecoder.h \
+ saml1/binding/SAML1SOAPEncoder.h
saml2coreinclude_HEADERS = \
saml2/core/Assertions.h \
saml1/binding/impl/SAML1POSTDecoder.cpp \
saml1/binding/impl/SAML1POSTEncoder.cpp \
saml1/binding/impl/SAML1SOAPDecoder.cpp \
+ saml1/binding/impl/SAML1SOAPEncoder.cpp \
saml2/core/impl/Assertions20Impl.cpp \
saml2/core/impl/Assertions20SchemaValidators.cpp \
saml2/core/impl/Protocols20Impl.cpp \
virtual void setContentType(const char* type=NULL)=0;
/**
+ * Sends a completed response to the client along with a
+ * transport-specific "OK" indication. Used for "normal" responses.
+ *
+ * @param inputStream reference to source of response data
+ * @return a result code to return from the calling MessageEncoder
+ */
+ virtual long sendResponse(std::istream& inputStream)=0;
+
+ /**
+ * Sends an "error" response to the client along with a
+ * transport-specific error indication.
+ *
+ * @param inputStream reference to source of response data
+ * @return a result code to return from the calling MessageEncoder
+ */
+ virtual long sendError(std::istream& inputStream)=0;
+
+ /**
* Sends a completed response to the client.
*
* @param inputStream reference to source of response data
/** Some common HTTP status codes. */
enum status_t {
SAML_HTTP_STATUS_OK = 200,
- SAML_HTTP_STATUS_MOVED = 302
+ SAML_HTTP_STATUS_MOVED = 302,
+ SAML_HTTP_STATUS_ERROR = 500
};
};
};
>\r
</File>\r
<File\r
+ RelativePath=".\saml1\binding\impl\SAML1SOAPEncoder.cpp"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\saml1\binding\impl\SAMLArtifactType0001.cpp"\r
>\r
</File>\r
>\r
</File>\r
<File\r
+ RelativePath=".\saml1\binding\SAML1SOAPEncoder.h"\r
+ >\r
+ </File>\r
+ <File\r
RelativePath=".\saml1\binding\SAMLArtifactType0001.h"\r
>\r
</File>\r
{
public:
SAML1ArtifactDecoder(const DOMElement* e);
- virtual ~SAML1ArtifactDecoder();
+ virtual ~SAML1ArtifactDecoder() {}
Response* decode(
std::string& relayState,
{
public:
SAML1ArtifactEncoder(const DOMElement* e);
- virtual ~SAML1ArtifactEncoder();
+ virtual ~SAML1ArtifactEncoder() {}
long encode(
GenericResponse& genericResponse,
{
public:
SAML1POSTDecoder(const DOMElement* e);
- virtual ~SAML1POSTDecoder();
+ virtual ~SAML1POSTDecoder() {}
Response* decode(
std::string& relayState,
{
public:
SAML1POSTEncoder(const DOMElement* e);
- virtual ~SAML1POSTEncoder();
+ virtual ~SAML1POSTEncoder() {}
long encode(
GenericResponse& genericResponse,
--- /dev/null
+/*
+ * Copyright 2001-2006 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.
+ */
+
+/**
+ * @file saml/saml1/binding/SAML1SOAPEncoder.h
+ *
+ * SAML 1.x SOAP binding message encoder
+ */
+
+#include <saml/binding/MessageEncoder.h>
+
+
+namespace opensaml {
+ namespace saml1p {
+
+ /**
+ * SAML 1.x POST binding/profile message encoder
+ */
+ class SAML_API SAML1SOAPEncoder : public MessageEncoder
+ {
+ public:
+ SAML1SOAPEncoder(const DOMElement* e);
+ virtual ~SAML1SOAPEncoder() {}
+
+ long encode(
+ GenericResponse& genericResponse,
+ xmltooling::XMLObject* xmlObject,
+ const char* destination,
+ const char* recipientID=NULL,
+ const char* relayState=NULL,
+ const xmlsignature::CredentialResolver* credResolver=NULL,
+ const XMLCh* sigAlgorithm=NULL
+ ) const;
+ };
+
+ };
+};
SAML1ArtifactDecoder::SAML1ArtifactDecoder(const DOMElement* e) {}
-SAML1ArtifactDecoder::~SAML1ArtifactDecoder() {}
-
Response* SAML1ArtifactDecoder::decode(
string& relayState,
const GenericRequest& genericRequest,
SAML1ArtifactEncoder::SAML1ArtifactEncoder(const DOMElement* e) {}
-SAML1ArtifactEncoder::~SAML1ArtifactEncoder() {}
-
long SAML1ArtifactEncoder::encode(
GenericResponse& genericResponse,
XMLObject* xmlObject,
SAML1POSTDecoder::SAML1POSTDecoder(const DOMElement* e) {}
-SAML1POSTDecoder::~SAML1POSTDecoder() {}
-
Response* SAML1POSTDecoder::decode(
string& relayState,
const GenericRequest& genericRequest,
#include "internal.h"
#include "exceptions.h"
-#include "binding/HTTPResponse.h"
#include "saml1/binding/SAML1POSTEncoder.h"
#include "saml1/core/Protocols.h"
throw XMLToolingException("SAML1POSTEncoder requires template attribute.");
}
-SAML1POSTEncoder::~SAML1POSTEncoder() {}
-
long SAML1POSTEncoder::encode(
GenericResponse& genericResponse,
XMLObject* xmlObject,
Category& log = Category::getInstance(SAML_LOGCAT".MessageEncoder.SAML1POST");
log.debug("validating input");
- HTTPResponse* httpResponse=dynamic_cast<HTTPResponse*>(&genericResponse);
- if (!httpResponse)
- throw BindingException("Unable to cast response interface to HTTPResponse type.");
if (xmlObject->getParent())
throw BindingException("Cannot encode XML content with parent.");
Response* response = dynamic_cast<Response*>(xmlObject);
params["TARGET"] = relayState;
stringstream s;
engine->run(infile, s, params);
- httpResponse->setContentType("text/html");
- long ret = httpResponse->sendResponse(s, HTTPResponse::SAML_HTTP_STATUS_OK);
+ genericResponse.setContentType("text/html");
+ long ret = genericResponse.sendResponse(s);
// Cleanup by destroying XML.
delete xmlObject;
--- /dev/null
+/*
+ * Copyright 2001-2006 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.
+ */
+
+/**
+ * SAML1SOAPEncoder.cpp
+ *
+ * SAML 1.x SOAP binding message encoder
+ */
+
+#include "internal.h"
+#include "exceptions.h"
+#include "binding/HTTPResponse.h"
+#include "saml1/binding/SAML1SOAPEncoder.h"
+#include "saml1/core/Protocols.h"
+
+#include <sstream>
+#include <log4cpp/Category.hh>
+#include <xmltooling/util/NDC.h>
+#include <xmltooling/soap/SOAP.h>
+
+using namespace opensaml::saml1p;
+using namespace opensaml;
+using namespace xmlsignature;
+using namespace soap11;
+using namespace xmltooling;
+using namespace log4cpp;
+using namespace std;
+
+namespace opensaml {
+ namespace saml1p {
+ MessageEncoder* SAML_DLLLOCAL SAML1SOAPEncoderFactory(const DOMElement* const & e)
+ {
+ return new SAML1SOAPEncoder(e);
+ }
+ };
+};
+
+SAML1SOAPEncoder::SAML1SOAPEncoder(const DOMElement* e) {}
+
+long SAML1SOAPEncoder::encode(
+ GenericResponse& genericResponse,
+ XMLObject* xmlObject,
+ const char* destination,
+ const char* recipientID,
+ const char* relayState,
+ const CredentialResolver* credResolver,
+ const XMLCh* sigAlgorithm
+ ) const
+{
+#ifdef _DEBUG
+ xmltooling::NDC ndc("encode");
+#endif
+ Category& log = Category::getInstance(SAML_LOGCAT".MessageEncoder.SAML1SOAP");
+
+ log.debug("validating input");
+ if (xmlObject->getParent())
+ throw BindingException("Cannot encode XML content with parent.");
+
+ genericResponse.setContentType("text/xml");
+
+ DOMElement* rootElement = NULL;
+ Response* response = dynamic_cast<Response*>(xmlObject);
+ if (response) {
+ try {
+ Envelope* env = EnvelopeBuilder::buildEnvelope();
+ Body* body = BodyBuilder::buildBody();
+ env->setBody(body);
+ body->getXMLObjects().push_back(response);
+ if (credResolver ) {
+ if (response->getSignature()) {
+ log.debug("response already signed, skipping signature operation");
+ rootElement = env->marshall();
+ }
+ else {
+ log.debug("signing and marshalling the response");
+
+ // Build a Signature.
+ Signature* sig = buildSignature(credResolver, sigAlgorithm);
+ response->setSignature(sig);
+
+ // Sign response while marshalling.
+ vector<Signature*> sigs(1,sig);
+ rootElement = env->marshall((DOMDocument*)NULL,&sigs);
+ }
+ }
+ else {
+ log.debug("marshalling the response");
+ rootElement = env->marshall();
+ }
+
+ string xmlbuf;
+ XMLHelper::serialize(rootElement, xmlbuf);
+ istringstream s(xmlbuf);
+ log.debug("sending serialized response");
+ long ret = genericResponse.sendResponse(s);
+
+ // Cleanup by destroying XML.
+ delete env;
+ return ret;
+ }
+ catch (XMLToolingException&) {
+ // A bit weird...we have to "revert" things so that the response is isolated
+ // so the caller can free it.
+ if (response->getParent()) {
+ response->getParent()->detach();
+ response->detach();
+ }
+ throw;
+ }
+ }
+
+ Fault* fault = dynamic_cast<Fault*>(xmlObject);
+ if (fault) {
+ try {
+ log.debug("building Envelope and marshalling Fault");
+ Envelope* env = EnvelopeBuilder::buildEnvelope();
+ Body* body = BodyBuilder::buildBody();
+ env->setBody(body);
+ body->getXMLObjects().push_back(fault);
+ rootElement = env->marshall();
+
+ string xmlbuf;
+ XMLHelper::serialize(rootElement, xmlbuf);
+ istringstream s(xmlbuf);
+ log.debug("sending serialized fault");
+ long ret = genericResponse.sendError(s);
+
+ // Cleanup by destroying XML.
+ delete env;
+ return ret;
+ }
+ catch (XMLToolingException&) {
+ // A bit weird...we have to "revert" things so that the fault is isolated
+ // so the caller can free it.
+ if (fault->getParent()) {
+ fault->getParent()->detach();
+ fault->detach();
+ }
+ throw;
+ }
+ }
+
+ Envelope* env = dynamic_cast<Envelope*>(xmlObject);
+ if (env) {
+ log.debug("marshalling envelope");
+ rootElement = env->marshall();
+
+ bool error =
+ (env->getBody() &&
+ env->getBody()->hasChildren() &&
+ dynamic_cast<Fault*>(env->getBody()->getXMLObjects().front()));
+
+ string xmlbuf;
+ XMLHelper::serialize(rootElement, xmlbuf);
+ istringstream s(xmlbuf);
+ log.debug("sending serialized envelope");
+ long ret = error ? genericResponse.sendError(s) : genericResponse.sendResponse(s);
+
+ // Cleanup by destroying XML.
+ delete env;
+ return ret;
+ }
+
+ throw BindingException("XML content for SAML 1.x SOAP Encoder must be a SAML 1.x <Response> or SOAP Fault/Envelope.");
+}
{
public:
SAML2ArtifactDecoder(const DOMElement* e);
- virtual ~SAML2ArtifactDecoder();
+ virtual ~SAML2ArtifactDecoder() {}
xmltooling::XMLObject* decode(
std::string& relayState,
{
public:
SAML2ArtifactEncoder(const DOMElement* e);
- virtual ~SAML2ArtifactEncoder();
+ virtual ~SAML2ArtifactEncoder() {}
long encode(
GenericResponse& genericResponse,
{
public:
SAML2POSTDecoder(const DOMElement* e);
- virtual ~SAML2POSTDecoder();
+ virtual ~SAML2POSTDecoder() {}
saml2::RootObject* decode(
std::string& relayState,
{
public:
SAML2POSTEncoder(const DOMElement* e, bool simple=false);
- virtual ~SAML2POSTEncoder();
+ virtual ~SAML2POSTEncoder() {}
long encode(
GenericResponse& genericResponse,
{
public:
SAML2RedirectDecoder(const DOMElement* e);
- virtual ~SAML2RedirectDecoder();
+ virtual ~SAML2RedirectDecoder() {}
xmltooling::XMLObject* decode(
std::string& relayState,
SAML2ArtifactDecoder::SAML2ArtifactDecoder(const DOMElement* e) {}
-SAML2ArtifactDecoder::~SAML2ArtifactDecoder() {}
-
XMLObject* SAML2ArtifactDecoder::decode(
string& relayState,
const GenericRequest& genericRequest,
}
}
-SAML2ArtifactEncoder::~SAML2ArtifactEncoder() {}
-
long SAML2ArtifactEncoder::encode(
GenericResponse& genericResponse,
xmltooling::XMLObject* xmlObject,
stringstream s;
engine->run(infile, s, params);
httpResponse->setContentType("text/html");
- return httpResponse->sendResponse(s, HTTPResponse::SAML_HTTP_STATUS_OK);
+ return httpResponse->sendResponse(s);
}
}
SAML2POSTDecoder::SAML2POSTDecoder(const DOMElement* e) {}
-SAML2POSTDecoder::~SAML2POSTDecoder() {}
-
saml2::RootObject* SAML2POSTDecoder::decode(
std::string& relayState,
const GenericRequest& genericRequest,
#include "internal.h"
#include "exceptions.h"
-#include "binding/HTTPResponse.h"
#include "saml2/binding/SAML2POSTEncoder.h"
#include "saml2/core/Protocols.h"
throw XMLToolingException("SAML2POSTEncoder requires template attribute.");
}
-SAML2POSTEncoder::~SAML2POSTEncoder() {}
-
long SAML2POSTEncoder::encode(
GenericResponse& genericResponse,
XMLObject* xmlObject,
Category& log = Category::getInstance(SAML_LOGCAT".MessageEncoder.SAML2POST");
log.debug("validating input");
- HTTPResponse* httpResponse=dynamic_cast<HTTPResponse*>(&genericResponse);
- if (!httpResponse)
- throw BindingException("Unable to cast response interface to HTTPResponse type.");
if (xmlObject->getParent())
throw BindingException("Cannot encode XML content with parent.");
pmap["action"] = destination;
stringstream s;
engine->run(infile, s, pmap);
- httpResponse->setContentType("text/html");
- long ret = httpResponse->sendResponse(s, HTTPResponse::SAML_HTTP_STATUS_OK);
+ genericResponse.setContentType("text/html");
+ long ret = genericResponse.sendResponse(s);
// Cleanup by destroying XML.
delete xmlObject;
SAML2RedirectDecoder::SAML2RedirectDecoder(const DOMElement* e) {}
-SAML2RedirectDecoder::~SAML2RedirectDecoder() {}
-
XMLObject* SAML2RedirectDecoder::decode(
string& relayState,
const GenericRequest& genericRequest,
return decoded;\r
}\r
\r
+ long sendResponse(std::istream& inputStream) {\r
+ return sendResponse(inputStream, HTTPResponse::SAML_HTTP_STATUS_OK);\r
+ }\r
+\r
+ long sendError(std::istream& inputStream) {\r
+ return sendResponse(inputStream, HTTPResponse::SAML_HTTP_STATUS_ERROR);\r
+ }\r
+\r
long sendResponse(std::istream& inputStream, long status) {\r
m_method="POST";\r
string page,line;\r