Skip to content

Older Alex contribs

Jose edited this page Apr 3, 2018 · 1 revision

Necessary improvements for inbound identity

  • automate how discovery happens.

  • saml is idp name, whats the equivalent for Google or Facebook?

  • how to signal which inbound identity to support? (SAML, OAuth, OpenID Connect, CAS).

  • which strategy? added to the state parameter.. then pass extra info. Take the JSON and add a top level strategy to it, then the app is signaling the strategy, then whatever extra information that strategy enables you to pass.

Alex's suggestions

General enhancements

  1. Would be nice to shift from our somewhat unconditional usage of "state" parameter to pass IDP's id to the script to our just added (3.1.2) custom authz request parameters functionality. The custom parameter it will be using must already exist OOTB. It also could be added as an additional feature, while keeping "state" parameter approach, just in case some implementers may prefer using parameter defined by spec instead of vendor-dependent approach.

Changes needed for compliance with customers' existing setups using old Asimba/SAML script

  1. At least one customer employs "map_all_attr" mode of Asimba script operation which allows them to retrieve almost all of possible (defined at this specific instance) attributes from SAML response without need to set any attribute mappings for specific IDPs. I.e. it works like "catch everything" rule, by auto-generating a mapping array for all attributes found in Gluu's LDAP directory. In current Passport.js code we use hardcoded mappings which only cover a limited set of attributes. To achieve customer requirements they would need to create an enormous hardcoded mapping array, and manage entries in it manually. One possible solution to this is of course to "teach" Passport to fetch attributes' metadata from Gluu's LDAP (what is generally useful feature as we also need to solve problem of replicating its configuration to other nodes in cluster setups, and storing its configuration in LDAP can be an answer to this as well) and make it "aware" of its format so it would be able to parse it and create this "catch-all" mapping array on the fly like the old Asimba scirpt does. A Cons of this approach is huge investment required in witting Node.js code which will effectively duplicate what our old Jython code did. We also will need some kind of "override mode" added to our current Passport-SAML jython script to make it able to pass all attributes recovered with this new "catch-all" Passport's mapping into actual user entry, as atm it as well uses static mappings only.

  2. Current implementation of mappings being stored in config file (passport-saml-config.json) used by Passport.js code won't scale well, as it's conceptually a bit clunky. Let's consider one customers case with their 1-2 dozens of IDPs registered (and that's probably is not a limit for huge vendors). Currently for Passport-SAML mappings are set at 2 different places at once: in SAML strategy's (Passport.js code) config file, and in script's properties itself. The most characteristic mapping phase is the one done by Passport, as it translates SAML attributes names to the ones used internally by Passport. SAML attributes' names come in different formats, and different IDPs in the list may use different formats for names they send. There may be groups of IDPs that use one similar format, as well. Managing this on per-IDP basis (as our current mapping approach implies) will be extremely cumbersome in huge deployments. The customer partly resolves this issue by using their "catch everything" approach which alleviates problem of managing huge mapping array a bit. Another solution (which I see as a great general UI/usability improvement as well) to this problem could be implementing mapping profiles:

    • Actual mappings arrays are moved out of passport-saml-config.json and to a separate config file.

    • Format of the new file is JSON object, with properties like "id_01":{mapping_json_object}, "id_02":{mapping_json_object}.. JSON object format of the mappings sets should be also used to its fullest to achieve another benefit of mappings in the old Asimba script: it should allow many-to-one mappings, allowing to map a bunch of different name formats to a single local attribute. There also should be a special hardcoded mapping option implementing "wildcard/catch-all mapping", ensuring that all names in SAML response will be mapped at least somehow (to achieve compliance with customer requirements). The actual algorithm of its work is still has to be decided (we need dev team assist here)

    • "reverseMapping" properties of IDP entries in passport-saml-config.json only contain id of the mappings' set from the new file ("reverseMapping":"id_02",...). Thus it allows to create some general mapping profiles which then can be assigned to a group of IDPs at once, as a single mapping object. By editing this one single object you as well is able to update mappings of all IDPs it's assigned to, thus solving a problem of updating mappings for a bunch of IDPs using the same set of them (what currently must be done one-IDP-at-a-time)

  3. Another answer to the mapping issues is to move any kind of complex mapping processing out of Passport's code and back to the Jython code. Passport will do the most basic processing work on parsing a SAML response, then will either pass some kind of xml or json with full its content, or will extract all relevant identity items from it (attributes, issuer's id, timestamps etc) and pass only them, yet still in "raw" state (without resolving any SAML names in this blob). The rest of the work will be done by the Passport-SAML (jython) script itself (a lot of old code from Asimba script to reuse here). Pros: it gives us better control over attribute mappings and transformation, without investing too much effort into writing Node.js code; a lot of code to reuse from the old script Cons: it takes our Passport-SAML script even further away from the Passport-Social one, breaking the core design principle it seems to follow in the process (i.e. that Passport does all the "dirty", low-level work related to a specific auth strategy, and Jython scrypt is just a some general-purpose "high-level" code that takes an extracted set of attributes from Passport and simply creates/updates/logins user, i.e. it does uniform job regardless of whatever method was actually used under the hood; at least it seemed to me that was the original idea)

Edit:

A note for items 1) and 2) Even if those issues are resolved, we still need to tackle the problem of subsequent, final mapping (a 2nd phase of mapping) done by the Jython script in the end. Atm it also uses static mapping list provided via script's properties, thus it won't comply with customer's "catch everything" requirements as well. This could be resolved by adding a new mode of operation similar to the one existing in the old script. That 2 step mapping design just seems too clunky to me (though I see its benefits as well, which is creating of an abstraction level between Passport.js and interception script's "realms"). A possible solution to double-mapping issue(?) (with its Pros and Cons) is provided in item 3)