diff --git a/docs/documentation/server_admin/images/authentication-step-up-flow.png b/docs/documentation/server_admin/images/authentication-step-up-flow.png index a27c96884e..93f9380970 100644 Binary files a/docs/documentation/server_admin/images/authentication-step-up-flow.png and b/docs/documentation/server_admin/images/authentication-step-up-flow.png differ diff --git a/docs/documentation/server_admin/topics/authentication/flows.adoc b/docs/documentation/server_admin/topics/authentication/flows.adoc index 6930ab979c..2494f80958 100644 --- a/docs/documentation/server_admin/topics/authentication/flows.adoc +++ b/docs/documentation/server_admin/topics/authentication/flows.adoc @@ -381,6 +381,11 @@ condition found in the authentication flow, such as the Username/Password in the and that level expired, the user is not required to re-authenticate, but `acr` in the token will have the value 0. This result is considered as authentication based solely on `long-lived browser cookie` as mentioned in the section 2 of OIDC Core 1.0 specification. +NOTE: During the first authentication of the user, the first configured subflow with the *Conditional - Level Of Authentication* is always executed (regardless of the requested level) as +the user does not yet have any level. Therefore, we recommend that the first level subflow contains the minimal required authenticators for user authentication. In addition, ensure that the subflows with different values of *Conditional - Level Of Authentication* are ordered starting with the lowest as shown +in the example above. For example, if you configure a subflow with level 2 and then add another subflow with level 1, the level 2 subflow will be always asked during the first authentication, which may +not be the desired behavior. + NOTE: A conflict situation may arise when an admin specifies several flows, sets different LoA levels to each, and assigns the flows to different clients. However, the rule is always the same: if a user has a certain level, it needs only have that level to connect to a client. It's up to the admin to make sure that the LoA is coherent. *Example scenario* diff --git a/services/src/main/java/org/keycloak/authentication/DefaultAuthenticationFlow.java b/services/src/main/java/org/keycloak/authentication/DefaultAuthenticationFlow.java index 31db8a72a1..20ff2d21ca 100755 --- a/services/src/main/java/org/keycloak/authentication/DefaultAuthenticationFlow.java +++ b/services/src/main/java/org/keycloak/authentication/DefaultAuthenticationFlow.java @@ -416,7 +416,7 @@ public class DefaultAuthenticationFlow implements AuthenticationFlow { if (authenticator.requiresUser()) { if (authUser == null) { - throw new AuthenticationFlowException("authenticator: " + factory.getId(), AuthenticationFlowError.UNKNOWN_USER); + throw new AuthenticationFlowException("authenticator '" + factory.getId() + "' requires user to be set in the authentication context by previous authenticators, but user is not set yet", AuthenticationFlowError.UNKNOWN_USER); } if (!authenticator.configuredFor(processor.getSession(), processor.getRealm(), authUser)) { if (factory.isUserSetupAllowed() && model.isRequired() && authenticator.areRequiredActionsEnabled(processor.getSession(), processor.getRealm())) {