Enforce 2FA and still reusing Cookie/SSO

Hi,

I have a bunch of OIDC-clients in a realm and the goal is to require users to login with 2-factor (TOTP or WebAuthN) for apps.

But the users also need to have access to the Account Console to be able to setup 2FA in the first place, so the account console must use Conditional 2FA (Condition - User Configured in flow)

So:

  • Account Manager should only enforce 2FA if user has it configured
  • All other clients should have 2FA enforced and deny user access until they have registered a 2FA in Acccount console.

I can solve this by creating a separate authentication flow for the account manager client which contains the Condition - User Configured and allow the user to login to account console without 2FA set up.

The problem with this is the “Cookie”-step in the both the (browser) flow for Account Console and the rest of OIDC-clients are “shared” so if a user logs in via one flow it is already logged in for the other flow as well (Single sign on, which is nice).

A user (without 2FA setup up) can bypass 2fa auth by:

  • Logging into Account Console (without 2FA)
  • In the same browser go to the url of one of the other clients - The user is already logged into Keycloak (Single Sign On) and the “Cookie” is shared among clients, so the user is authorized/sent back to the client without entering credentials or 2FA.

I can remove “Cookie”-step in the flow for all 2FA clients, but I would like users not to having to enter credentials more than necessary when switching between clients.

I tried experimententing with some Level-up auth flows, but I can’t figure out how/if it is at all possible to look at “Cookie”-step further down the flow based on the “Level”.

Is it possible to enforce 2FA this way? Or should it be enforced in the clients (sending acr_values and validating afterwards) instead or how is the correct way to achieve this?

Here’s just my point of view: Generally speaking, I prefer to delegate the enforcement to the application. This is why we have OIDC specifications that allow specifying the acr_values in the authentication request (or you can set a default flow for the client). The resulting acr claim in the id_token can then be used by the application for enforcement. The application can also force login by using the prompt=login parameter.

I prefer to keep Keycloak as simple as possible because authentication requirements often change, and by delegating the enforcement to the application, we maintain flexibility. The application can apply enforcement when needed, allowing for more granular control over the authentication process.

1 Like

I guess that makes sense - I will probably have to fight a few different applications and make them behave, but if that is the correct way to do it, I’ll gladly take the fight :slight_smile:

Thank you very much