Hi Sébastien,
JIRA
https://issues.jboss.org/browse/KEYCLOAK-10182 created accordingly.
Regards,
Fabrice Geslin
Groupe La Poste
________________________________
De : Sebastien Blanc <sblanc(a)redhat.com>
Envoyé : mardi 30 avril 2019 10:19
À : GESLIN Fabrice
Cc : keycloak-user(a)lists.jboss.org
Objet : Re: [keycloak-user] How to dynamically trigger a custom required action in a flow
?
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@laposte.fr<mailto:fabrice.geslin-prestataire@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<mailto:sblanc@redhat.com>]
Envoyé : lundi 29 avril 2019 14:35
À : GESLIN Fabrice
<fabrice.geslin-prestataire@laposte.fr<mailto:fabrice.geslin-prestataire@laposte.fr>>
Cc : keycloak-user@lists.jboss.org<mailto:keycloak-user@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@laposte.fr<mailto:fabrice.geslin-prestataire@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@lists.jboss.org<mailto:keycloak-user@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.
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.