TL;DR: How can I get SaToSa to select one attribute's value from a
list of attribute names, not all of which may be present?
Ivan's recommendation from PR 222 doesn't work for me:
https://github.com/IdentityPython/SATOSA/pull/222#issuecomment-533238061
Context: I'm trying to use SaToSa as a SAML SP registered in a
saml2int identity federation (SAML2 backend module plugin) protecting
a bunch of OIDC RPs (openid connect frontend module plugin).
In the field not all SAML IDPs support all of the common identifier
attributes: Some may only support e.g. eduPersonPrincipalName while
others will also (or in an hypothetical future maybe: only) support
the "new" SAML standard identifier attributes Subject-ID and/or
Pairwise-ID. (And while I could hard-code 'eppn' as the lowest common
denominator for everyone that would nullify any benefits the new
standard identifier attributes might offer.)
FWIW, the Shibboleth SP calls its own support for this the REMOTE_USER
precedence list: The first attribute from a list of given attribute
names that has a value is chosen as the value for REMOTE_USER.
Implementing Ivan's recommendation from PR 222 (link above) doesn't
work for me, though. This fails:
attributes:
id:
openid: [sub]
saml: [subject-id, pairwise-id, eppn]
eppn:
openid: [eppn]
saml: [eduPersonPrincipalName]
user_id_from_attrs: [id]
The relevant log lines being:
skipped backend attribute ['subject-id', 'pairwise-id', 'eppn']: no value found
backend attribute ['eduPersonPrincipalName'] mapped to eppn (['foo(a)example.org'])
...
KeyError: 'id'
[ERROR] [satosa.proxy_server.__call__] Unknown error
I.e., eppn is available/mapped but generating the userid from the 'id'
attribute fails, seemingly because there is no 'id' attribute because
according to SaToSa the list ['eppn', 'subject-id', 'pairwise-id'] has
"no value found".
The available behaviour is unhelpful in two regards, AFAICT:
https://github.com/IdentityPython/SATOSA/pull/222#issuecomment-533240357
* It implements "all those attributes need to have a value (what
currently happens)" (Ivan's words from PR 222) when I've only ever
needed "at least one of these attributes needs to have a value" in
over a decade of running federations and federated services.
* The attributes I care about and would list as possible attribute
names are also *not* mutually exclusive, i.e., there may be none
(failure), some or all of them available from an IDP. In any case
I'd want the user id to only ever have the value of **one** such
attribute at maximum, even if multiple attributes may have values.
TBH, I can't see how the documented behaviour:
https://github.com/IdentityPython/SATOSA/tree/master/doc#user_id_from_attrs
> The attribute values of the attributes specified in this list will
> be concatenated and used as the subject identifier.
could ever be useful to anyone? What good would be the concatenation
of multiple attributes' values (e.g. ['subject-id', 'pairwise-id',
'eppn']) provided several of them were available?
"foobar@example.orgFOO987654321@example.orgFOO@example.org"
Whereas from my experience it's often necessary to support multiple
"acceptable alternatives" (different attributes for essentially the
same purpose/data) and therefore desireble to have the software pick
*one* attribute's value(s) from an ordered-by-preference list.
E.g. given ['subject-id', 'pairwise-id', 'eppn'] that would try
subject-id, then pairwise-id, then eppn and the first one that has a
value would be the one attribute whose values we'd return.
(I'd fail if none of the above were present/had a value.)
Is there a way to get that behaviour? I'm probably biased but to me that
would make a much saner default behaviour than what's available now.
Best regards,
-peter