diff --git a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java index 18c78c435f..3d7e93c359 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/OIDCLoginProtocolService.java @@ -120,6 +120,16 @@ public class OIDCLoginProtocolService { return endpoint.register(); } + /** + * Forgot-Credentials endpoint + */ + @Path("forgot-credentials") + public Object forgotCredentialsPage() { + AuthorizationEndpoint endpoint = new AuthorizationEndpoint(authManager, realm, event); + ResteasyProviderFactory.getInstance().injectProperties(endpoint); + return endpoint.forgotCredentials(); + } + /** * Token endpoint */ diff --git a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java index fda09ee9a9..23c943ec3c 100755 --- a/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java +++ b/services/src/main/java/org/keycloak/protocol/oidc/endpoints/AuthorizationEndpoint.java @@ -46,7 +46,7 @@ public class AuthorizationEndpoint { public static final String CODE_AUTH_TYPE = "code"; private enum Action { - REGISTER, CODE + REGISTER, CODE, FORGOT_CREDENTIALS } @Context @@ -118,6 +118,8 @@ public class AuthorizationEndpoint { switch (action) { case REGISTER: return buildRegister(); + case FORGOT_CREDENTIALS: + return buildForgotCredential(); case CODE: return buildAuthorizationCodeAuthorizationResponse(); } @@ -145,6 +147,17 @@ public class AuthorizationEndpoint { return this; } + public AuthorizationEndpoint forgotCredentials() { + event.event(EventType.RESET_PASSWORD); + action = Action.FORGOT_CREDENTIALS; + + if (!realm.isResetPasswordAllowed()) { + throw new ErrorPageException(session, Messages.RESET_CREDENTIAL_NOT_ALLOWED); + } + + return this; + } + private void checkSsl() { if (!uriInfo.getBaseUri().getScheme().equals("https") && realm.getSslRequired().isRequired(clientConnection)) { event.error(Errors.SSL_REQUIRED); @@ -266,17 +279,7 @@ public class AuthorizationEndpoint { AuthenticationFlowModel flow = realm.getBrowserFlow(); String flowId = flow.getId(); - AuthenticationProcessor processor = new AuthenticationProcessor(); - processor.setClientSession(clientSession) - .setFlowPath(LoginActionsService.AUTHENTICATE_PATH) - .setFlowId(flowId) - .setConnection(clientConnection) - .setEventBuilder(event) - .setProtector(authManager.getProtector()) - .setRealm(realm) - .setSession(session) - .setUriInfo(uriInfo) - .setRequest(request); + AuthenticationProcessor processor = createProcessor(flowId, LoginActionsService.AUTHENTICATE_PATH); Response challenge = null; try { @@ -312,6 +315,32 @@ public class AuthorizationEndpoint { .createRegistration(); } + private Response buildForgotCredential() { + authManager.expireIdentityCookie(realm, uriInfo, clientConnection); + + AuthenticationFlowModel flow = realm.getResetCredentialsFlow(); + String flowId = flow.getId(); + + AuthenticationProcessor processor = createProcessor(flowId, LoginActionsService.RESET_CREDENTIALS_PATH); + + return processor.authenticate(); + } + + private AuthenticationProcessor createProcessor(String flowId, String flowPath) { + AuthenticationProcessor processor = new AuthenticationProcessor(); + processor.setClientSession(clientSession) + .setFlowPath(flowPath) + .setFlowId(flowId) + .setConnection(clientConnection) + .setEventBuilder(event) + .setProtector(authManager.getProtector()) + .setRealm(realm) + .setSession(session) + .setUriInfo(uriInfo) + .setRequest(request); + return processor; + } + private Response buildRedirectToIdentityProvider(String providerId, String accessCode) { logger.debug("Automatically redirect to identity provider: " + providerId); return Response.temporaryRedirect(