Fix precedence of REMOTE_USER export.
authorcantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Thu, 6 Dec 2007 03:54:45 +0000 (03:54 +0000)
committercantor <cantor@cb58f699-b61c-0410-a6fe-9272a202ed29>
Thu, 6 Dec 2007 03:54:45 +0000 (03:54 +0000)
git-svn-id: https://svn.middleware.georgetown.edu/cpp-sp/trunk@2658 cb58f699-b61c-0410-a6fe-9272a202ed29

shibsp/Application.h
shibsp/ServiceProvider.cpp
shibsp/handler/impl/SessionHandler.cpp
shibsp/impl/XMLServiceProvider.cpp

index d9bd87c..1571c10 100644 (file)
@@ -190,12 +190,11 @@ namespace shibsp {
         virtual std::string getNotificationURL(const char* request, bool front, unsigned int index) const=0;
 
         /**
-         * Returns a set of attribute IDs to use as a REMOTE_USER value.
-         * <p>The first attribute with a value (and only a single value) will be used.
+         * Returns an array of attribute IDs to use as a REMOTE_USER value, in order of preference.
          *
-         * @return  a set of attribute IDs, or an empty set
+         * @return  an array of attribute IDs, possibly empty
          */
-        virtual const std::set<std::string>& getRemoteUserAttributeIds() const=0;
+        virtual const std::vector<std::string>& getRemoteUserAttributeIds() const=0;
 
         /**
          * Clears any headers that may be used to hold attributes after export.
index e0d257b..944dc26 100644 (file)
@@ -402,19 +402,10 @@ pair<bool,long> ServiceProvider::doExport(SPRequest& request, bool requireSessio
         }
 
         // Export the attributes.
-        bool remoteUserSet = false;
         const multimap<string,const Attribute*>& attributes = session->getIndexedAttributes();
         for (multimap<string,const Attribute*>::const_iterator a = attributes.begin(); a!=attributes.end(); ++a) {
-            const vector<string>& vals = a->second->getSerializedValues();
-
-            // See if this needs to be set as the REMOTE_USER value.
-            if (!remoteUserSet && !vals.empty() && app->getRemoteUserAttributeIds().count(a->first)) {
-                request.setRemoteUser(vals.front().c_str());
-                remoteUserSet = true;
-            }
-
-            // Handle the normal export case.
             string header(request.getSecureHeader(a->first.c_str()));
+            const vector<string>& vals = a->second->getSerializedValues();
             for (vector<string>::const_iterator v = vals.begin(); v!=vals.end(); ++v) {
                 if (!header.empty())
                     header += ";";
@@ -434,6 +425,22 @@ pair<bool,long> ServiceProvider::doExport(SPRequest& request, bool requireSessio
             request.setHeader(a->first.c_str(), header.c_str());
         }
 
+        // Check for REMOTE_USER.
+        bool remoteUserSet = false;
+        const vector<string>& rmids = app->getRemoteUserAttributeIds();
+        for (vector<string>::const_iterator rmid = rmids.begin(); !remoteUserSet && rmid != rmids.end(); ++rmid) {
+            pair<multimap<string,const Attribute*>::const_iterator,multimap<string,const Attribute*>::const_iterator> matches =
+                attributes.equal_range(*rmid);
+            while (matches.first != matches.second) {
+                const vector<string>& vals = matches.first->second->getSerializedValues();
+                if (!vals.empty()) {
+                    request.setRemoteUser(vals.front().c_str());
+                    remoteUserSet = true;
+                    break;
+                }
+            }
+        }
+
         return make_pair(false,0L);
     }
     catch (exception& e) {
index 72951bf..a35dc0c 100644 (file)
@@ -119,18 +119,18 @@ pair<bool,long> SessionHandler::run(SPRequest& request, bool isHandler) const
 
     s << "<u>Miscellaneous</u>" << endl;
 
-    s << "<strong>Client Address</strong>: " << (session->getClientAddress() ? session->getClientAddress() : "(none)") << endl;
-    s << "<strong>Identity Provider</strong>: " << (session->getEntityID() ? session->getEntityID() : "(none)") << endl;
-    s << "<strong>SSO Protocol</strong>: " << (session->getProtocol() ? session->getProtocol() : "(none)") << endl;
-    s << "<strong>Authentication Time</strong>: " << (session->getAuthnInstant() ? session->getAuthnInstant() : "(none)") << endl;
-    s << "<strong>Authentication Context Class</strong>: " << (session->getAuthnContextClassRef() ? session->getAuthnContextClassRef() : "(none)") << endl;
-    s << "<strong>Authentication Context Decl</strong>: " << (session->getAuthnContextDeclRef() ? session->getAuthnContextDeclRef() : "(none)") << endl;
-    s << "<strong>Session Expiration (barring inactivity)</strong>: ";
+    s << "<strong>Client Address:</strong> " << (session->getClientAddress() ? session->getClientAddress() : "(none)") << endl;
+    s << "<strong>Identity Provider:</strong> " << (session->getEntityID() ? session->getEntityID() : "(none)") << endl;
+    s << "<strong>SSO Protocol:</strong> " << (session->getProtocol() ? session->getProtocol() : "(none)") << endl;
+    s << "<strong>Authentication Time:</strong> " << (session->getAuthnInstant() ? session->getAuthnInstant() : "(none)") << endl;
+    s << "<strong>Authentication Context Class:</strong> " << (session->getAuthnContextClassRef() ? session->getAuthnContextClassRef() : "(none)") << endl;
+    s << "<strong>Authentication Context Decl:</strong> " << (session->getAuthnContextDeclRef() ? session->getAuthnContextDeclRef() : "(none)") << endl;
+    s << "<strong>Session Expiration (barring inactivity):</strong> ";
     if (session->getExpiration())
         s << ((session->getExpiration() - time(NULL)) / 60) << " minute(s)" << endl;
     else
         s << "Infinite" << endl;
-    
+
     s << endl << "<u>Attributes</u>" << endl;
 
     string key;
index 822ca76..4f790ec 100644 (file)
@@ -131,7 +131,7 @@ namespace {
 #endif
         string getNotificationURL(const char* resource, bool front, unsigned int index) const;
 
-        const set<string>& getRemoteUserAttributeIds() const {
+        const vector<string>& getRemoteUserAttributeIds() const {
             return (m_remoteUsers.empty() && m_base) ? m_base->getRemoteUserAttributeIds() : m_remoteUsers;
         }
 
@@ -179,8 +179,7 @@ namespace {
         map<const XMLCh*,PropertySet*> m_partyMap;
 #endif
 #endif
-        set<string> m_remoteUsers;
-        vector<string> m_frontLogout,m_backLogout;
+        vector<string> m_remoteUsers,m_frontLogout,m_backLogout;
 
         // manage handler objects
         vector<Handler*> m_handlers;
@@ -501,7 +500,7 @@ XMLApplication::XMLApplication(
                     pos = strchr(start,' ');
                     if (pos)
                         *pos=0;
-                    m_remoteUsers.insert(start);
+                    m_remoteUsers.push_back(start);
                     start = pos ? pos+1 : NULL;
                 }
                 free(dup);