Using OpenID with Sogo + dovecot / Adding a secondary aud claim to OpenID access tokens
Henri Mikkonen
henri.mikkonen at nimbleidm.com
Fri Jun 13 12:38:44 UTC 2025
Hi Max,
My idea was to inject a message handler to the OIDC.SSO -profile. The
handler would need to detect that the message is an authorization
request, as the same handler-hook is used for both request and response
messages. For the request messages, your script should then add the
desired resource-parameter to the message, and OP would then act in the
same way as the client/RP would have included it by itself.
As documented, the function type for message handler is:
Function<MessageContext,Exception>. The CustomNimbusRequestParser
interface is related to the custom parsing, which is different hook from
the message handler.
BR,
Henri.
On 13.6.2025 11.16, Max Nuding via users wrote:
> Hi Henri,
>
> this already help a lot, thank you!
> I'm now able to add the audience to the client metadata. But I think it
> might be a dead end. It doesn't seem to do anything without SoGo
> requesting a resource.
>
> I'm trying my luck with OPMessageHandling now, but can't really get a
> grasp on it. If i read it correctly, I would need to set the following
> in relying-party.xml:
>
> <ref bean="OAUTH2.Introspection"
> p:messageHandler="CustomMessageHandler"/>
>
> <bean id="CustomMessageHandler">
> parent="shibboleth.Functions.Scripted"
> factory-method="inlineScript">
> <constructor-arg name="scriptSource">
> <value>
> <![CDATA[
> // TODO
> ]]>
> </value>
> </constructor-arg>
> </bean>
>
> But I don't understand how parse(HTTPRequest) and
> CustomNimbusRequestParser<T> play into it.
> I can't create a bean for CustomNimbusRequestParser, because it's an
> interface.
>
> Another entry point I'm currently exploring is OPToken [1] and
> OPScopeFiltering [2] where I should be able to set a custom "these
> audiences are valid", but I'm currently stuck on how to get a hold of
> the original audience and client info there and return multiple audiences
>
>
> Best
> Max
>
> [1]: https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/
> pages/2931327005/OPToken
>
> [2]: https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/
> pages/3001352203/OPScopeFiltering
>
> On 13.06.25 10:15, Max Nuding wrote:
>> Hi Henri,
>>
>> this already help a lot, thank you!
>> I'm now able to add the audience to the client metadata. But I think
>> it might be a dead end. It doesn't seem to do anything without SoGo
>> requesting a resource.
>>
>> I'm trying my luck with OPMessageHandling now, but can't really get a
>> grasp on it. If i read it correctly, I would need to set the following
>> in relying-party.xml:
>>
>> <ref bean="OAUTH2.Introspection"
>> p:messageHandler="CustomMessageHandler"/>
>>
>> <bean id="CustomMessageHandler">
>> parent="shibboleth.Functions.Scripted"
>> factory-method="inlineScript">
>> <constructor-arg name="scriptSource">
>> <value>
>> <![CDATA[
>> // TODO
>> ]]>
>> </value>
>> </constructor-arg>
>> </bean>
>>
>> But I don't understand how parse(HTTPRequest) and
>> CustomNimbusRequestParser<T> play into it.
>> I can't create a bean for CustomNimbusRequestParser, because it's an
>> interface.
>>
>> Another entry point I'm currently exploring is OPToken [1] and
>> OPScopeFiltering [2] where I should be able to set a custom "these
>> audiences are valid", but I'm currently stuck on how to get a hold of
>> the original audience and client info there and return multiple audiences
>>
>>
>> Best
>> Max
>>
>> [1]: https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/
>> pages/2931327005/OPToken
>>
>> [2]: https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/
>> pages/3001352203/OPScopeFiltering
>>
>>
>>
>> On 12.06.25 12:03, Henri Mikkonen wrote:
>>> Hi Max,
>>>
>>> As you seem to have very limited capabilities to modify the client/RP
>>> behaviour, one alternative is to customize the request message
>>> parsing on the OP-side. See OPMessageHandling page [1].
>>>
>>> For additional claims within dynamic client registration, check
>>> profile- specific metadataPolicy option in [2]. You may also exploit
>>> the property
>>> "idp.oidc.dynreg.defaultMetadataPolicyFile" for defining the file
>>> containing the policy. Some examples are described here [3].
>>>
>>> BR,
>>> Henri.
>>>
>>> [1] https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/
>>> pages/3785326593/OPMessageHandling
>>>
>>> [2] https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/
>>> pages/1376879077/OPDynamicClientRegistration
>>>
>>> [3] https://shibboleth.atlassian.net/wiki/spaces/IDPPLUGINS/
>>> pages/2948497410/OPMetadataPolicies#Policy-Examples
>>>
>>> On 12.6.2025 11.16, Max Nuding via users wrote:
>>>> Hi Henri,
>>>>
>>>> thanks.
>>>>
>>>> 1. But I don't think I *can* configure SOGO to indicate the IMAP-
>>>> resource. Its configuration options regarding OpenID are extremely
>>>> limited.
>>>>
>>>> 2. Even then, how would I add the audience? We're using dynamic
>>>> client registration, and "audience" is not one of the allowed
>>>> parameters of the client registration. Is there another JSON I'm
>>>> missing?
>>>>
>>>> Best
>>>> Max
>>>>
>>>> > Hi,
>>>> >
>>>> > You can configure SoGo to obtain an access token to be targeted
>>>> to the
>>>> > IMAP server in addition to the OP itself. The default target in OIDC
>>>> > sequence is the OP, as access token is used in the userinfo
>>>> endpoint.
>>>> >
>>>> > Three following things are needed:
>>>> >
>>>> > 1. Configure SoGo to indicate the IMAP-resource as defined in RFC
>>>> 8707.
>>>> > In short, the resource-parameter should have a value equal to the
>>>> IMAP's
>>>> > client_id.
>>>> >
>>>> > 2. Configure IMAP as SoGo's trusted audience
>>>> > - In JSON metadata, add audience=<IMAP_client_id> attribute, or
>>>> check
>>>> > [1] how to do it in SAML metadata if you use that
>>>> >
>>>> > 3. In conf/relying-party.xml, enable OAUTH2.TokenAudience profile
>>>> either
>>>> > globally (for shibboleth.DefaultRelyingParty) or at least for the
>>>> IMAP
>>>> > client:
>>>> >
>>>> > <util:list id="shibboleth.RelyingPartyOverrides">
>>>> > <bean id="IMAPAudience" parent="RelyingPartyByName"
>>>> > c:relyingPartyIds="<IMAP_CLIENTID>">
>>>> > <property name="profileConfigurations">
>>>> > <list>
>>>> > <bean parent="OAUTH2.TokenAudience"
>>>> > p:encryptionOptional="true" p:accessTokenType="JWT"/>
>>>> > </list>
>>>> > </property>
>>>> > </bean>
>>>> > </util:list>
>>>> >
>>>> > BR,
>>>> > Henri.
>>>>
>>>>
>>>> On 12.06.25 08:21, Max Nuding wrote:
>>>>> Hi!
>>>>>
>>>>> We're currently testing out adding OIDC support to our Shibboleth
>>>>> IdP at version 5.1.4, and the first client we want to test is SoGo,
>>>>> our webmail interface.
>>>>>
>>>>> SoGo requests an access token and forwards that to out IMAP server
>>>>> (dovecot 2.3.21), which then uses that token to make a call to /
>>>>> idp/ profile/oauth2/introspection. This is causing a problem:
>>>>> Shibboleth IdP is complaining about invalid audiences, because the
>>>>> client that's using the access token for the introspection endpoint
>>>>> is different from the client the token was issued to.
>>>>>
>>>>> Is it possible to configure out IdP, so that it addds an additional
>>>>> client Id to the audience claim?
>>>>>
>>>>> Another option would be, to configure dovecot and SoGo with the
>>>>> same client id/secret, so that it apears to be the same client.
>>>>> This won't work, because SoGo insists on using client_secret_post
>>>>> and dovecot insits on using client_secret_basic, and the IdP
>>>>> verifies that the used method is the same as the registered one.
>>>>>
>>>>> Is it possible to make an exception for this specific client?
>>>>>
>>>>> Are there any opther options I'm missing?
>>>>>
>>>>> Thanks!
>>>>> Max
>>>>>
>>>>>
>>>>
>>>>
>>>
>>
>
>
More information about the users
mailing list