Improve Authentication Conditional Behavior #17152
slominskir
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Why
It's often useful to authenticate users differently based on their location, role, or requested level of authorization. For example, users accessing Keycloak from the Internet (external) may be subject to two-factor authentication. Meanwhile, users accessing from the Intranet (internal) may be treated with SPNEGO. A user may wish to skip a non-interactive authenticator via a request parameter in order to switch user accounts.
How
Keycloak provides a configurable and extendable authentication
Flow: a procedure executed in response to an action such as a user sending a request to authenticate from a web browser or a request to register. The end result of a flow is eithersuccessorfailure, and there may be side effects especially in the case of registration and usually materialized asRequiredActions. A flow is organized into an ordered set of configurableExecutions: a step in the procedure that returns eithersuccessorfailureand is linked to an Authenticator.To allow fine tuning of flow behavior each execution has a "REQUIREMENT". In order to allow an Authenticator to fail without immediately stopping the flow you set
ALTERNATIVE. To stop the flow immediately if the step fails you setREQUIRED. TheALTERNATIVErequirement also means if the step is successful, stop (short circuit the flow) and return as success. TheREQUIREDrequirement on the other hand means if the step is successful continue going until the end of the flow is reached. There is also aDISABLEDrequirement type which means skip. Executions can be nested using a subflow execution. Just like a regular execution a subflow evaluates tosuccessorfailureand has a requirement type.A special requirement type of
CONDITIONAL, which can only be applied to subflows, is used to apply conditions. The subflow is effectively DISABLED if the conditions fail and is effectively REQUIRED if the conditions succeed. The conditional subflow otherwise acts like a regular subflow in that it can contain traditional Authenticators to determine if the subflow was asuccessorfailure. The location of Conditions with respect to traditional Authenticators in the subflow may matter. It also appearsALTERNATIVEexecutions behave differently in conditional subflows, if they are interactive, otherwise they behave the same. If interactive then at the beginning of the subflow the user should be prompted to choose whichALTERNATIVEAuthenticator to use.There are currently two approaches to conditional behavior:
Conditional AuthenticatorsandConditional Flows.Conditional Authenticator
Not to be confused with the ConditionalAuthenticator class, which only evaluates a condition and makes up a Conditional Flow, a Conditional Authenticator here means an Authenticator that evaluates one or more conditions before performing authentication. With this approach each authenticator is responsible for handling conditional execution. On the plus side this is easy to understand. The issue here is the lack of re-use, as often the conditions are useful across multiple different authenticators and would need to be duplicated. Examples:
Conditional Flow
As part of the effort to support Levels of Authentication, the concept of a Conditional Flow was created. The issue here is that conditions are not applied to executions, but instead a special Conditional Subflow is used to house conditions confusingly named
ConditionalAuthenticatorsand the logic is complicated and unintuitive. Even with all the complexity some things like indicating that any two out of the three authenticators must succeed appears to be unsupported.There doesn't appear to be a way to indicate that the conditional subflow is
ALTERNATIVE. For example I think you would be required todouble nest:Improvements
Maybe either:
CONDITIONAL_ALTERNATIVErequirement type for subflows that has effect typeALTERNATIVE. Rename existingCONDITIONALtoCONDITIONAL_REQUIREDCONDITIONALrequirement type and allow any other requirement type on a Conditional SubflowCONDITIONALrequirement type ANDConditional Flowand instead add a list of Condition objects as an attribute to an AuthenticatorAll reactions