[shibboleth-sp2] 27/82: SSPCPP-694 Prototype roles-based Authn

Etienne Dysli Metref edm-guest at moszumanska.debian.org
Thu Nov 16 08:16:21 UTC 2017


This is an automated email from the git hooks/post-receive script.

edm-guest pushed a commit to branch master
in repository shibboleth-sp2.

commit 639f8969647d451a3bbfa287eaff6c50d716df3f
Author: Rod Widdowson <rdw at steadingsoftware.com>
Date:   Mon May 29 15:22:08 2017 +0100

    SSPCPP-694 Prototype roles-based Authn
    
    https://issues.shibboleth.net/jira/browse/SSPCPP-694
    
    Prototype up how to add roles in an IIS plugin. Based on this prototypical config
    
    <IIS normalizeRequest="true" safeHeaderNames="true" useHeaders="false" useVariables="true">
      <Roles authNRole="ShibAuthenticated">
        <Role attribute="epa" prefix="AffiliatedAs"/>
      </Roles>
    </IIS>
    
    Populate the principal so that it has the role "ShibAuthenticated" and the roles consisting of every value provided to epa appropriated prefixed.  We can then do standard roles based AuthZ in the IIS GUI.
    
    The precisely plumbin is questionable (tokenising the setHeader() parameterization), but it keeps things non-intrusive for now.
---
 iis7_shib/NativeRequest.cpp                 | 18 +++++++++++-
 iis7_shib/ShibUser.cpp                      | 15 ++++++++--
 iis7_shib/headers/IIS7_shib.hpp             | 22 +++++++++++++++
 iis7_shib/headers/NativeRequest.hpp         |  1 +
 iis7_shib/headers/ShibUser.hpp              |  4 +--
 iis7_shib/register.cpp                      | 23 +++++++++++----
 schemas/shibboleth-2.0-native-sp-config.xsd | 43 +++++++++++++++++++----------
 7 files changed, 101 insertions(+), 25 deletions(-)

diff --git a/iis7_shib/NativeRequest.cpp b/iis7_shib/NativeRequest.cpp
index c40334e..a760c23 100644
--- a/iis7_shib/NativeRequest.cpp
+++ b/iis7_shib/NativeRequest.cpp
@@ -21,6 +21,7 @@
 #include "IIS7_shib.hpp"
 
 #include <boost/algorithm/string.hpp>
+#include <boost/tokenizer.hpp>
 
 #include <xercesc/util/Base64.hpp>
 #include <xmltooling/util/NDC.h>
@@ -161,6 +162,18 @@ void NativeRequest::setHeader(const char* name, const char* value)
         if (FAILED(hr)) {
             throwError("setHeader (Variable)", hr);
         }
+
+        for (list<role_t>::iterator role = g_Roles.begin(); role != g_Roles.end(); ++role) {
+            if (role->m_attribute == name) {
+                string str(value);
+                tokenizer<escaped_list_separator<char>> tok(str, escaped_list_separator<char>('\\', ';', '"'));
+                for (tokenizer<escaped_list_separator<char>>::iterator it = tok.begin(); it != tok.end(); ++it) {
+                    const xmltooling::auto_ptr_XMLCh widen(string(role->m_prefix + (*it)).c_str());
+                    m_roles.insert(widen.get());
+                }
+            }
+        }
+
     }
 }
 
@@ -186,7 +199,10 @@ void NativeRequest::setRemoteUser(const char* user)
         IAuthenticationProvider *auth = dynamic_cast<IAuthenticationProvider*>(m_event);
 
         if (auth) {
-            auth->SetUser(new ShibUser(user));
+            if (!g_authNRole.empty()) {
+                m_roles.insert(g_authNRole);
+            }
+            auth->SetUser(new ShibUser(user, m_roles));
         }
     }
 }
diff --git a/iis7_shib/ShibUser.cpp b/iis7_shib/ShibUser.cpp
index 4728e23..d15b4ab 100644
--- a/iis7_shib/ShibUser.cpp
+++ b/iis7_shib/ShibUser.cpp
@@ -21,7 +21,7 @@
 #include "IIS7_shib.hpp"
 #include "ShibUser.hpp"
 
-ShibUser::ShibUser(std::string name) : m_refCount(1), m_widen(name.c_str())
+ShibUser::ShibUser(std::string name, set<wstring> roles) : m_refCount(1), m_widen(name.c_str()), m_roles(roles)
 {
     ;
 }
@@ -87,12 +87,21 @@ HRESULT
 ShibUser::IsInRole(_In_  PCWSTR  pszRoleName, _Out_ BOOL *  pfInRole)
 {
     wstring role(pszRoleName);
-    *pfInRole = (role == L"shibAuthn");
+
+    if (m_roles.find(role) != m_roles.end()) {
+        *pfInRole = TRUE;
+    }
+    else {
+        *pfInRole = FALSE;
+    }
+
+
     return S_OK;
 }
+
 PVOID
 ShibUser::GetUserVariable(_In_ PCSTR    pszVariableName)
 {
-    return  "flibby";
+    return  "";
 }
 
diff --git a/iis7_shib/headers/IIS7_shib.hpp b/iis7_shib/headers/IIS7_shib.hpp
index 2b75688..346228a 100644
--- a/iis7_shib/headers/IIS7_shib.hpp
+++ b/iis7_shib/headers/IIS7_shib.hpp
@@ -28,6 +28,7 @@
 // Miscelanea
 //
 #include <set>
+#include <list>
 #include <boost/lexical_cast.hpp>
 #include <string>
 
@@ -46,6 +47,7 @@
 
 #include <xmltooling/util/XMLHelper.h>
 #include <xmltooling/Lockable.h>
+#include <shibsp/exceptions.h>
 
 #include <message.h>
 
@@ -64,9 +66,12 @@ namespace Config {
     static const XMLCh scheme[] =           UNICODE_LITERAL_6(s, c, h, e, m, e);
     static const XMLCh id[] =               UNICODE_LITERAL_2(i, d);
     static const XMLCh useHeaders[] =       UNICODE_LITERAL_10(u, s, e, H, e, a, d, e, r, s);
+    static const XMLCh theAttribute[] =     UNICODE_LITERAL_9(a, t, t, r, i, b, u, t, e);
+    static const XMLCh thePrefix[] =        UNICODE_LITERAL_6(p, r, e, f, i, x);
     static const XMLCh useVariables[] =     UNICODE_LITERAL_12(u, s, e, V, a, r, i, a, b, l, e, s);
     static const XMLCh Alias[] =            UNICODE_LITERAL_5(A, l, i, a, s);
     static const XMLCh Site[] =             UNICODE_LITERAL_4(S, i, t, e);
+    static const XMLCh Role[] =             UNICODE_LITERAL_4(R, o, l, e);
 
     static const char* SpoofHeaderName = "ShibSpoofCheck";
 
@@ -81,6 +86,7 @@ namespace Config {
     extern bool g_bUseVariables;
     extern vector<string> g_NoCerts;
 
+
     struct site_t {
         site_t(const DOMElement* e)
             : m_name(XMLHelper::getAttrString(e, "", name)),
@@ -105,6 +111,22 @@ namespace Config {
     };
 
     extern map<string, site_t> g_Sites;
+
+    struct role_t {
+        role_t(const DOMElement* e)
+            : m_attribute(XMLHelper::getAttrString(e, "", theAttribute)),
+            m_prefix(XMLHelper::getAttrString(e, "", thePrefix))
+        {
+            if (m_attribute.empty()) {
+                throw ConfigurationException("<Role> attribute name should not be empty");
+            }
+        }
+        const string m_attribute;
+        const string m_prefix;
+    };
+
+    extern wstring g_authNRole;
+    extern list<role_t> g_Roles;
 }
 
 BOOL LogEvent(
diff --git a/iis7_shib/headers/NativeRequest.hpp b/iis7_shib/headers/NativeRequest.hpp
index f391bce..135b2e2 100644
--- a/iis7_shib/headers/NativeRequest.hpp
+++ b/iis7_shib/headers/NativeRequest.hpp
@@ -40,6 +40,7 @@ private:
     mutable string m_body;
     mutable bool m_gotBody;
     string m_allhttp;
+    set<wstring> m_roles;
 
 public:
     NativeRequest(_In_ IHttpContext *pHttpContext, _In_ IHttpEventProvider *pEventProvider, _In_ bool checkUser);
diff --git a/iis7_shib/headers/ShibUser.hpp b/iis7_shib/headers/ShibUser.hpp
index 7e89a7a..e550b60 100644
--- a/iis7_shib/headers/ShibUser.hpp
+++ b/iis7_shib/headers/ShibUser.hpp
@@ -26,7 +26,7 @@ class ShibUser : public IHttpUser {
     // Also, a testbed for Roles Based AuthN.
 
 public:
-    ShibUser(std::string username);
+    ShibUser(std::string username, set<wstring> roles);
             
     PCWSTR
     GetRemoteUserName(
@@ -87,5 +87,5 @@ public:
 private:
     const auto_ptr_XMLCh m_widen;
     volatile unsigned int m_refCount;
-
+    const set<wstring> m_roles;
 };
\ No newline at end of file
diff --git a/iis7_shib/register.cpp b/iis7_shib/register.cpp
index 15c4b3d..8f22bfa 100644
--- a/iis7_shib/register.cpp
+++ b/iis7_shib/register.cpp
@@ -36,6 +36,8 @@ namespace Config {
     bool g_bUseHeaders = false;
     bool g_bUseVariables = true;
     vector<string> g_NoCerts;
+    list<role_t> g_Roles;
+    wstring g_authNRole;
 }
 
 using namespace Config;
@@ -159,12 +161,23 @@ RegisterModule(
             flag = props->getBool("useVariables");
             g_bUseVariables= !flag.first || flag.second;
 
-            const DOMElement* child = XMLHelper::getFirstChildElement(props->getElement(), Site);
-            while (child) {
-                string id(XMLHelper::getAttrString(child, "", id));
+            const DOMElement* site = XMLHelper::getFirstChildElement(props->getElement(), Site);
+            while (site) {
+                string id(XMLHelper::getAttrString(site, "", id));
                 if (!id.empty())
-                    g_Sites.insert(make_pair(id, site_t(child)));
-                child = XMLHelper::getNextSiblingElement(child, Site);
+                    g_Sites.insert(make_pair(id, site_t(site)));
+                site = XMLHelper::getNextSiblingElement(site, Site);
+            }
+            const PropertySet* roles = props->getPropertySet("Roles");
+            if (roles) {
+                pair<bool, const char*> authNRoleFlag = roles->getString("authNRole");
+                xmltooling::auto_ptr_XMLCh rolestr(authNRoleFlag.first? authNRoleFlag.second : "ShibbolethAuthN");
+                g_authNRole = rolestr.get();
+                const DOMElement* role = XMLHelper::getFirstChildElement(roles->getElement(), Role);
+                while (role) {
+                        g_Roles.push_back(role_t(role));
+                        role = XMLHelper::getNextSiblingElement(role, Role);
+                }
             }
         }
     }
diff --git a/schemas/shibboleth-2.0-native-sp-config.xsd b/schemas/shibboleth-2.0-native-sp-config.xsd
index 852b25c..0289cab 100644
--- a/schemas/shibboleth-2.0-native-sp-config.xsd
+++ b/schemas/shibboleth-2.0-native-sp-config.xsd
@@ -188,20 +188,35 @@
         <element name="IIS" minOccurs="0">
           <complexType>
             <sequence>
-              <element name="Site" maxOccurs="unbounded" minOccurs="0">
-                <complexType>
-                  <sequence>
-                    <element name="Alias" type="conf:string" minOccurs="0" maxOccurs="unbounded"/>
-                  </sequence>
-                  <attribute name="id" type="unsignedInt" use="required"/>
-                  <attribute name="name" type="conf:string" use="required"/>
-                  <attribute name="port" type="unsignedInt"/>
-            <attribute name="useHeaders" type="boolean"/>
-            <attribute name="useVariables" type="boolean"/>
-                  <attribute name="sslport" type="unsignedInt"/>
-                  <attribute name="scheme" type="conf:string"/>
-                </complexType>
-              </element>
+              <choice>
+                <element name="Site" maxOccurs="unbounded" minOccurs="0">
+                  <complexType>
+                    <sequence>
+                      <element name="Alias" type="conf:string" minOccurs="0" maxOccurs="unbounded"/>
+                    </sequence>
+                    <attribute name="id" type="unsignedInt" use="required"/>
+                    <attribute name="name" type="conf:string" use="required"/>
+                    <attribute name="port" type="unsignedInt"/>
+                    <attribute name="useHeaders" type="boolean"/>
+                    <attribute name="useVariables" type="boolean"/>
+                    <attribute name="sslport" type="unsignedInt"/>
+                    <attribute name="scheme" type="conf:string"/>
+                  </complexType>
+                </element>
+                <element name="Roles" maxOccurs="unbounded" minOccurs="0">
+                  <complexType>
+                      <sequence>
+                        <element name="Role" minOccurs="0" maxOccurs="unbounded">
+                          <complexType >
+                            <attribute name="attribute" type="string" use="required"/>
+                            <attribute name="prefix" type="string" use="optional"/>
+                          </complexType>
+                        </element>
+                    </sequence>
+                    <attribute name="authNRole" type="string" use="optional"/>
+                  </complexType>
+                </element>
+              </choice>
               <any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
             </sequence>
             <attribute name="normalizeRequest" type="boolean"/>

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-shibboleth/shibboleth-sp2.git



More information about the Pkg-shibboleth-devel mailing list