2

We have a PHP/MySQL based User Management System and are integrating it with Keycloak version 16 where we will store users credentials.

Our application does not allow users to self register. We create user accounts on the system. When we do this we do NOT specify a password because we want users to set up their own password.

The current system sends 2 separate emails in 2 different circumstances regarding passwords:

  1. If it's a completely new user who does NOT have an existing password, we send them a link to set up a password.

  2. If it's an existing user who already has a password, the system allows them to reset it, e.g. if they forget their password and can't login.

Keycloak seems to cater for scenario (2) because the login forms have a forgotten password link which opens a form where the user can enter their email address and receive a link which lets them do (2).

Unfortunately it doesn't deal with scenario (1) very well and that's where our problem starts. This has been asked a while ago Send password forgotten mail but it seems that Keycloak didn't support this very well in 2020 and perhaps still doesn't now.

Our "workaround" to this was that we added custom email templates and a custom page (reference: Themes on https://www.keycloak.org/docs/latest/server_development/#emails) which includes wording that caters for both scenarios, e.g. "set your password" rather than "reset your (existing) password". The result of this is that our email and form now reads appropriately for both scenarios (1) and (2).

The problem

We want to be able to send a link to the user that allows them to set their initial password to cover scenario (1).

We know that this page exists because on the login page for Keycloak there is a link to the forgotten password form that handles scenario (2). However, the form requires the user to enter their email address and submit the form. The user then receives an email from Keycloak which contains a URL to the page where they can do this. The URL has the following format:

https://example.com/auth/realms/foo/login-actions/action-token?key=...

The key= contains a ~945 character token. Going to the URL above redirects to the form where the user can reset their password. This next URL does not contain a token but a cookie has been set in the browser - by the previous URL - which makes it functional:

https://example.com/auth/realms/foo/login-actions/required-action?execution=UPDATE_PASSWORD

We can't send either of these URLs to the user because the first one (containing key=) has no API method for us to find out what it is - it's only possible to generate this by going through the "forgotten password" step during login, in the browser.

The second URL (/login-actions/required-action...) won't work either because it relies on the previous URL (containing key=) setting the cookie in the browser. If you try and go to this second URL directly (i.e. bypassing the first URL) it will error.

So neither of these URLs will work because we can't find what the first one is programmatically, and we can't use the second one without knowing the first one.

I found https://lists.jboss.org/pipermail/keycloak-user/2018-October/015910.html and the suggestion is using the Keycloak API to trigger a password reset email. This works - sending an HTTP PUT request containing 'UPDATE_PASSWORD' along with the relevant user ID sends the user an email. The request endpoint has the format PUT /{realm}/users/{id}/execute-actions-email which is documented on the link above.

Up to here all is fine - the user gets an email. However, this email does NOT contain a link that goes directly to the "reset password" page! Instead it sends them an email containing the following text:

Your administrator has just requested that you update your account by performing the following action(s): Update Password. Click on the link below to start this process.

Link to account update

When the user clicks "Link to account update" it then shows them a web page like this:

enter image description here

It is only when they click on the link on this page (the one that says "click here to proceed" on the screenshot) that they arrive at the form where they can reset their password.

This is a really poor user experience because the user gets sent a (badly worded) email with a link to... a page with another link! It should just take them to the password reset page directly. What's more frustrating is the fact that Keycloak is clearly capable of generating/sending the exact email we'd like in this scenario: the one which gets sent when a user manually does a password reset via their browser.

So the problem seems that Keycloak's API doesn't support this incredibly important and common use-case of a user being able to set an initial password, in a user-friendly manner.

halfer
  • 19,824
  • 17
  • 99
  • 186
Andy
  • 5,142
  • 11
  • 58
  • 131
  • Any solution for this poor user experience? – S Kumar May 02 '23 at 16:57
  • @SKumar: "chase comments" don't really work well on Stack Overflow, especially where the question topic is rather niche. This post seems to be a feature request anyway, so you may be best contacting the software author and asking them about it. – halfer May 02 '23 at 19:25
  • @SKumar no. One solution - given this is how Keycloak works - is to implement your own pages/emails and then use Keycloak's API to update the relevant data. As an e.g. we have a platform integrated with Keycloak that has web pages where a user can update their profile (including password). It's possible to send that via Keycloak's API and update Keycloak but it's a lot of work as you need to map users in your application/DB with a Keycloak user ID. But we've managed to do this, and it is possible. @ halfer it wasn't a feature request really - it was to find out if we'd overlooked anything. – Andy May 03 '23 at 13:59

1 Answers1

0

I am adding the js script in the template to automatically click "click here to proceed". It's ugly but at least the user doesn't see the page