Email verification opens unnecessary verification page in new browser session

(Email verification is turned on)

When creating an user account in Keycloak the user receives an email to verify it’s email address. When opening the received link in a new browser session (or different browser) a verify email page is shown.

This does not apply to when the verify link is opened in the same browser session, in those cases the email is verified and the user is logged in immediately

The user has to click here to verify his email. I was wondering why this extra click is required. The user already clicked the verify link in his email to verify the email address.

We would like to skip this extra user action and immediately verify the email address. Is this possible?

2 Likes

Hi Marcel,
I had the same issue that in Incognito it will open a new window asking “confirm validity of email xyz@gmail.com” with a Proceed and Back to Application button.
I was able to change the flow using Javascript to programatically click the proceed button on landing of the intermediate page.
The file where you can achieve this is Info.ftl.

Hope this will help you.

Best
Anubhav

Thanks @Anubhav,

I’ll give it a try, althought this does not sound as a solid solution. It’s more a workaround for the problem.

Do you know if this is addressed to the developers team?

you’re most welcome!
I am not quite sure if this is addressed directly to the developers team.
I myself is waiting for a reply from them on a similar query.

Can you give me a notification if you have a reply which addresses this issue.
Links to issue tickets are also highly appreciated if known or created.

Sure I can but I doubt it will help in this issue. Anyways I can update no issues.
Meanwhile you may also want to check the authentication flows in admin console, which can be used to change the default flow for email verification.

marcel

i have the oppsoitte i got redirected to client page . and i need to add extra step did you how to solve your issue i think it may help .

thanks

For future references. My current solution is:

Added a javascript file in the theme resources

// Search for the proceed-link on the page. If it exists click it to automate the step
window.onload = function() {
    var proceedLink = document.getElementById("proceed-link");
    if (proceedLink) {
        proceedLink.click();
    }
}

Added proceed-link identifier to the info.ftl file found under login/info.ftl in the theme files

<#-- This template file follows info.ftl from the base theme, no major changes are made -->
<#import "template.ftl" as layout>
<@layout.registrationLayout displayMessage=false; section>
    <#if section = "header">
        <#if messageHeader??>
        ${messageHeader}
        <#else>
        ${message.summary}
        </#if>
    <#elseif section = "form">
    <div id="kc-info-message">
        <p class="instruction">${message.summary}<#if requiredActions??><#list requiredActions>: <b><#items as reqActionItem>${msg("requiredAction.${reqActionItem}")}<#sep>, </#items></b></#list><#else></#if></p>
        <#if skipLink??>
        <#else>
            <#if pageRedirectUri??>
                <p><a href="${pageRedirectUri}">${kcSanitize(msg("backToApplication"))?no_esc}</a></p>
            <#elseif actionUri??>
            
                <#-- Added unique identifier to the proceedWithAction link to automate the process via javascript (see javascript file) -->
                <p><a id="proceed-link" href="${actionUri}">${kcSanitize(msg("proceedWithAction"))?no_esc}</a></p>
            <#elseif client.baseUrl??>
                <p><a href="${client.baseUrl}">${kcSanitize(msg("backToApplication"))?no_esc}</a></p>
            </#if>
        </#if>
    </div>
    </#if>
</@layout.registrationLayout>

I don’t think this solution is a solid solution, but it does work quite well.

Hi Bebo130. I don’t that my current solution will help you solve your issue.
AFAIK a user is automatically logged in after email verification in the same session.

Hi @bebo130, As Marcel mentioned a session is immediately created once email verification link is clicked and thus you are redirected to the client page.
Can you share what is your exact requirement. Where do you wish to redirect the user when he/she clicks on email verification link.

Hello Marcel,
I added the first section into script.js file under login/ressources.
and also added the info.ftl but your solution seems don’t work for me, can you tell me more details?
Thank you

Did you add your script.js to the theme.properties
When your script is located at login/resources/script.js add the following to theme.properties:

scripts=script.js

I noticed that my script was not taking in consideration and i added scripts=js/script.js and it works! but, i still see the screen for a few seconds before the rediretion, do you an idea to hide it? (i am beginner on keycloak)
Thank you again

@Jean As I said earlier, this solution is a workaround and not a solid solution. It all depends on the speed of the browser rendering the page (which depends on the specs of the machine).

I encourage you to get in touch with the Keycloak development team and ask for a solid solution.

Did anyone find a different solution?

Hi Jean,
This is a workaround but works pretty well. I understand the internet could be quite slow in some scenarios. You may want to add a UI loader till the time the above script code is processed. This will help prevent the unnecessary fraction of the screen to visible to the user.

Br,
Anubhav

Hi Machr ,
You may want to check Keycloak Authentication Flow
to override this behaviour by writing your own custom flow for authentication.
Note: It might require some heavy customizations

Br,
Anubhav

1 Like

Hi,
You can implement your own provider that does a double redirection:

public class CustomVerifyEmailActionTokenHandler extends VerifyEmailActionTokenHandler {
    public Response handleToken(VerifyEmailActionToken token, ActionTokenContext<VerifyEmailActionToken> tokenContext) {
        if (tokenContext.isAuthenticationSessionFresh()) {
            AuthenticationSessionModel authSession = tokenContext.getAuthenticationSession();
            UriInfo uriInfo = tokenContext.getUriInfo();
            RealmModel realm = tokenContext.getRealm();
            KeycloakSession session = tokenContext.getSession();

            token.setCompoundOriginalAuthenticationSessionId(token.getCompoundAuthenticationSessionId());
            String nextAction = AuthenticationSessionCompoundId.fromAuthSession(tokenContext.getAuthenticationSession()).getEncodedId();
            token.setCompoundAuthenticationSessionId(nextAction);
            UriBuilder builder = Urls.actionTokenBuilder(uriInfo.getBaseUri(), token.serialize(session, realm, uriInfo), authSession.getClient().getClientId(), authSession.getTabId());
            return Response.status(302).location(builder.build(new Object[]{realm.getName()})).build();
        }

        boolean mustRedirectToClient = token.getCompoundOriginalAuthenticationSessionId() != null;
        Response response = super.handleToken(token, tokenContext);

        if (mustRedirectToClient) {
            response.close();
            String clientUrl = tokenContext.getAuthenticationSession().getClient().getBaseUrl();
            UriBuilder builder = UriBuilder.fromUri(clientUrl);
            response = Response.status(302).location(builder.build(new Object[0])).build();
        }

        return response;
    }
}
1 Like

@tontonpat could you please provide more information about this implementation? when and how can we call handleToken? it seems to be a solution but I’m struggling implemening it
thanks in advance

Hi @alina_b

You dont call it directly.
You must register your custom SPI in a file called org.keycloak.authentication.actiontoken. ActionTokenHandlerFactory located in META-INF/services/
see Server Developer Guide

Regards