Override /auth, use three fields on login page

Hello!
I’m novice in keycloak. Sorry if I ask stupid question :slight_smile:
I have an existing application. In this app each user has several companies (user has one login/pass for all his companies). When user login it needs to enter three fields LOGIN/COMPANY_LOGIN/PASS to enter to the necessary company. Customer don’t want to use the second login page, like in example with secretQuestion (Server Developer Guide).

1)Is it possible to override logic to use custom login page with three fields?

I downloaded keycloak code, but cant find controller method with URI /auth. I suppose that if I read code from the beginning (/auth) I’ll understand flow.

2)Do you know class and folder where it is?

You’re on the right track.

  1. You’ll have to create a custom Authenticator like the UsernamePasswordForm (keycloak/UsernamePasswordForm.java at master · keycloak/keycloak · GitHub) that takes your three fields and validates them. The “secret question” example you cited gives you information on how you can build and deploy a custom Authenticator.

  2. You’ll also have to create a custom theme with your replacement login page that takes three fields. Probably easiest to just replace the login.ftl page (keycloak/login.ftl at master · keycloak/keycloak · GitHub). You can find more information on building and deploying themes here: Server Developer Guide

1 Like

@xgp Than’s for your answer.

I wrote maven project that has three files:

  1. class UsernameCompanyPasswordFormFactory implements AuthenticatorFactory
  2. class UsernameCompanyPasswordForm extends UsernamePasswordForm implements Authenticator
  3. org.keycloak.authentication.AuthenticatorFactory

My code: GitHub - MishaSviridenko/KeycloakTheeFieldsAuth

Then using maven comands clean/compile/install i got keycloak-authenticator-1.0-SNAPSHOT.jar
I started keycloak server locally and put .jar file into directory keycloak-12.0.4\standalone\deployments.
And got:

ERROR [org.jboss.as.controller.management-operation] (DeploymentScanner-threads - 1) WFLYCTL0013: Operation (“deploy”) failed - address: ([(“deployment” => “keycloak-authenticator-1.0-SNAPSHOT.jar”)]) - failure description: {“WFLYCTL0080: Failed services” => {“jboss.deployment.unit.“keycloak-authenticator-1.0-SNAPSHOT.jar”.POST_MODULE” => “WFLYSRV0153: Failed to process phase POST_MODULE of deployment “keycloak-authenticator-1.0-SNAPSHOT.jar”
Caused by: java.util.ServiceConfigurationError: org.keycloak.authentication.AuthenticatorFactory: Provider com.sid.keycloakauthenticator.UsernameCompanyPasswordFormFactory could not be instantiated
Caused by: java.lang.NoClassDefFoundError: Failed to link com/sid/keycloakauthenticator/UsernameCompanyPasswordForm (Module “deployment.keycloak-authenticator-1.0-SNAPSHOT.jar” from Service Module Loader): org/keycloak/authentication/authenticators/browser/UsernamePasswordForm”}}
16:57:39,625 INFO [org.jboss.as.server] (DeploymentScanner-threads - 1) WFLYSRV0010: Deployed “keycloak-authenticator-1.0-SNAPSHOT.jar” (runtime-name : “keycloak-authenticator-1.0-SNAPSHOT.jar”)
16:57:39,626 INFO [org.jboss.as.controller] (DeploymentScanner-threads - 1) WFLYCTL0183: Service status report
WFLYCTL0186: Services which failed to start: service jboss.deployment.unit.“keycloak-authenticator-1.0-SNAPSHOT.jar”.POST_MODULE: WFLYSRV0153: Failed to process phase POST_MODULE of deployment “keycloak-authenticator-1.0-SNAPSHOT.jar”

Do you know how resolve it?

1 Like
  1. I excluded ‘UsernamePasswordForm’ form ‘public class UsernameCompanyPasswordForm extends UsernamePasswordForm implements Authenticator’. So it looks like ‘public class UsernameCompanyPasswordForm implements Authenticator’.
  2. Copied to ‘UsernameCompanyPasswordForm’ all methods from ‘AbstractUsernameFormAuthenticator’ (with body). Not good but I got .jar.deployed

I added this code to login.ftl (deleted first unsafe string)

  <label for="company" class="${properties.kcLabelClass!}">Сompany</label>
  <input tabindex="7" id="company" class="${properties.kcInputClass!}" name="company"  type="text" autofocus autocomplete="off"/>
            </div>

Now I am trying to find information how to connect login.ftl to new auth logic. Someone can give a reference on documentation about it?

You now need to update your Authentication flow with your new form. See Server Administration Guide for more information. The easiest way is usually just to copy the “Browser” flow and then update it with your form.

Without knowing exactly what you’ve implemented in your UsernameCompanyPasswordForm I can’t say exactly how you cause the login.ftl to be rendered. If you didn’t change how the existing class loads the template, and you’ve selected the theme you created, you might not have to do anything to get it to render your login.ftl.

I will ask by the other way. How (where) login.ftl connects with “UsernamePasswordForm”?
As I understand it use:
public static final String PROVIDER_ID = “auth-username-password-form”;

But I can’t find where this two files connect?

I did manipulations with Authentication flow added “Copy of browser” and found overriding string in this method “getDisplayType()” at Provider list.

And I made .ftl page that looks like on the picture.

Please help me connect this picture (.ftl) to custom provider that i did!

1 Like

if you follow this line in UsernamePasswordForm you’ll eventually get to where it uses the login.ftl template.

        return forms.createLoginUsernamePassword();

Have you created a custom login theme with your login.ftl template? If you have, then you should only need to seelct your theme in the Realm Settings, and the UsernamePasswordForm you have built should automatically use your login.ftl assuming you are still calling the return forms.createLoginUsernamePassword() at the end of your challenge method. This is the way I would recommend it, as calling that does a lot of necessary setup to the template scope in order to render the .ftl properly.

If you haven’t already created and deployed a custom theme with your login.ftl file in it, there is documentation here:
https://www.keycloak.org/docs/latest/server_development/#_themes
and a template project for creating a custom theme I wrote here:

@xgp thanks for your answer!

I’m tying to make custom them. But earlier I tried to check my custom “UsernameCompanyPasswordForm” with Postman.

I added “Custom” to Bindings.

I deleted all the strings from “Custom” (As I understand POST request (http://localhost:8080/auth/realms/SpringBootKeycloak/protocol/openid-connect/token) shoud not works).
screen “1x” (I can put only one picture in the message, others below)

But i got AccessToken
screen “2x”

Is it always works with Browser Flow?
How can I check my custom Flow with postman?

P.S.:
Once again. THANKS A LOT your answers!!!

screen “1x”

screen “2x”