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