Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Expand
titleComputed IDs

The defaultĀ PairwiseIdStore implementation is a hash/digest-based approach called "Computed" that avoids the need for a database to store the IDs, but is incapable of reverse-mapping a given identifier (e.g., as part of a SAML attribute query), or revoking or changing the identifier associated with a subject. Tracking back to a subject for debugging purposes generally involves the use of audit logs rather than direct access to a mapping of users. It's not the best approach in the abstract, but it is much simpler to deploy.

To enable the Computed strategy, you must set additional properties:

  • idp.persistentId.sourceAttribute

    • A list of attributes from which to derive a "source" key for the subject. The key is used as the hash input, and should be a very stable value for each subject and must never be reassigned later to a different subject. This should be a permanent serial number associated by an IDMS to each account, and not a name-based identifier like a login ID or email address. It should also be technology-neutral; using a GUID generated by an Active Directory is a very bad choice that will lead to problems if you ever change directories.

  • idp.persistentId.salt

    • A secret string used as a default salt when hashing the subject key derived from the property above. This is required to prevent trivial attacks to determine the identifier for a given subject, and must be kept secret. Note that leading or trailing whitespace is not trimmed from the property, though using whitespace in the salt is not advisable.

  • idp.persistentId.encodedSalt

    • If your salt value contains special characters that Spring won't accept safely, you can work around this by base64-encoding the salt you want to use, and specifying the encoded version in this property instead of the previous property. Do not set both.

    idp.persistentId.encoding

    • Controls the encoding of the generated hash value. Defaults to BASE64 if not set, but new installations set this property to BASE32 to produce values without mixed case.

The attribute used as the source key need not be released (in the sense of an attribute filter policy) to the SP.

Dynamic Salt 4.3

V4.3 introduces the option to configure a dynamic salt source using a BiFunction (a Java function object that takes two inputs). If a bean named shibboleth.ComputedIdSaltLookupStrategy is defined, the function will override the value of the salt to use for a request, or if it returns null will suppress generation of a value entirely. This works in combination with the Sparse Override map desribed in the next section (i.e., the map overrides the BiFunction which overrides the default). It is also now legal to only define the BiFunction and omit the global salt if desired.

The bean is of type BiFunction<ProfileRequestContext,PairwiseId>

The intent is that the second argument will supply details about the request such as the subject and relying party, while the first provides full access to request state.

A trivial example that is equivalent to just using a global salt would be:

Code Block
    <bean id="shibboleth.ComputedIdSaltLookupStrategy" parent="shibboleth.BiFunctions.Constant">
        <constructor-arg>
            <value>thisisasaltsalthisis</value>
        </constructor-arg>
    </bean>

Sparse Overrides

One of the disadvantages of strictly computing IDs is a loss of manageability of the values, particularly the ability to change a value should it become compromised. The IdP includes a feature allowing fine-grained override of the salt value used to generate IDs for specific users and/or relying parties, by means of a Java Map bean, which can be declared in saml-nameid.xml, and by default is named shibboleth.ComputedIdExceptionMap

The Java type of the object is a mouthful: Map<String,Map<String,String>> (i.e., it's a string-keyed map whose values are themselves maps). It's easier to grasp this in practice in the example below.

The primary keys are the names of subjects/users, or an asterisk (*) to signify a wildcard rule.

The values are maps of Relying Party names to salt values. These keys are the names of relying parties or an asterisk (*) as a wildcard, and the values are either a substitute salt string to use, or can be null to block the generation of an ID altogether.

One use for this feature is to maintain an old salt value for a legacy service while relying on a new value for everybody else:

Overriding salt for a single SP
Code Block
languagexml
<util:map id="shibboleth.ComputedIdExceptionMap">
	<entry key="*"> <!-- all users -->
		<map>
			<entry key="https://legacysp.example.org/sp" value="legacysalt" />
			<entry key="https://invalid.example.org/sp">
				<null/>	<!-- blocks generation of a value for this SP -->
			</entry>
		</map>
	</entry>
</util:map>

...