MFA and OIDC RP canceling

Pierre SAGNE pierre.sagne at ac-orleans-tours.fr
Thu May 22 12:44:00 UTC 2025


Hello,

I am currently using an MFA authn flow including :

* LDAP password as a first factor

* OIDC RP as a second factor (proxying to another IdP which handles 
different methods)

It works fine but I need to handle a special case : the second IdP I 
delegate the second factor needs to implement a "cancel" button, in case 
the user can't use his second factor at the moment (forgot his phone for 
a TOTP validation for example)

And in this case, my IdP needs to react to this situation and route the 
user to another internal second factor.

My first idea was to make the second IdP return to my redirect uri with 
?error=cancel&state=xxxxx

So in my authn-events-flow.xml I define :

     <end-state id="cancel" />
and

     <global-transitions>
         <transition on="cancel" to="cancel" />
         <transition on="#{!'proceed'.equals(currentEvent.id)}" 
to="InvalidEvent" />
     </global-transitions>

And in my mfa-authn-config.xml :

         <entry key="authn/OIDCRelyingParty">
             <bean parent="shibboleth.authn.MFA.Transition">
                 <property name="nextFlowStrategyMap">
                     <map>
                         <entry key="cancel" value="authn/MyOtherFactor" />
                         <entry key="proceed" 
value-ref="my_final_strategy" />
                     </map>
                 </property>
             </bean>
         </entry>

But this doesn't work.

I get this error :

2025-05-22 14:41:49,246 - xxx.xxx.xxx.xxx - ERROR 
[net.shibboleth.idp.plugin.authn.oidc.rp.impl.ValidateAuthenticationResponseResult:78] 
- Profile Action ValidateAuthenticationResponseResult: OIDC 
Authentication Response contained an error from upstream OP 
'https://my-second-idp.example.com' : Code -> 'cancel', Description -> 
'null'

Is what I'm trying to achieve impossible to do, or am I just missing 
some steps, to make the OIDC error not fatal, besides what i configured 
in authn-events-flow.xml ?

If I can't do it this way, I thought about another way to do it, but 
which I don't really like :

The second IdP could return a success but with an additional claim which 
tells my first IdP that the user aborted.

I think it should work but I don't like the fact that the OIDC flow 
returns a success when the user just cancels and didn't actually 
authenticate. I fear it may open some exploits I don't yet thing of.


I'm using Shibboleth IdP 5.1.4, with :

* oidc commons 3.2.0

* oidc config 2.2.0

* oidc op 4.2.1

* oidc rp 2.2.0

-- 
Pierre Sagne.



More information about the users mailing list