Merge pull request #3435 from stianst/KEYCLOAK-3331

KEYCLOAK-3331 Reset password leads to 400 bad request when link is op…
This commit is contained in:
Stian Thorgersen 2016-10-28 06:40:48 +02:00 committed by GitHub
commit e958bd254a
3 changed files with 51 additions and 0 deletions

View file

@ -41,6 +41,7 @@ import org.keycloak.models.utils.HmacOTP;
import org.keycloak.provider.ProviderConfigProperty; import org.keycloak.provider.ProviderConfigProperty;
import org.keycloak.services.ServicesLogger; import org.keycloak.services.ServicesLogger;
import org.keycloak.services.messages.Messages; import org.keycloak.services.messages.Messages;
import org.keycloak.services.resources.LoginActionsService;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriBuilder;
@ -60,6 +61,8 @@ public class ResetCredentialEmail implements Authenticator, AuthenticatorFactory
@Override @Override
public void authenticate(AuthenticationFlowContext context) { public void authenticate(AuthenticationFlowContext context) {
LoginActionsService.createActionCookie(context.getRealm(), context.getUriInfo(), context.getConnection(), context.getClientSession().getId());
UserModel user = context.getUser(); UserModel user = context.getUser();
String username = context.getClientSession().getNote(AbstractUsernameFormAuthenticator.ATTEMPTED_USERNAME); String username = context.getClientSession().getNote(AbstractUsernameFormAuthenticator.ATTEMPTED_USERNAME);

View file

@ -20,6 +20,8 @@ package org.keycloak.authentication.authenticators.resetcred;
import org.keycloak.authentication.AuthenticationFlowContext; import org.keycloak.authentication.AuthenticationFlowContext;
import org.keycloak.models.UserCredentialModel; import org.keycloak.models.UserCredentialModel;
import org.keycloak.models.UserModel; import org.keycloak.models.UserModel;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.resources.LoginActionsService;
/** /**
* @author <a href="mailto:bill@burkecentral.com">Bill Burke</a> * @author <a href="mailto:bill@burkecentral.com">Bill Burke</a>
@ -31,6 +33,11 @@ public class ResetPassword extends AbstractSetRequiredActionAuthenticator {
@Override @Override
public void authenticate(AuthenticationFlowContext context) { public void authenticate(AuthenticationFlowContext context) {
String actionCookie = LoginActionsService.getActionCookie(context.getSession().getContext().getRequestHeaders(), context.getRealm(), context.getUriInfo(), context.getConnection());
if (actionCookie == null || !actionCookie.equals(context.getClientSession().getId())) {
context.getClientSession().setNote(AuthenticationManager.END_AFTER_REQUIRED_ACTIONS, "true");
}
if (context.getExecution().isRequired() || if (context.getExecution().isRequired() ||
(context.getExecution().isOptional() && (context.getExecution().isOptional() &&
configuredFor(context))) { configuredFor(context))) {

View file

@ -606,6 +606,47 @@ public class ResetPasswordTest extends TestRealmKeycloakTest {
} }
} }
@Test
public void resetPasswordLinkOpenedInNewBrowser() throws IOException, MessagingException {
String username = "login-test";
String resetUri = oauth.AUTH_SERVER_ROOT + "/realms/test/login-actions/reset-credentials";
driver.navigate().to(resetUri);
resetPasswordPage.assertCurrent();
resetPasswordPage.changePassword(username);
loginPage.assertCurrent();
assertEquals("You should receive an email shortly with further instructions.", loginPage.getSuccessMessage());
events.expectRequiredAction(EventType.SEND_RESET_PASSWORD)
.user(userId)
.detail(Details.REDIRECT_URI, oauth.AUTH_SERVER_ROOT + "/realms/test/account/")
.client("account")
.detail(Details.USERNAME, username)
.detail(Details.EMAIL, "login@test.com")
.session((String)null)
.assertEvent();
assertEquals(1, greenMail.getReceivedMessages().length);
MimeMessage message = greenMail.getReceivedMessages()[0];
String changePasswordUrl = getPasswordResetEmailLink(message);
driver.manage().deleteAllCookies();
driver.navigate().to(changePasswordUrl.trim());
System.out.println(driver.getPageSource());
updatePasswordPage.assertCurrent();
updatePasswordPage.changePassword("resetPassword", "resetPassword");
assertTrue(infoPage.isCurrent());
assertEquals("Your account has been updated.", infoPage.getInfo());
}
public static String getPasswordResetEmailLink(MimeMessage message) throws IOException, MessagingException { public static String getPasswordResetEmailLink(MimeMessage message) throws IOException, MessagingException {
Multipart multipart = (Multipart) message.getContent(); Multipart multipart = (Multipart) message.getContent();