SAML 2 Artifact decoder/test, with some API adjustments.
[shibboleth/cpp-opensaml.git] / saml / binding / MessageDecoder.h
1 /*\r
2  *  Copyright 2001-2006 Internet2\r
3  * \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *\r
8  *     http://www.apache.org/licenses/LICENSE-2.0\r
9  *\r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 \r
17 /**\r
18  * @file saml/binding/MessageDecoder.h\r
19  * \r
20  * Interface to SAML protocol binding message decoders. \r
21  */\r
22 \r
23 #ifndef __saml_decoder_h__\r
24 #define __saml_decoder_h__\r
25 \r
26 #include <saml/base.h>\r
27 \r
28 #include <xmltooling/XMLObject.h>\r
29 \r
30 namespace opensaml {\r
31     \r
32     class SAML_API SAMLArtifact;\r
33     class SAML_API X509TrustEngine;\r
34     namespace saml1p {\r
35         class SAML_API Response;\r
36     };\r
37     namespace saml2p {\r
38         class SAML_API SAML2Artifact;\r
39         class SAML_API ArtifactResponse;\r
40     };\r
41     namespace saml2md {\r
42         class SAML_API MetadataProvider;\r
43         class SAML_API IDPSSODescriptor;\r
44         class SAML_API RoleDescriptor;\r
45         class SAML_API SSODescriptorType;\r
46     }\r
47 \r
48     /**\r
49      * Interface to SAML protocol binding message decoders.\r
50      */\r
51     class SAML_API MessageDecoder\r
52     {\r
53         MAKE_NONCOPYABLE(MessageDecoder);\r
54     public:\r
55         virtual ~MessageDecoder() {}\r
56 \r
57         /**\r
58          * Interface to caller-supplied shim for accessing HTTP request context.\r
59          * \r
60          * To supply information from the surrounding web server environment,\r
61          * a shim must be supplied in the form of this interface to adapt the\r
62          * library to different proprietary server APIs.\r
63          */\r
64         class SAML_API HTTPRequest {\r
65             MAKE_NONCOPYABLE(HTTPRequest);\r
66         protected:\r
67             HTTPRequest() {}\r
68         public:\r
69             virtual ~HTTPRequest() {}\r
70             \r
71             /**\r
72              * Returns the HTTP method of the request (GET, POST, etc.)\r
73              * \r
74              * @return the HTTP method\r
75              */\r
76             virtual const char* getMethod() const=0;\r
77             \r
78             /**\r
79              * Returns the complete request URL, including scheme, host, port.\r
80              * \r
81              * @return the request URL\r
82              */\r
83             virtual const char* getRequestURL() const=0;\r
84             \r
85             /**\r
86              * Returns the HTTP query string appened to the request. The query\r
87              * string is returned without any decoding applied, everything found\r
88              * after the ? delimiter. \r
89              * \r
90              * @return the query string\r
91              */\r
92             virtual const char* getQueryString() const=0;\r
93             \r
94             /**\r
95              * Returns a decoded named parameter value from the query string or form body.\r
96              * If a parameter has multiple values, only one will be returned.\r
97              * \r
98              * @param name  the name of the parameter to return\r
99              * @return a single parameter value or NULL\r
100              */\r
101             virtual const char* getParameter(const char* name) const=0;\r
102 \r
103             /**\r
104              * Returns all of the decoded values of a named parameter from the query string\r
105              * or form body. All values found will be returned.\r
106              * \r
107              * @param name      the name of the parameter to return\r
108              * @param values    a vector in which to return pointers to the decoded values\r
109              * @return  the number of values returned\r
110              */            \r
111             virtual std::vector<const char*>::size_type getParameters(\r
112                 const char* name, std::vector<const char*>& values\r
113                 ) const=0;\r
114         };\r
115 \r
116         /**\r
117          * Interface to caller-supplied artifact resolution mechanism.\r
118          * \r
119          * Resolving artifacts requires internally performing a SOAP-based\r
120          * call to the artifact source, usually in a mutually authenticated fashion.\r
121          * The potential options vary widely, so the work is encapsulated by this\r
122          * interface, though of course other library facilities may be used.\r
123          * \r
124          * <p>A MessageDecoder implementation will invoke the supplied interface\r
125          * when it requires an artifact be resolved.\r
126          */\r
127         class SAML_API ArtifactResolver {\r
128             MAKE_NONCOPYABLE(ArtifactResolver);\r
129         protected:\r
130             ArtifactResolver() {}\r
131             \r
132             /** Flag controlling schema validation. */\r
133             bool m_validate;\r
134 \r
135         public:\r
136             virtual ~ArtifactResolver() {}\r
137 \r
138             /**\r
139              * Controls schema validation of incoming XML messages.\r
140              * This is separate from other forms of programmatic validation of objects,\r
141              * but can detect a much wider range of syntax errors. \r
142              * \r
143              * @param validate  true iff the resolver should use a validating XML parser\r
144              */\r
145             void setValidating(bool validate=true) {\r
146                 m_validate = validate;\r
147             }\r
148             \r
149             /**\r
150              * Resolves one or more SAML 1.x artifacts into a response containing a set of\r
151              * resolved Assertions. The caller is responsible for the resulting Response. \r
152              * \r
153              * @param authenticated     output flag set to true iff the resolution channel was authenticated\r
154              * @param artifacts         one or more SAML 1.x artifacts\r
155              * @param idpDescriptor     reference to IdP role of artifact issuer\r
156              * @param trustEngine       optional pointer to X509TrustEngine supplied to MessageDecoder\r
157              * @return the corresponding SAML Assertions wrapped in a Response.\r
158              */\r
159             virtual saml1p::Response* resolve(\r
160                 bool& authenticated,\r
161                 const std::vector<SAMLArtifact*>& artifacts,\r
162                 const saml2md::IDPSSODescriptor& idpDescriptor,\r
163                 const X509TrustEngine* trustEngine=NULL\r
164                 ) const=0;\r
165 \r
166             /**\r
167              * Resolves a SAML 2.0 artifact into the corresponding SAML protocol message.\r
168              * The caller is responsible for the resulting ArtifactResponse message.\r
169              * \r
170              * @param authenticated     output flag set to true iff the resolution channel was authenticated\r
171              * @param artifact          reference to a SAML 2.0 artifact\r
172              * @param ssoDescriptor     reference to SSO role of artifact issuer (may be SP or IdP)\r
173              * @param trustEngine       optional pointer to X509TrustEngine supplied to MessageDecoder\r
174              * @return the corresponding SAML protocol message or NULL\r
175              */\r
176             virtual saml2p::ArtifactResponse* resolve(\r
177                 bool& authenticated,\r
178                 const saml2p::SAML2Artifact& artifact,\r
179                 const saml2md::SSODescriptorType& ssoDescriptor,\r
180                 const X509TrustEngine* trustEngine=NULL\r
181                 ) const=0;\r
182         };\r
183 \r
184         /**\r
185          * Provides an ArtifactResolver implementation for the MessageDecoder to use.\r
186          * The implementation's lifetime must be longer than the lifetime of this object. \r
187          * This method must be externally synchronized. \r
188          * \r
189          * @param artifactResolver   an ArtifactResolver implementation to use\r
190          */\r
191         void setArtifactResolver(ArtifactResolver* artifactResolver) {\r
192             m_artifactResolver = artifactResolver;\r
193             if (m_artifactResolver)\r
194                 m_artifactResolver->setValidating(m_validate);\r
195         }\r
196         \r
197         /**\r
198          * Controls schema validation of incoming XML messages.\r
199          * This is separate from other forms of programmatic validation of objects,\r
200          * but can detect a much wider range of syntax errors. \r
201          * \r
202          * @param validate  true iff the decoder should use a validating XML parser\r
203          */\r
204         void setValidating(bool validate=true) {\r
205             m_validate = validate;\r
206             if (m_artifactResolver)\r
207                 m_artifactResolver->setValidating(m_validate);\r
208         }\r
209 \r
210         /**\r
211          * Decodes an HTTP request into a SAML protocol message, and returns related\r
212          * information about the issuer of the message and whether it can be trusted.\r
213          * If the HTTP request does not contain the information necessary to decode\r
214          * the request, a NULL will be returned. Errors during the decoding process\r
215          * will be raised as exceptions.\r
216          * \r
217          * <p>Artifact-based bindings require an ArtifactResolver be set to\r
218          * turn an artifact into the corresponding message.\r
219          * \r
220          * <p>In some cases, a message may be returned but not authenticated. The caller\r
221          * should examine the issuerTrusted output value to establish this.  \r
222          * \r
223          * @param relayState        RelayState/TARGET value accompanying message\r
224          * @param issuer            role descriptor of issuing party\r
225          * @param issuerTrusted     output flag set to true iff the message was authenticated\r
226          *                          (signed or obtained via secure backchannel)\r
227          * @param httpRequest       reference to interface for accessing HTTP message to decode\r
228          * @param metadataProvider  optional MetadataProvider instance to authenticate the message\r
229          * @param role              optional, identifies the role (generally IdP or SP) of the peer who issued the message \r
230          * @param trustEngine       optional TrustEngine to authenticate the message\r
231          * @return  the decoded message, or NULL if the decoder did not recognize the request content\r
232          */\r
233         virtual xmltooling::XMLObject* decode(\r
234             std::string& relayState,\r
235             const saml2md::RoleDescriptor*& issuer,\r
236             bool& issuerTrusted,\r
237             const HTTPRequest& httpRequest,\r
238             const saml2md::MetadataProvider* metadataProvider=NULL,\r
239             const xmltooling::QName* role=NULL,\r
240             const TrustEngine* trustEngine=NULL\r
241             ) const=0;\r
242 \r
243     protected:\r
244         MessageDecoder() : m_artifactResolver(NULL), m_validate(false) {}\r
245 \r
246         /** Pointer to an ArtifactResolver implementation. */\r
247         ArtifactResolver* m_artifactResolver;\r
248         \r
249         /** Flag controlling schema validation. */\r
250         bool m_validate;\r
251     };\r
252 \r
253     /**\r
254      * Registers MessageDecoder plugins into the runtime.\r
255      */\r
256     void SAML_API registerMessageDecoders();\r
257 \r
258     /** MessageDecoder for SAML 1.x Browser/Artifact "binding" (really part of profile) */\r
259     #define SAML1_ARTIFACT_DECODER  "urn:oasis:names:tc:SAML:1.0:profiles:artifact-01"\r
260 \r
261     /** MessageDecoder for SAML 1.x Browser/POST "binding" (really part of profile) */\r
262     #define SAML1_POST_DECODER  "urn:oasis:names:tc:SAML:1.0:profiles:browser-post"\r
263     \r
264     /** MessageDecoder for SAML 2.0 HTTP-Artifact binding */\r
265     #define SAML2_ARTIFACT_DECODER "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"\r
266 \r
267     /** MessageDecoder for SAML 2.0 HTTP-POST binding */\r
268     #define SAML2_POST_DECODER "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"\r
269 \r
270     /** MessageDecoder for SAML 2.0 HTTP-Redirect binding */\r
271     #define SAML2_REDIRECT_DECODER "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"\r
272 };\r
273 \r
274 #endif /* __saml_decoder_h__ */\r