Form generator for discovery along with sample form.
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Sat, 9 Feb 2008 00:07:02 +0000 (00:07 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Sat, 9 Feb 2008 00:07:02 +0000 (00:07 +0000)
Fix transformer to handle non-matching expressions, which return the matching string.

git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2732 cb58f699-b61c-0410-a6fe-9272a202ed29

configs/Makefile.am
configs/discoveryTemplate.html [new file with mode: 0644]
postinstall
shibsp/Makefile.am
shibsp/handler/SessionInitiator.h
shibsp/handler/impl/FormSessionInitiator.cpp [new file with mode: 0644]
shibsp/handler/impl/SessionInitiator.cpp
shibsp/handler/impl/TransformSessionInitiator.cpp
shibsp/shibsp-lite.vcproj
shibsp/shibsp.vcproj

index 8b17cae..24baa09 100644 (file)
@@ -39,6 +39,7 @@ CONFIGFILES = \
        sessionError.html \
        metadataError.html \
        bindingTemplate.html \
+       discoveryTemplate.html \
        localLogout.html \
        globalLogout.html \
        sslError.html
diff --git a/configs/discoveryTemplate.html b/configs/discoveryTemplate.html
new file mode 100644 (file)
index 0000000..75f8d8d
--- /dev/null
@@ -0,0 +1,44 @@
+<html>
+       <head>
+               <title>Request for Authentication</title>
+       </head>
+       <body>
+               <h1>Request for Authentication</h1>
+
+        <p>This web site requires you to login before proceeding. Please identify
+        the domain name of your organization:</p>
+       
+               <form method="GET" action="<shibmlp action/>">
+            <shibmlpif target>
+                <input type="hidden" name="target" value="<shibmlp target/>"/>
+            </shibmlpif>
+
+            <shibmlpif acsIndex>
+                <input type="hidden" name="acsIndex" value="<shibmlp acsIndex/>"/>
+            </shibmlpif>
+
+            <shibmlpif isPassive>
+                <input type="hidden" name="isPassive" value="<shibmlp isPassive/>"/>
+            </shibmlpif>
+
+            <shibmlpif forceAuthn>
+                <input type="hidden" name="forceAuthn" value="<shibmlp forceAuthn/>"/>
+            </shibmlpif>
+
+            <shibmlpif authnContextClassRef>
+                <input type="hidden" name="authnContextClassRef" value="<shibmlp authnContextClassRef/>"/>
+            </shibmlpif>
+
+            <shibmlpif authnContextComparison>
+                <input type="hidden" name="authnContextComparison" value="<shibmlp authnContextComparison/>"/>
+            </shibmlpif>
+            
+                   <input type="text" name="entityID" value="<shibmlp entityID/>">
+                   <input type="submit" value="Submit"/>
+               </form>
+               
+               <shibmlpif entityID>
+               <p>The system was unable to determine how to proceed using the value you supplied.</p>
+               </shibmlpif>
+       </body>
+</html>
index 7de6d91..5137447 100644 (file)
@@ -12,6 +12,7 @@ CONFIGFILES=" \
     metadataError.html \
     sslError.html \
     bindingTemplate.html \
+    discoveryTemplate.html \
     localLogout.html \
     globalLogout.html \
     attribute-map.xml \
index 1b77187..32c5e43 100644 (file)
@@ -111,6 +111,7 @@ common_sources = \
        handler/impl/AssertionLookup.cpp \
        handler/impl/ChainingLogoutInitiator.cpp \
        handler/impl/ChainingSessionInitiator.cpp \
+       handler/impl/FormSessionInitiator.cpp \
        handler/impl/LocalLogoutInitiator.cpp \
        handler/impl/LogoutHandler.cpp \
        handler/impl/MetadataGenerator.cpp \
index a201c0a..bd0ae6b 100644 (file)
@@ -83,6 +83,9 @@ namespace shibsp {
     
     /** SessionInitiator that attempts a sequence of transforms of an input until an entityID is found. */
     #define TRANSFORM_SESSION_INITIATOR "Transform"
+
+    /** SessionInitiator that uses HTML form submission from the user. */
+    #define FORM_SESSION_INITIATOR "Form"
 };
 
 #endif /* __shibsp_initiator_h__ */
diff --git a/shibsp/handler/impl/FormSessionInitiator.cpp b/shibsp/handler/impl/FormSessionInitiator.cpp
new file mode 100644 (file)
index 0000000..7842963
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ *  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.
+ */
+
+/**
+ * FormSessionInitiator.cpp
+ * 
+ * HTML form-based IdP discovery.
+ */
+
+#include "internal.h"
+#include "Application.h"
+#include "exceptions.h"
+#include "SPRequest.h"
+#include "handler/AbstractHandler.h"
+#include "handler/SessionInitiator.h"
+#include "util/TemplateParameters.h"
+
+#include <fstream>
+#include <xmltooling/XMLToolingConfig.h>
+#include <xmltooling/util/PathResolver.h>
+#include <xmltooling/util/URLEncoder.h>
+
+using namespace shibsp;
+using namespace opensaml;
+using namespace xmltooling;
+using namespace std;
+
+namespace shibsp {
+
+#if defined (_MSC_VER)
+    #pragma warning( push )
+    #pragma warning( disable : 4250 )
+#endif
+
+    class SHIBSP_DLLLOCAL FormSessionInitiator : public SessionInitiator, public AbstractHandler
+    {
+    public:
+        FormSessionInitiator(const DOMElement* e, const char* appId)
+            : AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT".SessionInitiator.Form")), m_template(getString("template").second) {
+            if (!m_template)
+                throw ConfigurationException("Form SessionInitiator requires a template property.");
+        }
+        virtual ~FormSessionInitiator() {}
+        
+        pair<bool,long> run(SPRequest& request, string& entityID, bool isHandler=true) const;
+
+    private:
+        const char* m_template;
+    };
+
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
+    SessionInitiator* SHIBSP_DLLLOCAL FormSessionInitiatorFactory(const pair<const DOMElement*,const char*>& p)
+    {
+        return new FormSessionInitiator(p.first, p.second);
+    }
+
+};
+
+pair<bool,long> FormSessionInitiator::run(SPRequest& request, string& entityID, bool isHandler) const
+{
+    string target;
+    const char* option;
+    bool isPassive=false;
+    const Application& app=request.getApplication();
+
+    if (isHandler) {
+        option = request.getParameter("target");
+        if (option)
+            target = option;
+        recoverRelayState(request.getApplication(), request, request, target, false);
+    }
+    else {
+        // We're running as a "virtual handler" from within the filter.
+        // The target resource is the current one.
+        target=request.getRequestURL();
+    }
+
+    // Compute the return URL. We start with a self-referential link.
+    string returnURL=request.getHandlerURL(target.c_str());
+    pair<bool,const char*> thisloc = getString("Location");
+    if (thisloc.first) returnURL += thisloc.second;
+
+    if (isHandler) {
+        // We may already have RelayState set if we looped back here,
+        // but just in case target is a resource, we reset it back.
+        option = request.getParameter("target");
+        if (option)
+            target = option;
+    }
+    preserveRelayState(request.getApplication(), request, target);
+
+    request.setContentType("text/html");
+    request.setResponseHeader("Expires","01-Jan-1997 12:00:00 GMT");
+    request.setResponseHeader("Cache-Control","private,no-store,no-cache");
+    string fname(m_template);
+    ifstream infile(XMLToolingConfig::getConfig().getPathResolver()->resolve(fname, PathResolver::XMLTOOLING_CFG_FILE).c_str());
+    if (!infile)
+        throw ConfigurationException("Unable to access HTML template ($1).", params(1, m_template));
+    TemplateParameters tp;
+    tp.m_request = &request;
+    tp.setPropertySet(request.getApplication().getPropertySet("Errors"));
+    tp.m_map["action"] = returnURL;
+    if (!target.empty())
+        tp.m_map["target"] = target;
+    stringstream str;
+    XMLToolingConfig::getConfig().getTemplateEngine()->run(infile, str, tp);
+    return make_pair(true,request.sendResponse(str));
+}
index 3bdefc1..0e96922 100644 (file)
@@ -35,6 +35,7 @@ namespace shibsp {
     SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory WAYFSessionInitiatorFactory;
     SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory SAMLDSSessionInitiatorFactory;
     SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory TransformSessionInitiatorFactory;
+    SHIBSP_DLLLOCAL PluginManager< SessionInitiator,string,pair<const DOMElement*,const char*> >::Factory FormSessionInitiatorFactory;
 };
 
 void SHIBSP_API shibsp::registerSessionInitiators()
@@ -45,6 +46,7 @@ void SHIBSP_API shibsp::registerSessionInitiators()
     conf.SessionInitiatorManager.registerFactory(SAML2_SESSION_INITIATOR, SAML2SessionInitiatorFactory);
     conf.SessionInitiatorManager.registerFactory(WAYF_SESSION_INITIATOR, WAYFSessionInitiatorFactory);
     conf.SessionInitiatorManager.registerFactory(TRANSFORM_SESSION_INITIATOR, TransformSessionInitiatorFactory);
+    conf.SessionInitiatorManager.registerFactory(FORM_SESSION_INITIATOR, FormSessionInitiatorFactory);
 }
 
 pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
index fa712d8..440668b 100644 (file)
@@ -99,6 +99,9 @@ namespace shibsp {
                             auto_ptr_char repl(e->getFirstChild()->getNodeValue());
                             m_regex.push_back(make_pair((*flag==chDigit_1 || *flag==chLatin_t), pair<string,string>(m.get(), repl.get())));
                         }
+                        else {
+                            m_log.warn("Unknown element found in Transform SessionInitiator configuration, check for errors.");
+                        }
                     }
                     e = XMLHelper::getNextSiblingElement(e);
                 }
@@ -248,6 +251,10 @@ void TransformSessionInitiator::doRequest(const Application& application, string
                 auto_ptr_char narrow(temp);
                 XMLString::release(&temp);
 
+                // For some reason it returns the match string if it doesn't match the expression.
+                if (entityID == narrow.get())
+                    continue;
+
                 if (r->first) {
                     m_log.info("forcibly transformed entityID from (%s) to (%s)", entityID.c_str(), narrow.get());
                     entityID = narrow.get();
index cdfd090..a59b023 100644 (file)
                                                >\r
                                        </File>\r
                                        <File\r
+                                               RelativePath=".\handler\impl\FormSessionInitiator.cpp"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
                                                RelativePath=".\handler\impl\LocalLogoutInitiator.cpp"\r
                                                >\r
                                        </File>\r
index d638725..d3511c3 100644 (file)
                                                >\r
                                        </File>\r
                                        <File\r
+                                               RelativePath=".\handler\impl\FormSessionInitiator.cpp"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
                                                RelativePath=".\handler\impl\LocalLogoutInitiator.cpp"\r
                                                >\r
                                        </File>\r