Needs work
Project:
SAML Authentication
Version:
8.x-3.x-dev
Component:
Code
Priority:
Normal
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
15 Oct 2019 at 16:38 UTC
Updated:
30 Apr 2026 at 14:30 UTC
Jump to comment: Most recent
Comments
Comment #2
cweagansSounds interesting. I'm not opposed, but I imagine this would be the start of a new branch, right?
Comment #3
jesconstantineHello!
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!
Comment #4
roderikHi 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:
(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.
Comment #7
dylan donkersgoed commentedI'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:
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.
Comment #8
pierrepaul commentedHey @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?
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!
Comment #10
pierrepaul commentedMy 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/shared configuration.
Comment #11
pierrepaul commentedIm 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 :)
Comment #12
jfurnas commentedthe 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.
Comment #13
roderikCould 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
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.
Comment #14
jfurnas commented@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.
Comment #15
jfurnas commentedOkay, 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'.
Comment #16
jfurnas commentedI just ended up creating a new module to handle the extension of the samlauth module to support multiple IdPs. It's still in development but being developed in a real-world use case so should work as expected. This was to ensure I could properly maintain it if needed.
On module installation it copies the values of the configured idp in /config/people/saml into a 'default' config entity. This default config entity can't be deleted, and acts as a fallback for if an invalid idp is provided, or no idp is provided. If samlauth hasn't been configured yet, a default idp is created with some placeholder data.
https://drupal.org/project/samlauth_multi_idp
Comment #17
roderikThank you. I mentioned the module in the README + project page
In my mind, this makes it even more important to document a clear opinion on whether your module satisfies users' needs or any work is needed in this queue. I admit to not having reviewed it myself yet. (Forever lagging behind and closing other bugs in the queue first.)
Comment #18
jfurnas commentedThank you. We put this through it's paces during our implementation with a lot of back and forth with the iDP during development, so it's got a pretty solid base.
We are going to be starting another site using this implementation very shortly, and will be able to provide some more feedback then.
Comment #19
varunity commentedI appreciate you creating a separate module @jfurnas. I created a patch that addresses this issue of supporting multiple IDPs by leveraging the `key` module (which `samlauth` already integrates with). Take a look and let me know if it works for your use case: https://www.drupal.org/project/samlauth/issues/3578383 . Essentially you can store the different IDP details as environment variables so that they are picked up automatically.