All parts of the resolver are always executed (in a default configuration), even though much of the data gathered may be discarded later on in the attribute release/filtering stage. Because of this all configured data sources (such as LDAP Direcory Services or Relational Database Systems) should be highly available (and contain up-to-date, correct data, of course) – at least as highly available as you expect your IDP deployment to be. With LDAP directory servers achieving redundancy and replication usually is a much simpler (and cheaper) task than with RDBMSs, so sometimes it's worth the extra effort of synchronising data from other sources into an LDAP directory first, and only pointing the IDP to these LDAP data sources. But all of this depends on local Identity Management decisions and processes and no one recipie will fit all. Feel free to discuss pros and cons of approaches and tools on the eduID.at community mailing list.
Attribute resolver examples can be found in the
/opt/shibboleth-idp/conf/ directory of a default Shibboleth IDPv3 installation:
attribute-resolver-full.xml. Only the file
attribute-resolver.xml is used by default, though, and we'll replace its content with our own definitions below. Backup copies of all configuration files can always be found in
/opt/shibboleth-idp/dist/conf/ for comparison and as source for copying/pasting of more/other definitions. In fact much of the content below is just collected from those example configuration files.
The the attribute resolver contains two kinds of configuration items:
DataConnectors, which supply input data from data sources as described above, and
AttributeDefintions, which transform and encode the individual data elements (e.g. name, email address) retrieved from those DataConnectors into their proper on-the-wire representation as SAML attributes. Every AttributeDefintion references from where the input data should come from (DataConnectors or other AttributeDefinitions) with
Dependency elements, and specifies how it should be represented on-the-wire with
XML root element
This is the XML "container" element all AttributeDefinitions and DataConnectors need to be wrapped in. Be sure to also properly close the root element with the final line
</AttributeResolver> as shown below:
You can always perform minimal sanity checks on your configuration by checking the well-formedness of the XML, in this case with the command (from within your IDP's
Below are examples for all of the attributes commonly used in (inter-)federation today. As such all eduID.at IDPs should at least be able to create all of those attributes, but their specific definitions may vary from organisation to organisation, due to local Identity Management and software choices. For more details on the syntax and semantics of this part of the IDP configuration consult the relevant upstream documentation.
Also don't change the attribute
If you have created attribute definitions that might also be relevant for other members of the community – e.g. based on the widely used (within Austria) Campus Online software – please share them! Contributions to this wiki are very much welcome. You can also just send them to the eduID.at Operations Team, of course, and we will edit and include them here.
Many SAML Service Providers will need the subject's real name in one form or another, e.g. to allow collaboration between subjects based on trusted, verified names. Some applications will only be able to use names in separate fields (first name, last name) and some are content with a unified field that contains the full name in a format chosen by the institution or the subject herself. So for interoperability every IDP will need to be able to provide both forms. Assuming you have the subject's name availabe in an LDAP directory and configured a DataConnector for that (see further below), these are simple examples to use:
If you have the
displayName attribute available in your LDAP directory we'll go with that, as it's not generally being misused to store data other than the subject's real name (like "
cn" commonly is, e.g. storing the subject's login name or userid instead of her real name).
If you only have the "cn" LDAP attribute available and it contains the subject's full name (not her login name / userid) you can simply change the sourceAttributeID to become
sourceAttributeID="cn" in the first line of the example above. (Don't change anything else!) In this case you'll need to be aware that contrary to "cn" displayName is defined to be single-valued, though, and therefore you should be absolutely certain that your source attribute ("cn" in the modified example here) also only ever contains a single value per subject in your LDAP deployment, for all subjects! If that requirement cannot bet met you will need to use a slightly more complex AttributeDefinition that takes one of the values (usually the first one as returned by an LDAP search) and turns that into the displayName attribute. You can request such an example to be added to this wiki on the eduid-discuss mailing list.
If you don't have the subject's full name available in your LDAP deployment (or your "cn" attribute is unusable because it may contain multiple values for a subject, but your
sn attributes are single-valued) you can create this SAML attribute from first name and last name dynamically within the Shibboleth IDP:
With the notable exception of Library Services almost all (other) SAML Service Providers will need to consistently recognise a returning subject. I.e., they may not need to know who you are based on the identifier alone, but they will need to know that you are the same subject accessing their services as when you accessed them previously. That's what subjects expect themselfs, of course, otherwise all their work/data would be unavailable to them the next time they accessed the same service! See also this comparison of commonly used identifiers and their properties from the Shibboleth wiki.
There are a few types of identifier attributes in use within the federation community, each with their own unique properties, advantages and disadvantages. These are all explained in the Attributes section (or rather its child pages), for each attribute. So go read (and possibly re-read) those, as you will need to understand their definition and usage patters to be able to decide if/how you can support them in your IDP. As always: Discuss with the community if anything is unclear!
All eduID.at IDPs should be able to produce all of these identifiers, in order to be able to interoperate with – and make use of – all SAML Services Providers your community members may need to work with.
If you have a "mail" attribute with the subject's email address available in your LDAP directory, the example below is all you need. Ideally the LDAP attribute should in practice be single-valued (i.e., never contain more than one attribute value for a subject) as some SAML Service Providers cannot handle multi-valued attributes. This attribute's specification does allow for multiple values, of course, but you may make your life harder by not being able to supply a single-valued version of what's in your LDAP directory.
Some institutions may need more complex processing than the above, e.g. getting the value from one of several LDAP attribute depending on the role/affiliation of the subject (localPersonStudentMail, localPersonStafMail). The eduID.at community (or the eduID.at Operatons Team) will be able to supply you with other/more complex examples, so please ask.
Our documentation for creation and usage of eduPersonPrincipalName also contains some info on using email addresses as identifiers (and why/when best to avoid it), but sometimes services just need an email address for email's sake and will rely on other attributes for the unique identification of the subject.
eduPersonPrincipalName is commonly produced either from the local login name (uid, sAMAccountName) or by re-using a copy of the institutional email address as its value. Our documentation for that attribute explains the pros and cons of each approach in detail. Below you'll find examples for both main methods used to create that attribute. First, the variant based on login name (replace
sourceAttributeID="sAMAccountName" or whatever holds local login names in your LDAP directory):
And here's a definition when you've chosen to re-use the institutional email address as eduPersonPrincipalName attribute value.
Only do this if you are certain that all email address values for all subjects from your instituition are within (one of) your own institutional email domain(s). The eduPersonPrincipalName is filtered at SAML Service Providers to only allow domain values that have been whitelisted per each SAML Identity Provider, cf. the "attribute scope" column in the catalog of eduID.at Identity Providers. If needed you can ask the eduID.at operations team to whitelist more of your domains in your IDP's SAML Metadata, to match the email domains in use within your LDAP email attributes. But you cannot use email addresses as base for eduPersonPrincipalName attribute values if you populate external (arbitrary) email addresses in the referenced LDAP attribute.
A more complex example could use a ScriptedAttribute type definition to enforce in code that only email addresses matching local mail domains will be used, but what to do about those addresses that fail the check? So in such cases it's probably best to chose some other strategy to create eduPersonPrincipalName values.
eduPersonUniqueID can be seen as an opaque (not name-based, with long "ugly" values), more stable version of eduPersonPrincipalName. It is not widely used and is about to be replaced with the SAML SubjectID, but if you have eduPersonUniqueID in your IDP you can also trivially create the SAML SubjectID attribute from it. Best to be prepared, as to avoid problems with access to needed services. The example provided below re-uses configuration already made to support persistent NameIDs, namely the settings
idp.persistentId.salt from the file
Provided you already have a stable internal identifier for your subjects you can set that attribute in the
idp.persistentId.sourceAttribute property of the referenced config file, and it will also be used as the basis for the eduPersonUniqueID attribute. The configuration below will also re-use the salt configured in the property
idp.persistentId.salt to generate a salted hash of the chosen source attribute as (local part of the) eduPersonUniqueID attribute value:
If you do not have one such identifer readily available but you can fabricate one based on other/more data, that would be an alternative approach. For example, if login names may be reassigned at your organisation – meaning you cannot base you could concatenate the login name with something that's hopefully quite unique or sufficiently randomly distributed (e.g. the subject's birth date) to create another attribute with the IDP, that's a usable basis for eduPersonUniqueID attributes and persistent NameIDs. E.g. the combination
loginname+birthdate would hopefully be unique even if you ever reassigned a given login name to another person, as that other person is highly unlikely to also share the same birth date. Or if accounts get a new account creation date after re-activation you may also be able to use
loginname+accountcreationdate or something along those lines, which would then still be unique if the same login name would later be used in a new account for another (or even for the same) person.
Note that the source attribute to calculate the ID from (referenced in the
idp.persistentId.sourceAttribute property within the file
/opt/shibboleth-idp/conf/saml-nameid.properties) must exist with that same name in the
AttributeDefinition referenced as
Dependency near the begining of the
eduPersonUniqueID attribute definition. E.g. if you create a custom attribute within the resolver, named
id="person_id" in the IDP (using whatever methods and data sources available), and want to use that as basis for NameIDs, eduPersonUniqueID, etc. (by setting
idp.persistentId.sourceAttribute=person_id in your
saml-nameid.properties) you have to reference this
AttributeDefinition as dependency, note the second line of the second AttributeDefinition below:
Authorization / Org data
eduPersonScopedAffiliation is sometimes used for simple authorisation cases. eduPersonAffiliation describes a person's relationship with the IDP's organisation in general terms (from a controlled vocabulary of only 8 allowed values), and eduPersonScopedAffiliation is simply the scoped variant of that (i.e., the applicable affiliation values suffixed with "@" + the main institutional domain, same as for eduPersonPrincipalName or eduPersonUniqueID). Only the scoped version should be used for federated use cases: Even if a recieving Service Provider did not want to differentiate between e.g.
firstname.lastname@example.org it can always easily throw away the scope with minimal processing, yielding the unscoped version (here: "
staff" in both cases).
In the examples below we'll first create the unscoped version using one of several alternative methods, since this part will need be done differently at most organisations as it depends on local Identity Management choices. Then further below we'll create the scoped variant from that, in a configuration snippet that can be the same for everyone, no matter how the (unscoped) affiliation values was created.
Here's a first very simple example that creates a few of the affiliation values based on a regex match of some other attribute's value, in this case the login name as stored in the "uid" LDAP attribute (cf. sourceAttributeID). Replace with "
sAMAccountName" or "
cn" or whatever as needed in your deployment. This method can be used if you assign login names based on a schema that encodes the role/affiliation of a subject into her login name/userid. While overloading identifiers with semantics (such as role information) is not generally recommended such practices exist, so you might as well make use of them if it makes your IDP configuration easier. Note that identical
SouceValue elements are used twice below to make sure all
students are also members, and all
staff are also members, too, as required by the eduPerson specification.
Now here's another example where the correct affiliations are derived from the name of a locally defined group attribute (
phoUsergroup in the example below). This example uses partial string matches for the individual affiliations, and a regex that makes all subjects with any group value (at least, or also) a
And here's another example that derives the applicable affiliations from the subject's LDAP Distinguished Name (DN) or rather its place within the LDAP Directory Information Tree (DIT). The referenced sourceAttributeID
distinguishedName here is an operational attribute maintained by the LDAP server. (This may be called
entryDN in other LDAP server implemenations.) Everyone within OU=MitarbeiterInnen will be assigned
employee, only those within OU=Verwaltung,OU=MitarbeiterInnen will additionally become
staff, and so on.
In the final
ValueMap all employees, staff, faculty and students also get assigned "member", as required by the eduPerson specification.
There are of course many more ways this could be done, depending on local data available and LDAP deployment decisions (e.g. group implementation). The wiki for the old Shibboleth IDP v2.x software has more and more complex examples, including one to recursively map affiliations from nested groups within Microsoft "Active Directory" deployments.
Finally, it's time to turn the (unscoped) eduPersonAffiliation values created by one of the methods above into a properly scoped one:
eduPersonEntitlement is a container for all kinds of values and data, usually only with clearly defined values within closed communities. One notable exception is its global use for (location-independent, off-campus) authorisation to Library Services. Here's a simple example that should work for most, giving all subjects you have declared to have an
member earlier (see above) the
common-lib-terms entitlement, thereby stating that these all are entitled to access licensed resources on behalf of your organisation, according to the "common library licensing terms" (again, see Library Services for details):
Another use-case relevant to ACOnet and GÉANT communities is the GÉANT Trusted Certificate Service that relies on a specific
eduPersonEntitlement value to signal that a given subject satisfies the criteria to automatically issue them personal X.509 certificates (based on personal data provided in other SAML attributes, such as name and email address).
TCS has very specific requirements when someone should be marked as eligible to request personal certificates. Do not just blindly copy/paste the following configuration into your IDP before having read and understood those requirements. Cf. TCS Personal Certs and ACOnet Zertifikats-Service in this wiki, as well as https://www.aco.net/tcs.html for more information.
We can amend the previous example above to do both: Assign the
common-lib-terms entitlement to all
members, and also assert that all your subjects with the an affiliation of
faculty have had their identity sufficiently verified that they can all request personal certificates via TCS. (You'll need to adapt that second part as needed, also depending on what parts of your community you intend to offer the TCS personal service to.) I.e., for TCS we just add the second ValueMap to the above config, resulting in this example:
You can have several
SourceValue elements in a ValueMap, e.g. to additionally allow everyone with affiliation
student to get a personal certificate as well. See the examples above (eduPersonScopedAffiliation) or the Shibboleth wiki for details.
If you're supporting use of your Shibboleth IDP to access USI Wien services check out another variant to create
schacHomeOrganization is sometimes needed by services, usually as an IDP- and
entityID-independent identifier for an organization, e.g. to map subjects from an IDP to a contract in the name of the organisation that runs the IDP (without having to hard-code the IDP's entityID into some configurationn file or database). The following will work for anyone, based on the data connector provided below (that's also generic, thanks to its use of Java properties):
Add these two DataConnector XML elements to the same
attribute-resolver.xml file you've been adding the
AttributeDefinition XML elements to above, e.g. at the very end of the file (but before the closing tag of the AttributeResolver element).
First, here's a simple static DataConnector referenced by one of the AttributeDefinitions above. This only produces a single attribute (value), with an id of "schacHomeOrganization" and the IDP's scope as the sole value. "Static" here means its value(s) will unconditionally be produced for everyone using your IDP, no matter who they are or what attributes they have. That's perfectly fine for this SCHAC attribute since that's about identifying the organisation, not the subject.
And finally here's a verbatim copy of the default example of an LDAP DataConnector (taken from the file
attribute-resolver-ldap.xml). All the parameters and values in this DataConnector come from the
ldap.properties file in the IDP's
conf directory, so nothing needs to be set/changed here – with the exception of possibly removing some of the XML attributes. E.g. for deployments without any transport-layer security (no TLS and no SSL) when connecting to the LDAP directory servers you'll need to remove the
trustFile XML-attribute (i.e., the whole line starting with
trustFile), the rest should still work for everyone, based on the (correct, or default) settings in
If you're done with editing you can activate the changes in a running IDP by reload only the IDP's attribute resolver sub-system, without having to restart the whole Java container:
/opt/shibboleth-idp/logs/idp-process.log for any ERROR or WARN occurances.
That should cover producing all the common attributes in use in federation (and interfederation) today! Next move up to configuring attribute release.
<DisplayName xml:lang="de">Rollen an der Institution</DisplayName>