-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Correctly moves to the next required action #31060
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@graziang There are failures in FIPS that (I think) are related as the stacktrace seems to show the modified method. My feeling is that you need to separate the ignore in a different else if. But not tested. 😄
| return context.getChallenge(); | ||
| } | ||
| else if (context.getStatus() == RequiredActionContext.Status.SUCCESS) { | ||
| else if (context.getStatus() == RequiredActionContext.Status.SUCCESS || context.getStatus() == RequiredActionContext.Status.IGNORE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't be move the ignore in a different if and do the next only in that situation? Something like:
diff --git a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
index 10fd0e7523..847341149f 100755
--- a/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
+++ b/services/src/main/java/org/keycloak/services/managers/AuthenticationManager.java
@@ -1279,6 +1279,10 @@ public class AuthenticationManager {
authSession.setAuthNote(AuthenticationProcessor.CURRENT_AUTHENTICATION_EXECUTION, model.getProviderId());
return context.getChallenge();
}
+ else if (context.getStatus() == RequiredActionContext.Status.IGNORE) {
+ authSession.getAuthenticatedUser().removeRequiredAction(factory.getId());
+ authSession.removeRequiredAction(factory.getId());
+ return nextActionAfterAuthentication(session, authSession, session.getContext().getConnection(), request, session.getContext().getUri(), event);
+ }
else if (context.getStatus() == RequiredActionContext.Status.SUCCESS) {
event.clone().event(EventType.CUSTOM_REQUIRED_ACTION).detail(Details.CUSTOM_REQUIRED_ACTION, factory.getId()).success();
// don't have to perform the same action twice, so remove it from both the user and session required actionsThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case where a user has already verified their email, and for some reason you add the VERIFY_EMAIL and webauthn-register (or any other action with low priority) action to the user, the webauthn-register action would be skipped because of context.success() here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah! Ok, the failure in fips was that the verify email was re-added all the time. OK. Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe then if ignored the event should not be added. I don't think we shoukd report an event if verify_email is ignored. The next line. WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, ok about not reporting the event.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking if it would be better to let it fail in any case if the email is null instead of ignoring it, because otherwise if you manually add the required action to the user the behavior between the the two flows would still be different
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks that is general fix for all required which call context.success(); from requiredActionChallenge(final RequiredActionContext context)
context.success(); from requiredActionChallenge(final RequiredActionContext context)
@rmartinc Is it ok for you, are you going to approve this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would do the same in both situations. The condition for evaluateTriggers is context.getRealm().isVerifyEmail() && !context.getUser().isEmailVerified() so I would do the same for requiredActionChallenge. The action should not pass if the email is blank but the realm is configured to verify email. I think it's the less disruptive decision. But, as you say, we can also decide to always fail if the action is assigned and the email is blank (but maybe you need to change tests).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@radoslawsyga We need to take a decision about what to do with the verify email action. There is a test that is failing right now. It will be approved and merged when ready.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated the PR to always fail if the action is assigned and the email is blank. Tests look OK
a5e6911 to
261ae28
Compare
Closes keycloak#31014 Signed-off-by: Giuseppe Graziano <[email protected]>
rmartinc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @graziang! LGTM! It's a bit of a change but it makes sense in IMHO. Besides actions update profile and verify email can be added to a user to force the email update and the verify.
mposolda
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@graziang @rmartinc Thanks for the PR and the review.
I have some doubts as this is quite backwards incompatible change. I've tried to test the scenario like this:
- New realm
testis created - Admin switches
Verify Emailto ON for that realm - Admin creates user
johnwith some password and without email (This is possible asemailis not required user-profile attribute for administrators by default. It is required just for the regular users) - Attempt to login as
john. Now I see the error message that email is not set. Moreover user does not have any chance to set his email, so he would be completely stuck at this moment.
I would expect the behaviour for that scenario that after login with username/password user is first required to update his profile (because of Verify profile required action, which was triggered due the email attribute missing) and then email verification required as next step. I've checked that was the behaviour in Keycloak 24.
Do we need to keep the changes in the behaviour in the VerifyEmail class? If we need (which I am not sure), how to make sure that behaviour would be correct (ideally same as in Keycloak 24)?
Maybe one option is that we can make sure that Verify Profile action is before Verify Email action. This will require changing the behaviour for new realms, but also migration as it will need to be updated for existing realms migrated from previous versions (which can be complicated as I am not sure if Verify Profile action is set and enabled by default for the deployments like Keycloak 22 where user-profile was not yet enabled by default). Do we have any better option then tricky migration changes?
|
The change in verify email was needed, because if not there was a loop (the evaluate triggers added the action but it was ignored later). My feeling is that the different order in the verify profile and verify email is triggered by the other PR, now the order is exactly specified by the priority in the actions. I have done some tests with 24.0.5 (I had not done this before):
So maybe we should do the following to emulate better the previous behavior (which it's not perfect either):
WDYT? If you don't like that the only way (I have seen) is modifying priorities in the upgrade for the actions. |
|
@rmartinc +1 to make sure that behaviour is the same as in Keycloak 24.0.5 for both cases when
Can be also good to make automated tests for those scenarios IMO (if not already present). From the options you proposed, any of them is OK IMO as long as we have the behaviour as in Keycloak 24. Both are better than changing the order of required actions IMO (due the migration and the possible issues related to that...). Maybe another option is to not do any changes in the |
Closes keycloak#31014 Signed-off-by: Giuseppe Graziano <[email protected]>
|
@graziang I'm working on this, forget about it for noe! 😄 |
|
@rmartin @mposolda thanks for the review and all the suggestions! IMO the Verify Email action should not be ignored if the email is not set and also not verified when Verify Email is enabled on the realm. Probably the best solution would be that after login with username/password, the user is first required to update their profile (because of the Verify Profile required action, which was triggered due to the missing email attribute) and then verify email required as the next step. This is the behavior with Keycloak 24.0.5. On the other hand, I agree with Ricardo's proposed solution that it is better than changing the order of required actions because of the migration and the possible issues. @rmartinc feel free to continue the work |
|
Superseded by #31358. |
If a required action was successful or ignored in
RequiredActionProvider.requiredActionChallenge()(like the VERIFY_EMAIL action on an already verified email), the following actions were skipped.I just have a doubt if the current behavior of ignoring the action in case of a null email in the VERIFY_EMAIL action is correct, or if the user should be stopped with a message indicating that the email is not present and therefore not verified.
Closes #31014