Keycloak default login form with additional user attribute validation. Example:
To use this authenticator, it should be bundled together with Keycloak, here are two ways how to do that:
To deploy custom Keycloak extension it needs to be placed in {$KEYCLOAK_PATH}/standalone/deployments/
.
Latest authenticator jar file can be downloaded from
Github Releases page or
Maven Central Repository.
If you want to use this authenticator in cloud environment, here is ready init container.
Jar file is placed in /opt/jboss/keycloak/standalone/deployments
, so same location as target one.
According to official Keycloak example,
Helm chart could look like following:
extraInitContainers: |
- name: attribute-authenticator-provider
image: kilmajster/keycloak-username-password-attribute-authenticator:latest
imagePullPolicy: IfNotPresent
command:
- sh
args:
- -c
- |
echo "Copying attribute authenticator..."
cp -R /opt/jboss/keycloak/standalone/deployments/*.jar /attribute-authenticator
volumeMounts:
- name: attribute-authenticator
mountPath: /attribute-authenticator
extraVolumeMounts: |
- name: attribute-authenticator
mountPath: /opt/jboss/keycloak/standalone/deployments
extraVolumes: |
- name: attribute-authenticator
emptyDir: {}
Following steps shows how to create authentication flow that uses authenticator with user attribute validation.
- In Keycloak admin console, go to Authentication section, select authentication type of Browser and click Copy.
- Set name for new authentication flow eg.
Browser with user attribute
and click Ok. - In newly created authentication flow remove Username Password Form execution.
- On Browser With User Attribute Forms level, click Actions > Add execution and select provider of type Username Password Attribute Form, then save.
- Then move Username Password Attribute Form on a previous position of Username Password Form, so in the end authentication flow should look like following:
- On Username Password Attribute Form level, click Actions > Config.
- Attribute used to validate login form.
-
If enabled, label for login form will be generated based on attribute name, so attribute with name:
foot_size
will be labeled as Foot sizeREALLY_custom.user-Attribute
will be translated to Really custom user attribute, etc.
By default, set to
true
. IfUser attribute form label
is configured, label is taken form configuration and generation is skipped. -
If enabled, user is not stored in session context in case username and password were valid but user attribute was not.
-
Message which will be displayed as user attribute input label. If value is a valid message key, then proper translation will be used.
-
Message which will be displayed as user attribute validation error. If value is a valid message key, then proper translation will be used.
Configuration could be also provided as environment variables. If such config exists, then configuration from Keycloak admin UI is ignored. Available properties:
- LOGIN_FORM_GENERATE_LABEL
- LOGIN_FORM_ATTRIBUTE_LABEL
- LOGIN_FORM_ERROR_MESSAGE
- CLEAR_USER_ON_ATTRIBUTE_VALIDATION_FAIL
Theme configuration is handled in clients section, in following example Keycloak default account-console
client will be used.
In Keycloak admin panel, go to Clients and select client you want to authenticate with user attribute form. As Login Theme set base-with-attribute
and in Authentication Flow Overrides for Browser Flow, choose authentication that contain previously configured login form,
so for example Browser with user attribute
, like below:
If you have your own theme, then in .your-theme/login/login.ftl
add following below <div>
responsible for a password stuff or anywhere you want.
How it was done with Keycloak base theme, you can check here.
...
<div class="${properties.kcFormGroupClass!}">
<label for="password" class="${properties.kcLabelClass!}">${msg("password")}</label>
<input tabindex="2" id="password" class="${properties.kcInputClass!}" name="password" type="password" autocomplete="off"
aria-invalid="<#if messagesPerField.existsError('username','password')>true</#if>"
/>
</div>
<!-- keycloak-user-attribute-authenticator custom code block start -->
<div class="${properties.kcFormGroupClass!}">
<label for="login_form_user_attribute" class="${properties.kcLabelClass!}">
<#if login_form_attribute_label??>
${msg(login_form_attribute_label)}
<#else>
${msg("login_form_attribute_label_default")}
</#if>
</label>
<input tabindex="3" id="login_form_user_attribute" class="${properties.kcInputClass!}"
name="login_form_user_attribute" type="text" autocomplete="off"
aria-invalid="<#if messagesPerField.existsError('login_form_user_attribute')>true</#if>"
/>
</div>
<!-- keycloak-user-attribute-authenticator custom code block end -->
<div class="${properties.kcFormGroupClass!} ${properties.kcFormSettingClass!}">
...
$ mvn package
After building a project, do following to start Keycloak with bundled authenticator jar and dummy configuration (dev-realm.json
).
$ docker-compose up --build
Open browser and go to http://localhost:8081/auth/realms/dev-realm/account
use Username or email = test
, Password = test
and Foot size = 46
to login.
.github/debug-in-docker.run.xml
$ docker-compose build
$ mvn test -P automation-tests
$ mvn test -P automation-tests -D selenide.headless=true