Skip to content

Latest commit

 

History

History
132 lines (115 loc) · 7.62 KB

File metadata and controls

132 lines (115 loc) · 7.62 KB

Keycloak username password attribute authenticator

main GitHub

Supported Keycloak versions

compatible with Keycloak - 16.1.1 keycloak-username-password-attribute-authenticator:0.3.0
compatible with Keycloak - 24.0.1 keycloak-username-password-attribute-authenticator:1.0.1

Description

Keycloak default login form with additional user attribute validation. Example:

Login form preview     Form error message preview

Usage

To use this authenticator, it should be bundled together with Keycloak, here's how do that:

Deploying jar

Build your Keycloak image like below:

FROM quay.io/keycloak/keycloak:24.0.1

RUN curl -s -L -o /opt/keycloak/providers/keycloak-username-password-attribute-authenticator-1.0.1.jar https://github.com/kilmajster/keycloak-username-password-attribute-authenticator/releases/download/1.0.1/keycloak-username-password-attribute-authenticator-1.0.1.jar
RUN /opt/keycloak/bin/kc.sh build

ENTRYPOINT ["/opt/keycloak/bin/kc.sh", "start"]

Authentication configuration

Following steps shows how to create authentication flow that uses authenticator with user attribute validation.

  1. In Keycloak admin console, go to Authentication section, select authentication type of Browser and click Duplicate action.
  2. Set name for new authentication flow eg. Browser with user attribute and click Ok.
  3. In newly created authentication flow remove Username Password Form execution.
  4. On Browser With User Attribute Forms level, click Actions > Add execution and select provider of type Username Password Attribute Form, set Requirement to required, then save.
  5. Then move Username Password Attribute Form on a previous position of Username Password Form, so in the end authentication flow should look like following:

    New authentication execution

  6. On Username Password Attribute Form level, click Actions > Settings.

    Authenticator configuration

Minimal configuration

  • User attribute
    Attribute used to validate login form.

Advanced configuration

  • Generate label (default true)
    If enabled, label for login form will be generated based on attribute name, so attribute with name:
    • favorite_number will be labeled as Favorite number
    • REALLY_custom.user-Attribute will be translated to Really custom user attribute, etc. By default, set to true. If User attribute form label is configured, label is taken form configuration and generation is skipped.
  • User attribute form label
    Message which will be displayed as user attribute input label. If value is a valid message key, then proper translation will be used.
  • Invalid user attribute error message
    Message which will be displayed as user attribute validation error. If value is a valid message key, then proper translation will be used.

Theme configuration

Theme configuration is handled in clients section, in following example Keycloak default account-console client will be used.

Using bundled default Keycloak theme

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

Example client configuration

Then in advance section > _Authentication Flow Overrides_ for _Browser Flow_, choose authentication that contain previously configured login form, so for example `Browser with user attribute`.

Example client configuration

Extending own theme

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.

    <#if usernameHidden?? && messagesPerField.existsError('username','password')>
        <span id="input-error" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
                ${kcSanitize(messagesPerField.getFirstError('username','password'))?no_esc}
        </span>
    </#if>

</div>

<!-- attribute input block start-->
<div class="${properties.kcFormGroupClass!}">
    <label for="user_attribute" class="${properties.kcLabelClass!}"><#if user_attribute_label??>${msg(user_attribute_label)}<#else>${msg("defaultUserAttributeLabel")}</#if></label>
    <div class="${properties.kcInputGroup!}">
        <input tabindex="3" id="user_attribute" class="${properties.kcInputClass!}" name="user_attribute" type="password" autocomplete="current-user-attribute"
            aria-invalid="<#if messagesPerField.existsError('username','password','user_attribute')>true</#if>"
        />
        <button class="${properties.kcFormPasswordVisibilityButtonClass!}" type="button" aria-label="${msg("showUserAttribute")}"
            aria-controls="user_attribute" data-password-toggle tabindex="4"
            data-icon-show="${properties.kcFormPasswordVisibilityIconShow!}" data-icon-hide="${properties.kcFormPasswordVisibilityIconHide!}"
            data-label-show="${msg('showUserAttribute')}" data-label-hide="${msg('hideUserAttribute')}">
            <i class="${properties.kcFormPasswordVisibilityIconShow!}" aria-hidden="true"></i>
        </button>
    </div>
    <#if usernameHidden?? && messagesPerField.existsError('username','password', 'user_attribute')>
    <span id="input-error" class="${properties.kcInputErrorMessageClass!}" aria-live="polite">
        ${kcSanitize(messagesPerField.getFirstError('username','password'))?no_esc}
    </span>
    </#if>
</div>
<!-- attribute input block end-->

<div class="${properties.kcFormGroupClass!} ${properties.kcFormSettingClass!}">
    <div id="kc-form-options">
        <#if realm.rememberMe && !usernameHidden??>
            <div class="checkbox">

Testing & development

Build the project

$ mvn package

Run Keycloak with authenticator in docker compose

After building a project, do following to start Keycloak with bundled authenticator jar and dummy configuration (dev-realm.json).

$ docker compose up

Open browser and go to http://localhost:8080/realms/dev-realm/account use Username or email = test, Password = test and Favorite number = 46 to login.