OPSubClaim

Overview

A special claim called "sub" is defined in the OIDC core specification as carrying the unique identifier for the subject. SAML historically is much more general and accomodated lots of good and bad (ok, mostly bad) practices around subject identification, leading to a lot of confusion for everybody.

The "sub" claim is somewhat analagous to the recently standardized SAML "subject-id" and "pairwise-id" attributes and it is usually advisable to use the same underlying sources of data for both. There are additional mechanical requirements to the "sub" claim because it can be either pairwise or non-pairwise based on RP client registration, and there are special activation condition beans predefined for you that can automate these rules.

Unlike in SAML, it is necessary to provide some source of "sub" claim to be compliant, so you must consider how you want to do this early in the process. Of course, for testing, these decisions can be temporary, but "testing" often becomes "production" sooner than one might expect.

If you have questions about all this, it's strongly suggested you leverage one of the support options to ask them, because these are hugely critical decisions that have nearly permanent implications. You do not want to make a mistake in production with this. You are not Google and don't get to just break everybody because you feel like it.

Configuration

The examples at the top of the oidc-attribute-resolver.xml file demonstrate a couple of different approaches to "sub" claim generation. You may save some time by importing the example file into your resolver service resources via conf/services.xml but may need to comment or remove some of the other examples. Alternatively just add the new XML declarations in the root element to your own resolver configuration and copy the parts you need. Note that because the "sub" claim is unusual, there are no default transcoding rules for it, and dedicated, OIDC-specific <AttributeEncoder> elements are attached to produce the proper claim name. It’s certainly possible to do so with transcoding rules if preferred.

A recommended strategy is one in which the public "sub" variant is produced by slapping a scope suffix on the end of a value you use for stable identification of your user population, such as an IDM-assigned serial number, employee/student/guest ID, etc. The pairwise variant is a salted hash of this same underlying value.

An alternative approach is one in which an underlying value is fed into a salted hash that will be either pairwise or not based on the RP registration, but will in both cases "mask" the underlying input value. This makes provisioning user access out of band and supporting applications much more complex, as well as fostering the misguided idea that identifiers should be "secret", a mistake that should be familiar to deployers that remember when SSNs had to be remediated.

Both approaches are syntactically compatible in most cases with the SAML "subject-id" and "pairwise-id" requirements, though the activation conditions are specific to the OIDC case, so separate AttributeDefinitions are needed.

The examples supplied rely on a handful of properties in conf/oidc.properties to set some of the important input values

Once you have a strategy for producing the claim, you will also need a filter policy that releases the "sub" claim for RPs that request the "openid" OIDC scope. An example rule for this can be found in the oidc-attribute-filter.xml file, or you may want to add that file into the set of filter service resources in conf/services.xml.

Reference

Properties related to "sub" claim generation in oidc.properties are:

Name

Default

Description

Name

Default

Description

idp.oidc.subject.sourceAttribute



Source of data to use to compute pairwise (and/or public) value

idp.oidc.subject.algorithm

SHA

Digest algorithm used to compute pairwise (and/or public) value

idp.oidc.subject.salt



Salt to inject for randomness, should generally be moved into credentials/secrets.properties to avoid committing to configuration repository

Beans related to "sub" claim generation are:

Name

Type

Description

Name

Type

Description

shibboleth.oidc.Conditions.PublicRequired

Predicate<ProfileRequestContext>

An activation condition that evaluates to true if and only if the client registers for a public "sub" claim and the request involves the authorization endpoint

shibboleth.oidc.Conditions.PairwiseRequired

Predicate<ProfileRequestContext>

An activation condition that evaluates to true if and only if the client registers for a pairwise "sub" claim and the request involves the authorization endpoint

shibboleth.oidc.Conditions.SubjectRequired

Predicate<ProfileRequestContext>

An activation condition that evaluates to true if and only if the request involves the authorization endpoint (the type is determined internally based on the client's registration)