Date: Thu, 28 Mar 2024 20:02:44 +0000 (UTC) Message-ID: <1972507820.35.1711656164650@456e64462cba> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_34_1922032808.1711656164650" ------=_Part_34_1922032808.1711656164650 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
This is a summary of the origins, issues, and SP best pra= ctices associated with the eduPersonTargetedID attribute.
While extending SAML, the Liberty Alliance developed a concept they call= ed "federated" identifiers. In their terms, federating a user is accomplish= ed by creating an opaque identifier for the user that is specific to both a= n IdP and an SP, and is shared only between them. This was termed a "federa= tion handle" and was designed to preserve privacy and prevent correlation o= f user activity across unrelated services.
Conceptually, a federation handle consisted of three required pieces of = data:
An SP was also permitted to attach an optional "alias" for the user that= it could rely on the IdP to pass to it each time the user was referenced s= o that systems could both avoid rekeying and secondary indexing.
In SAML 2.0, the same concept was evolved into something called a "persi= stent" NameID format, the term "federated" having political connotations un= acceptable at the time to at least one of the companies participating in th= e process. The wire-level syntax is different in SAML than in Liberty, and = some of the rules are a bit more precise, but the concept is identical.
While the SAML standard was evolving, the Shibboleth project identified = a need for something analagous to the Liberty concept in the work it was do= ing with SAML 1.1. With a focus on SAML attributes, and because of limitati= ons in the older SAML schema, it was decided to define this concept as an a= ttribute called "eduPersonTargetedID" within the eduPerson specification an= d develop a syntax for it as a SAML attribute.
In formally defining the attribute, the same "triple" of data was used, = and the notion of an SP alias was dropped as unnecessarily complicated. A f= ew more precise rules were written as to the processes that would go into m= anaging the attribute, but it was largely envisioned as a SAML 1.1 Attribut= e "equivalent" to the Liberty (and eventually SAML 2.0) concept.
Unfortunately, during this phase of the project, shipping code often pre= ceded formalization, and a significant mistake was accidently propagated in= to the Shibboleth releases, in which the syntax of the example implementati= ons of this attribute was botched. Instead of fully representing the three = pieces of data mentioned above, a "simplified" version of the attribute was= used in which a DNS domain (e.g. osu.edu) replaced the full entityID of th= e IdP. This so-called "scoped" syntax became common among early adopters an= d has led to a number of interoperability and complexity problems as a resu= lt.
Were it not for the "botch" mentioned above, this would be a simple stor= y, but unfortunately it's not.
As a starting point, let me outline the formal/XML representations recog= nized by the Shibboleth project/community. Each representation is of the sa= me underlying data.
Note that regardless of whether the resulting <NameID>
appears in a SAML attribute (eduPersonTargetedID) or in the <Sub=
ject>
of an assertion, using it to perform SAML queries or other =
forms of communication with the IdP would depend on the IdP's ability to "r=
everse" the identifier back into the local user identity.
In Shibboleth, the two are essentially interchangeable because the "revers=
ibility" property is dependent solely on the use of a <PrincipalCo=
nnector>
in the attribute resolver. Other implementations are lik=
ely to be more limited and tend to draw distinctions between attributes and=
subject identifiers.
This is the usually recommended approach to passing an eduPersonTargeted= ID to SAML 2.0 SPs, including Shibboleth 2.x. Instead of using a SAML attri= bute, the information is passed in the subject of the assertion:
<saml= 2:Subject> <saml2:NameID xmlns:saml2=3D"urn:oasis:names:tc:SAML:2.0:assertion" Format=3D"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier=3D"https://idp.example.org/idp/shibboleth" SPNameQualifier=3D"https://sp.example.org/shibboleth"> 84e411ea-7daa-4a57-bbf6-b5cc52981b73 </saml2:NameID> </saml2:Subject>
See the IdPPersistentNameIdentifier<=
/a> topic for information on producing this result. The main requirement is=
to attach an "AttributeEncoder" of type SAML2StringNameID
to =
the source attribute in the resolver:Attr=
ibuteDefinition; i.e., <
resolver:AttributeEncoder
=3D
As an alternative, it's possible to embed the same syntax above inside a= SAML attribute with the formal name "urn:oid:1.3.6.1.4.1.5923.1.1.1.10". T= he main reason for doing this would be to preserve the ability to pass a di= fferent kind of identifier in the assertion subject. One use case for this = is to support the use of computed/non-reversible values for the "targeted" = ID, but use transient, reversible values in the subject to support attribut= e queries or logout.
<saml= 2:Attribute xmlns:saml2=3D"urn:oasis:names:tc:SAML:2.0:assertion" NameFormat=3D"urn:oasis:names:tc:SAML:2.0:attrname-format:uri" Name=3D"urn:oid:1.3.6.1.4.1.5923.1.1.1.10" FriendlyName=3D"eduPersonTargetedID"> <saml2:AttributeValue> <saml2:NameID Format=3D"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier=3D"https://idp.example.org/idp/shibboleth" SPNameQualifier=3D"https://sp.example.org/shibboleth"> 84e411ea-7daa-4a57-bbf6-b5cc52981b73 </saml2:NameID> </saml2:AttributeValue> </saml2:Attribute>
See the IdPAddAttribute topic for informatio=
n on producing this result. The main requirement is to attach an "Attribute=
Encoder" of type SAML2XMLObjectAttributeEncoder
to the source =
attribute in resolver:AttributeDefinition=
; i.e., <
resolver:AttributeEncoder
xsi:type
=3D
"SAML2XMLObject"... />.
This is the recommended approach to passing an eduPersonTargetedID to SA= ML 1.1 SPs, including Shibboleth 1.3.x. It is very similar to the attribute= -based syntax above and uses the same formal name.
<saml= :Attribute xmlns:saml=3D"urn:oasis:names:tc:SAML:1.0:assertion" AttributeNamespace=3D"urn:mace:shibboleth:1.0:attributeNamespace:uri" AttributeName=3D"urn:oid:1.3.6.1.4.1.5923.1.1.1.10"> <saml:AttributeValue> <saml2:NameID xmlns:saml2=3D"urn:oasis:names:tc:SAML:2.0:assertion" Format=3D"urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier=3D"https://idp.example.org/idp/shibboleth" SPNameQualifier=3D"https://sp.example.org/shibboleth"> 84e411ea-7daa-4a57-bbf6-b5cc52981b73 </saml2:NameID> </saml:AttributeValue> </saml:Attribute>
See the IdPAddAttribute topic for informatio=
n on producing this result. The main requirement is to attach an "Attribute=
Encoder" of type SAML1XMLObjectAttributeEncoder
to the source =
attribute.
Finally, the original "botched" syntax is below. Unfortunately, this is = probably by far the most common approach one will see today. It is however = incorrect.
<saml= :Attribute xmlns:saml=3D"urn:oasis:names:tc:SAML:1.0:assertion" AttributeNamespace=3D"urn:mace:shibboleth:1.0:attributeNamespace:uri" AttributeName=3D"urn:mace:dir:attribute-def:eduPersonTargetedID"> <saml:AttributeValue Scope=3D"https://idp.example.org/idp/shibboleth"&= gt;84e411ea-7daa-4a57-bbf6-b5cc52981b73</saml:AttributeValue> </saml:Attribute>
Both branches of the SP software have extensive support for parsing and = communicating the various forms of eduPersonTargetedID to applications.
The newer SP supports all of the forms discussed above and includes addi= tional plugins to ease the job of migrating eduPersonTargetedID consumers t= o the proper syntax.
The three proper forms that rely on a SAML 2.0 NameID element are by def= ault (in the attribute-map) interchangeably handled and reflected to applic= ations as an SP attribute called "persistent-id". By default, the attribute= is expressed by concatenating the three pieces of data together with a ban= g (!) symbol as follows (using the example data above).
https:/= /idp.example.org/idp/shibboleth!https://sp.example.org/shibboleth!84e411ea-= 7daa-4a57-bbf6-b5cc52981b73
However, this string can be modified as required by the application to i= nclude or exclude each component and use any separator desired. For details= , see the documentation for the NameIDAttr= ibuteDecoder.
The broken form by default is mapped to an SP attribute called "targeted= -id" (to help delineate it from the proper form) and is expressed as a "sco= ped" string with the following @-delimited form:
84e411e= a-7daa-4a57-bbf6-b5cc52981b73@example.org
As a migration feature to encourage adoption of the proper syntax, an al= ternate plugin can be enabled for consuming the deprecated syntax that prod= uces the same result as the proper syntax would, by dropping the "scope", a= nd substituting the entityID of the IdP source of the value. This feature i= s called a NameIDFromScopedAttributeDecode= r for reasons that are hopefully clear at this point.
The older SP only supports SAML 1.1 and therefore can only process the t= wo SAML 1.1 attribute forms. Both the broken form and the proper form are b= uilt-in to the default configuration using some custom attribute handling c= ode and a pair of rules in the AAP file.
When processing the two forms, the SP will "publish" the attribute infor= mation to the application using a different string form depending on which = syntax is found. It lacks the flexibility and customization of the newer SP= and consumers of eduPersonTargetedID are urged to upgrade.
The proper form was handled by concatenating the three pieces of data to= gether with a bang (!) symbol as follows (using the example data above). Th= is was a hard-coded approach that can't easily be altered without plugging = in additional code or altering the source code while building it.
https:/= /idp.example.org/idp/shibboleth!https://sp.example.org/shibboleth!84e411ea-= 7daa-4a57-bbf6-b5cc52981b73
The broken form was handled by treating the attribute as "scoped", resul= ting in the following @-delimited form:
84e411e= a-7daa-4a57-bbf6-b5cc52981b73@example.org
While both forms can be handled at once, and they obviously will never o= verlap, the specific data seen for a given user will depend on which form t= he IdP chooses to use. This is in contrast to the migration capability adde= d to the newer SP and discussed above.
Having plowed through all that background, what the heck are you suppose= d to do? I'll try and be succinct because I hope that the mess above explai= ns why this is the kind of thing that needs a clear approach to deal with.<= /p>
In my opinion, an SP that wants a robust service should follow these gui= delines:
That's it. If you follow those steps, you should be able to ignore the p= roblems with the broken syntax and leave it to the IdPs you deal with to fi= x their systems on whatever timeline they can fix them. None of these steps= requires significant coordination with anybody, and the rekeying process s= hould be safe to perform.
One of the pressures that I've observed in some of the resistance to get= ting this problem fixed is that the broken syntax is much shorter than the = proper syntax can generally be, and is also more "understandable", since it= resembles other identifiers like eduPersonPrincipalName. While this is tru= e, I think it's safe to say that no user is going to want to look at the va= lue in any case, and treating it as anything but an internal identifier is = a mistake anyway.
The length argument, on the other hand, is legitimate and not perfectly = solved at this point. Unfortunately, for historical and frankly stupid reas= ons, SAML places very few limits on the possible length of the various comp= onents. An entityID can in theory be huge, up to 1024 characters. The ident= ifier portion is more limited, but still only to 256 characters.
Obviously it's completely impractical to allow for an identifier over 1K= , let alone 2K. Unfortunately, the best I can offer right now is that in pr= actice, this doesn't come up. Nobody uses an entityID that long, and limiti= ng the size to 512 or even 256 is almost certainly good enough.
The downside is that you have to at least allow for the chance you'll ge= t one that's too long and deal with that error condition, but I would suspe= ct that the chances of that error are very small, and likely to be "global"= to an entire site such that some kind of accomodation can be made at the t= ime this is noticed. It shouldn't happen on a per-user basis.
Hashing is of course another option, but a hash isn't reversible, and th= is will create problems when tracking back or communicating with the IdP ab= out a user.