If you believe their is a inconsistency please open a JIRA, tbh I don't
know that much about the implementation details of this part.
You probably have but worth asking : have you set the priority of your
custom required action ? I can see that "Update password" has prio 30 , so
your custom action should be >30 (0 is the highest priority) if you want it
to be run after.
And regarding sort by names and priority, if I look at the implementation
of the comparator it looks like it first sort by prio and after that by
name (if they have the same prio).
On Tue, Apr 30, 2019 at 9:43 AM GESLIN Fabrice <
fabrice.geslin-prestataire(a)laposte.fr> wrote:
Hi Sébastien,
We’ve finally found the addRequiredAction() function with the String
parameter and it works.
But we felt into a new issue due to the fact that the required actions are
sometime handled sorted and sometime not sorted.
For instance, at the end of the authentication flow processing, when the
required actions are processed, they are treated in an arbitrary order that
doesn’t even correspond to the order in which they were added. In Keycloak
release 4.8.3.FINAL, The call stack leads to line 893 of
org.keycloak.services.managers.AuthenticationManager that is:
public static String nextRequiredAction(final KeycloakSession session,
final AuthenticationSessionModel authSession,
final ClientConnection
clientConnection,
final HttpRequest request,
final UriInfo uriInfo, final EventBuilder event) {
final RealmModel realm = authSession.getRealm();
final UserModel user = authSession.getAuthenticatedUser();
final ClientModel client = authSession.getClient();
evaluateRequiredActionTriggers(session, authSession,
clientConnection, request, uriInfo, event, realm, user);
if (!user.getRequiredActions().isEmpty()) {
return user.getRequiredActions().iterator().next();
}
if (!authSession.getRequiredActions().isEmpty()) {
return authSession.getRequiredActions().iterator().next();
}
This causes the user to be redirected to the URI of the required action
that has been arbitrarily selected. *But* when the browser GET the
corresponding URI, the call stack reaches line 1045 of
org.keycloak.services.managers.AuthenticationManager where the required
actions are sorted according to their priorities or their names (?!?):
protected static Response executionActions(KeycloakSession session,
AuthenticationSessionModel authSession,
HttpRequest request, EventBuilder event,
RealmModel realm, UserModel user,
Set<String> requiredActions) {
List<RequiredActionProviderModel> sortedRequiredActions =
sortRequiredActionsByPriority(realm, requiredActions);
for (RequiredActionProviderModel model : sortedRequiredActions) {
RequiredActionFactory factory =
(RequiredActionFactory)session.getKeycloakSessionFactory().getProviderFactory(RequiredActionProvider.class,
model.getProviderId());
if (factory == null) {
throw new RuntimeException("Unable to find factory for Required
Action: " + model.getProviderId() + " did you forget to declare it in a
META-INF/services file?");
}
RequiredActionContextResult context = new
RequiredActionContextResult(authSession, realm, event, session, request, user, factory);
RequiredActionProvider actionProvider = null;
try {
actionProvider = createRequiredAction(context);
} catch (AuthenticationFlowException e) {
if (e.getResponse() != null) {
return e.getResponse();
}
throw e;
}
actionProvider.requiredActionChallenge(context);
The side effect of this inconsistency is that in our case, where we’ve
added a custom required action after the UPDATE_PASSWORD required action to
the reset credential flow, the user is first redirected to the URI of our
custom action (which is not what we expected) AND the form that is
challenged to the user once redirected is the one from the UPDATE_PASSWORD
action !
The question is how can we have the required actions that are added to a
flow be processed according to the order in which they are added ?
Regards,
Fabrice Geslin
Groupe La Poste
*De :* Sebastien Blanc [mailto:sblanc@redhat.com]
*Envoyé :* lundi 29 avril 2019 14:35
*À :* GESLIN Fabrice <fabrice.geslin-prestataire(a)laposte.fr>
*Cc :* keycloak-user(a)lists.jboss.org
*Objet :* Re: [keycloak-user] How to dynamically trigger a custom
required action in a flow ?
Hi,
When you says it does not accept it, you have an exception at runtime ?
Because you have addRequiredAction(String string)
On Mon, Apr 29, 2019 at 12:13 PM GESLIN Fabrice <
fabrice.geslin-prestataire(a)laposte.fr> wrote:
Hi,
We're trying to trigger a custom required action as part of the reset
credential.
For this we plan to mimic the implementation of the authenticate method of
the org.keycloak.authentication.authenticators.resetcred.ResetPassword.java
:
@Override
public void authenticate(AuthenticationFlowContext context) {
if (context.getExecution().isRequired() ||
(context.getExecution().isOptional() &&
configuredFor(context))) {
context.getAuthenticationSession().addRequiredAction(UserModel.RequiredAction.UPDATE_PASSWORD);
}
context.success();
}
But the question is what value should we pass to the addRequiredAction() ?
This method seems to only accept the predefined required actions mapped to
the values from the UserModel.RequiredAction enum.
Any help is welcome .
Fabrice Geslin
Groupe La Poste
Post-scriptum La Poste
Ce message est confidentiel. Sous reserve de tout accord conclu par
ecrit entre vous et La Poste, son contenu ne represente en aucun cas un
engagement de la part de La Poste. Toute publication, utilisation ou
diffusion, meme partielle, doit etre autorisee prealablement. Si vous
n'etes pas destinataire de ce message, merci d'en avertir immediatement
l'expediteur.
_______________________________________________
keycloak-user mailing list
keycloak-user(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/keycloak-user
Post-scriptum La Poste
Ce message est confidentiel. Sous reserve de tout accord conclu par
ecrit entre vous et La Poste, son contenu ne represente en aucun cas un
engagement de la part de La Poste. Toute publication, utilisation ou
diffusion, meme partielle, doit etre autorisee prealablement. Si vous
n'etes pas destinataire de ce message, merci d'en avertir immediatement
l'expediteur.