- πΊπΈUnited States jesconstantine
Hello!
This is a usecase I'll need to satisfy as well, I was curious if anyone had developed this functionality or if anyone had plans to develop this functionality?
Thanks!
- π³π±Netherlands roderik Amsterdam,NL / Budapest,HU
Hi jesconstantine,
The original poster has not replied and noone has made actual plans to develop this. I happily accept either contributed code or sponsorship ;-)
The saml_sp module β is able to handle multiple IdPs. Per 2021, there were some other incompatibilities that make you choose one or the other -- primarily:
- the 'unique id' for the logging-in user. saml_sp wants this in the NameID attribute of the SAML message / cannot handle it being in a generic SAML attribute value. Also, it may or may not require the NameID to be the user's email (I don't remember).
- inversely, samlauth wants the unique ID a generic SAML attribute value, and can only handle the NameID with a patch currently ( #3211380-10: [RFC] NameID support β ).
(Also I have a feeling this module is more future proof, but I'm biased.)
My current idea about getting this feature into this module is:
1)
I'd appreciate anyone laying out their use case, so I can be sure I'm not misunderstanding it / it gets documented properly.
(Per #3211419-3: Consider merging with the saml_sp module / differences between modules β , the saml_sp maintainer lays out his reasons, which is the only actual use case I've seen written down. My interpretation of this is: he's not _actually_ using multiple IdPs at once -- but having multiple configurations saved as config entities makes it a lot easier to switch / there are situations where some form of config override would be too hard.
I'm assuming most people are using some form of config override for making things work in dev/test/live environments.)
2)
Implementation:
Almost all configuration in the config screen (except the "Login / Logout" section) should be configurable per IdP. Having config entities indeed seems the best way, to me. So the config form should be 1) split between "Login / Logout" and the rest, 2) almost all configuration should be saved in an entity.
(There can be discussion about which configuration values could be shared between IdPs, but at this moment I don't believe a good distinction can be made and I think we'll have to just duplicate and reconfigure all the things for every IdP.)Then the locations in the code which currently get the 'samlauth.authentication' configuration, must know which config entity to load (by ID) and load configuration from there instead. I believe this should be doable.
(And if you need the add-on modules for role mapping and attribute mapping... we'd need to have separate config entities for for those too. Again, maybe those can/should be shareable between different IdPs, but I'm not convinced. May depend on point 1.)
3)
Since most sites don't need this, I probably would want to not work with config entities by default, and have this functionality in an add-on module. Where e.g. enabling the module reads the existing 'global' config and creates a config entity from it, and there's some documentation on what to do when uninstalling it.
But that's for later. A patch/hacked module that would do 2, would be a good step toward getting this functionality included in a stable version eventually.
- π¨π¦Canada dylan donkersgoed London, Ontario
Dylan Donkersgoed β made their first commit to this issueβs fork.
- Open on Drupal.org βCore: 9.5.5 + Environment: PHP 7.4 & MySQL 5.7last update
about 2 years ago Not currently mergeable. - @dylan-donkersgoed opened merge request.
- last update
about 2 years ago 2 fail - last update
about 2 years ago 2 fail - last update
about 2 years ago 2 fail - Status changed to Needs work
about 2 years ago 7:00pm 6 June 2023 - π¨π¦Canada dylan donkersgoed London, Ontario
I've pushed some preliminary code to an MR for this. It still needs some work. Right now this just splits the configuration related to the IdP metadata into a config entity. However, as roderick noted above there are some other attributes that almost certainly should be configurable. E.g. the unique ID, username and e-mail attributes. There are some other attributes arguably could be (e.g. maybe you want to require signed assertions for one IdP but not another?). And the submodules should be integrated with it as well.
This MR will also need an update hook to move the existing IdP config to the config entities.
Also, right now this MR doesn't expose any mechanism to actually select which IdP you're using through the UI besides setting a default one nor does it provide, e.g., separate login links for separate IdPs. So it's kind of useless unless you're planning to supplement it with overrides outside the module (which I am). So for some possible enhancements:
- The module could provide login links per-IdP
- The module could provide some mechanism for configuring when to use which IdP, e.g. selecting based on domain.
I'd appreciate anyone laying out their use case, so I can be sure I'm not misunderstanding it / it gets documented properly.
(Per #3211419-3: Consider merging with the saml_sp module / differences between modules, the saml_sp maintainer lays out his reasons, which is the only actual use case I've seen written down. My interpretation of this is: he's not _actually_ using multiple IdPs at once -- but having multiple configurations saved as config entities makes it a lot easier to switch / there are situations where some form of config override would be too hard.
I'm assuming most people are using some form of config override for making things work in dev/test/live environments.)
I can think of two other use cases besides per-environment configuration.
The one I'm dealing with right now is having different configuration for different site domains. I have a site with two different domains, one English and one French, so they have a different ACS URL etc. which means multiple SPs. The way the IdP owner's system works there's only one IdP per SP so that means multiple IdPs as well. I can kind of work around this with settings.php overrides/custom code, but it would be much more convenient if it was in the module.
Another case (and one that's harder to work around) would be allowing logins from multiple different IdPs. I haven't worked on any sites that have done this with SAML, but I have personally worked on sites that have done it with OpenID and seen sites that do it with SAML in the wild.
- π¨π¦Canada pierre paul lefebvre
Hey @dylan-donkersgoed, nice work!
I'm interested in working on custom login link and maybe unique name id per idp.
Can you provide a bit more details on how you override the idp to be used?So it's kind of useless unless you're planning to supplement it with overrides outside the module (which I am).
The only way I've found, by reading your code, is to override the config variable, default_idp, but if I do that on a high traffic site, the ACS reply might be done on a different IDP than it was first requested. Unless you're overriding per site, which have different domain name?
Thanks!
- Merge request !12Draft: Issue #3088092: Multiple IDP Support β (Open) created by pierre paul lefebvre
- last update
almost 2 years ago 2 fail - π¨π¦Canada pierre paul lefebvre
My merge request is based on Dylan's work. I'm adding a custom event that can override the IDP to be used.
For my use case, I have a route that sets the IDP in the session, when the event is fired, the value is read from the session and returns the ID of the idp to use.It's working fine for my use case, but I just realized that I need to send a different SP id to my IDP. Im not sure if this should be considered a normal use case though. Right now the SP id (and certificates) are general configuration.
- π¨π¦Canada pierre paul lefebvre
Im currently at Drupalcon Lille and I'm planning on moving this task forward as much as possible. If anyone wants to join, I'll be at the contrib room everyday, whenever I have downtime :)
- πΊπΈUnited States jfurnas
the organization I work for is currently working with an agency that has multiple IdPs that they use to authenticate different types of users (one for internal users, connected to Active Directory, and one for all other users (considered external users)). As such, we need a solution that supports being able to use multiple IdPs simultaneously, not being able to store multiple but only be able to use one at a time.
Using this contrib module as a base and extending things in a custom module as needed, I've gotten a good ways into the process. I would like to contrib it back in an MR, but I think the customizations I am making would break backwards compatibility.
It currently stores multiple IdPs as configuration entities, each with their own fields based on the original single IdP values in the contrib module.
Then there is an additional configuration entity for creating 'logins' that allow you to create new 'Login' links on the login page, and creates a separate login route for each IdP, allowing you to use multiple ones at a time by using their route or clicking their link on the /user/login page.
- π³π±Netherlands roderik Amsterdam,NL / Budapest,HU
I would like to contrib it back in an MR, but I think the customizations I am making would break backwards compatibility.
Could you push your work to a new branch (with or without MR)?
There's no decision yet on a specific solution / set of code, because nothing was really reviewed yet. I admit to not looking at the other MRs yet.
(My work is volunteer time and without any set timeline, but sometime in the future....) I want to review
- the use of config entities for the per-IDP configuration, and how we can make this optional. (I suspect this will end up in a separate add-on module, and before it gets merged into the main module there should probably be an 'update path' from the plain config... which shouldn't be hard to make. I'm curious whether y'all have made different choices for which config properties to 'diversify'.)
- your config entities for 'login'. I don't have a mental picture yet of how this module should implement "the decision which IdP to use"; from the comments in this issue, I gather that Dylan has implemented a generic event for this, and your 'login entities' are the first 'complete' solution.
I think, before this module includes with multiple IdP support, it must include a ''complete' solution / 'point 2'. But if it is 'opinionated' / other people would want to implement it differently... then this (e.g. your) solution can become the 'reference implementation' in another optional module... that is e.g. implemented on top of Dylan's event.
After reviewing the code, I'll hopefully be able to form a mental image and a better opinion, and will comment on it here. Of course anyone else can do that too :-)
P.S. thanks for mentioning an actual non-dev use case for multiple IdPs.
- πΊπΈUnited States jfurnas
@roderick I am currently working on getting my changes into a separate branch/fork as a 'draft branch' so I can get it pushed up and looked at.
As for the backwards compatibility, I think I may have figured it out. In the latest iteration I have been working on, the 'Identity Provider' details panel remains on the 'SAML Configuration' page, with some additional markup added to indicate that the settings in that section are the 'default values'. (Or the values used when only a single idp has been configured)
The SamlService loads the configuration values from the passed in IDP configuration entity, or falls back to the 'config' values if one isn't provided (or it's invalid). This 'should' retain backwards compatibility. (Since anyone currently using the module would have a valid and populated $config.
As for the 'login entities', I was proposing either an additional configuration entity called 'idp login' (or baking it into the default schema for for the identity provider configuration entity), that would create new 'Login' links on the /user/login page (similar to how the single idp one works now), but would instead create a unique route for each idp (e.g. /saml/login/idp_id, /saml/login/idp_id2), that would be passed into the login route handler, and pass that correct idp entity id into the SamlService.
When users enable the option to disable the default /user/login page, the proposal would be to make a new intermediary page if multiple IDPs are configured, that works similar to the default /user/login page), that generates a list of the configured login links they can select from.
- πΊπΈUnited States jfurnas
Okay, I pushed my work up. I don't want to discredit Dylan's work, but it was several years old and the mainline branch was way ahead of it on commits, so I replaced most of his work with mine. There's still work to be done and the schema isn't mapped out fully yet so this should be considered a 'draft'.