Claims from proxied OIDC RP flow do not propagate to ID token
Jiří Špaček
jiri.spacek at cvut.cz
Tue Apr 14 12:34:49 UTC 2026
Hi,
I'm trying to setup Shibboleth IdP 5.2.1 as an OIDC proxy using
following OIDCRelyingPartyAuthnConfiguration docs [1].
Downstream relying parties will connect to my IdP using OIDC as well.
For this purpose I'm following the OIDC OP docs [2].
I've successfuly configured and tested the OIDCRelyingParty authn flow
and can see the local IdP session is established correctly with
attributes populated from ID token claims from upstream OP (as
IdPAttributePrincipal in SubjectContext's authenticationResults).
For that I'm using a Subject passthrough data connector in my
attribute-resolver.xml:
<DataConnector id="passthroughAttributes" xsi:type="Subject"
exportAttributes="preferred_username name" />
The preferred_username and name custom claims are present in ID token
issued by upstream OP and I want them preserved as claims of the ID
token issued by my IdP to my relying parties.
However, when I try to log in to my relying party using OIDC.SSO
profile, the "preferred_username" and "name" attributes resolved during
OIDC.SSO flow are not present in the downstream ID token:
{
"at_hash": "j-5d_P2d4lRj2BQgxtuNkw",
"sub": "whatever at test.local",
"aud": "b5a9e179-c832-4aa3-86bf-8130f01d12d6",
"auth_time": 1776163397,
"iss": "https://idp.shibboleth.local",
"exp": 1776169528,
"iat": 1776165928,
"nonce": "vYOpKCJsEieosOM9voBxvEMcZWFazwo1Xb3R6-mWQNE",
"sid": "_ade2bc608e2894e621f8b127cd566ba9"
}
I've tried to step through "oidc-token-flow" in debugger and I can
clearly see that during ResolveAttributes action execution the attribute
resolution process does not resolve attributes specified in the
"passthroughAttributes" DataConnector because the SubjectContext is not
populated with any Subject during a RP's call to the Token endpoint
(same behavior occurs for UserInfo endpoint).
Excerpts from my configuration are following:
1. attribut-resolver.xml:
<AttributeDefinition id="subjectPublic" xsi:type="Scoped"
scope="%{idp.scope}"
activationConditionRef="shibboleth.oidc.Conditions.PublicRequired">
<InputAttributeDefinition ref="preferred_username" />
<AttributeEncoder xsi:type="oidc:OIDCScopedString" name="sub" />
</AttributeDefinition>
<AttributeDefinition id="subjectPairwise" xsi:type="Scoped"
scope="%{idp.scope}"
activationConditionRef="shibboleth.oidc.Conditions.PairwiseRequired">
<InputDataConnector ref="computedSubjectId"
attributeNames="subjectId"/>
<AttributeEncoder xsi:type="oidc:OIDCScopedString" name="sub" />
</AttributeDefinition>
<DataConnector id="computedSubjectId" xsi:type="ComputedId"
generatedAttributeID="subjectId"
salt="%{idp.oidc.subject.salt}"
algorithm="%{idp.oidc.subject.algorithm:SHA}"
encoding="BASE32">
<InputAttributeDefinition
ref="%{idp.oidc.subject.sourceAttribute}"/>
</DataConnector>
<DataConnector id="passthroughAttributes" xsi:type="Subject"
exportAttributes="preferred_username name" />
2. attribute-filter.xml contains only simple "alway release" rule for my
attrs:
<AttributeFilterPolicy id="alwaysRelease">
<PolicyRequirementRule xsi:type="ANY" />
<AttributeRule attributeID="preferred_username" permitAny="true" />
<AttributeRule attributeID="name" permitAny="true" />
<AttributeRule attributeID="subjectPublic" permitAny="true" />
<AttributeRule attributeID="subjectPairwise" permitAny="true" />
</AttributeFilterPolicy>
3. oidc-claim-rules.xml contain transcoding props for my custom claims:
<bean parent="shibboleth.TranscodingProperties">
<property name="properties">
<props merge="true">
<prop key="id">preferred_username</prop>
<prop key="transcoder">OIDCStringTranscoder</prop>
<prop key="oidc.name">preferred_username</prop>
<prop key="displayName.en">Preferred Username</prop>
</props>
</property>
</bean>
<bean parent="shibboleth.TranscodingProperties">
<property name="properties">
<props merge="true">
<prop key="id">name</prop>
<prop key="transcoder">OIDCStringTranscoder</prop>
<prop key="oidc.name">name</prop>
<prop key="displayName.en">Name</prop>
</props>
</property>
</bean>
<bean parent="shibboleth.TranscodingProperties">
<property name="properties">
<props merge="true">
<prop key="id">subjectPublic</prop>
<prop key="transcoder">OIDCStringTranscoder</prop>
<prop key="oidc.name">sub</prop>
<prop key="displayName.en">Subject</prop>
</props>
</property>
</bean>
And my questions are:
1. Is SubjectDataConnector supposed to be used like this in combination
with OIDC OP functionality? I must admit I've resorted after I saw some
SAML proxy examples on wiki but I'm not sure If it is compliant with
OIDC. The OIDCRelyingPartyConfiguration [1] manual did not mention this.
It seems the fact that calls to Token and UserInfo endpoints are
backchannel calls might be problem as opposed to SAML proxy usage.
2. Is subject C14N described here [3] related to this issue? I do not
care about sub claim value (our RP's only use the custom attribute) so I
thought I did not need to set this up.
2. Is there available a complete working example configuration of OIDC
OP plugin being used together with a OIDC RP proxy plugin?
Thanks in advance!
Jiri
[1]
https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/3013804089/OIDCRelyingPartyAuthnConfiguration
[2]
https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/1376878976/OIDC+OP
[3]
https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/pages/3013804089/OIDCRelyingPartyAuthnConfiguration#Subject-Canonicalization
More information about the users
mailing list