keycloak: notification after max login failure - keycloak

After a user has failed to log in too many times in too short a time, is there a way to have the Keycloak login screen tell the user that they are temporarily locked, so they can know they have to wait and try again later?
At the moment, it continues to tell them their password is wrong, so they will probably keep trying, and may end up being told their correct password is incorrect.

Keycloak provides you the possibility to define custom messages and to provide a custom theme where you can overwrite certain views and messages as well as provide messages for other languages.
https://www.keycloak.org/docs/latest/server_development/#_themes
Custom message key
You can modify the message key 'invalidUserMessage' which is the message shown when the user is locked. It defaults to 'Invalid username or password'.
We do it by providing a custom theme for the login type, but you can modify the message key provided by the keycloak installation at 'keycloak/themes/base/login/messages/messages_en.properties'.
Custom view
When you provide a custom login-password.ftl or login.ftl, depends on what you use, then you could check for the message during the rendering, and conditionally render a part which is only shown when the user is locked.
<#assign userLocked = message?? && message.summary == msg("invalidUserMessage")>
<#if section = "header" && !userLocked >...<#/if>
For instance, we use it in javascript to disable all inputs when we see that the user is locked along with displaying the modified message to the user.
<script>
const serverFieldErrors = {
"password": "${(message.summary)!""}"
}
if (serverFieldErrors.password === "${msg('invalidUserMessage')}") {
document.querySelectorAll("input").forEach((element) => element.setAttribute("disabled", "disabled"));
}
</script>
To my knowledge, keycloak provides no other way to handle such a use case.

Related

Keycloak - conditinal flow - cannot edit condition

I want to create a conditional flow for reseting password: if a user will have some attribute or a role then I don't want the reset password email to be sent. But when I edit keycloak flow conditions I am getting a weird error.
A flow which I've created.
However when I want to edit the condition and click on the options button there I am getting such a message:
Cannot convert undefined or null to object
The same is for other conditions.
In the keyckloak logs I don't see any errors.
I am using dockerized keyckloak 19
Maybe someone knows some other way how to disable resetting password only for particular users.
Thank you

Preventing user from modifying their name in Keycloak

In Keycloak, by default, users are able to change their first and last name in the account manager page. However, is it possible to disable this behavior?
Removing both fields in the theme results in those values not being sent and the form failing, and a hand-crafted POST request would defeat this method anyway.
I came across a similar problem and after reading this SO post, came to know that although you can disable/hide fields in ftl, you cannot disable form validation
For e.g I hid firstname field , but still cannot submit. Same was the result with disable as well:
I am not aware about disabling a particular field in some other way. However there is a workaround in which you can disable the entire account modification flow (Password can still be changed by Forgot Password option).
Bu default, account modification is enabled, but you can disable it for a particular realm by going to Realms -> Clients -> Account.
The result of this will be, the account page will be inaccessible:
You can remove the client role 'manage_account' for client 'account'.
In Keycloak, by default, users are able to change their first and last
name in the account manager page. Is it possible to disable this
behavior?
That can be done out-of-the-box (since Keycloak 14) by using the user profile functionality. First, the preview feature declarative-user-profile has to be enabled. For that start the server with:
--features=declarative-user-profile.
for the Quarkus version, or with
-Dkeycloak.profile.feature.declarative_user_profile=enabled
for the Wildfly version.
Bear in mind that:
Declarative User Profile is Technology Preview and is not fully
supported.
After starting the server with the aforementioned option, go to the Keycloak Admin Console and:
Go to the according Realm;
Go to the tab General;
Set User Profile enabled to ON
A new tab named User Profile (top right) will show up; click on it, and a set of configurable attributes will be shown.
Click on firstName, and then go to Permissions
In that section the permissions can be changed, accordingly. For example, if one sets Can user edit? to OFF, then when the user tries to change the firstName field in the account UI, that UI throws the following warning message:
The field First name is read only.
The same configuration can also be applied to the lastName attribute.
For the new Keycloak UI the workflow is exactly the same as the one I have just described. More information about the feature can be found in the official keycloak documentation (link)
You can use readonly property to disable email you can just change the following line:
<input type="text" class="form-control" id="email" name="email" readonly autofocus value="${(account.email!'')}"/>

Loopback login with phone as username and verification

I've extended the User model in my loopback application, and added phone number as a login method, I use the username field to do this, the only deal is that on login I get the 'email not verified' error, I have my own phoneNumberVerified field, and have overwritten the confirm method to validate the token against the emailVerificationToken and against the phoneNumberVerificationToken and update the corresponding flag, I thought of overwriting the original login method to not allow login only if both emailVerified and phoneNumberVerified fields are false (not just the email) but I don't know how to actually do the login the way loopback does it (I believe it creates an AccessToken or something), and I'm asking for some help on how to do this, thanks XD. I can do the overwriting and validations myself I just need to know how to do the actual login without using the original login method, since I'll be rewriting it.
So I figured out that I actually don't need email or phone number verified validation at all on login (later on the workflow will be required, but that'll be another use case, so it's irrelevant on login to me now XD). So when I was looking on how to overwrite the login method I realized that all the models code it's on the node_modules folder xD
node_modules/loopback/common/models/user.js
And found there in the login method a flag that validates if should check email verified or not, so on my startup script I just put this:
app.models.MyUser.settings.emailVerificationRequired = false;
That stops the email verified validation on login.
And maybe if some of you would like to override the login method I believe copying the whole method from the original user model up there and attaching it to your model and doing some modifications might work xD, it invokes the createAccessToken from the user model (itself) and that's what I believe creates the 'login', what I came to understand is that there is no "session" data, it creates an accesstoken when you successfully login, and as I've been doing just sending the token id to every request 'authenticates' your logged user.
Thanks for reading, have a nice day :)

Password protecting Apigility admin UI without htpasswd

I was being searching to password protect apiglity admin ui without using htpasswd, but i did not got any information about. Can anybody help me out with this?
Thanks in advance
You don't need password protection for ApiGility UI. Access should only be allowed in the Dev environment.
php public/index.php development enable <- to enable the UI
php public/index.php development disable <- to disable the UI
If you consist of having password protection for it. Then you can add an event to the Application Module.php that check if the identified user is allowed to access that resource.
Edit - If you do want to protect something by password
The following code should be placed in the Module.php file. (In many cases under the Application module).
It call the event manager and attach action to the Dispatch event.
Every time the application reach the dispatch phase it will fire this event.
The action is passed as a call back so you can attach function, classes ans etc. In this example I passed a new class that have access to the MvcEvent ($e).
For example, that class can check if a user is logged in. If it is not then redirect him to /login.
public function onBootstrap(MvcEvent $e)
{
$eventManager = $e->getApplication()->getEventManager();
$eventManager->attach(MvcEvent::EVENT_DISPATCH, array(new UserAccessChecker($e), 'getResponse'));
}
For the purpose of auth You should further investigate ACL & RABC

Multiple scenarios within a specification feature file?

After having gotten more comfortable in Behaviour-Driven Developement using SpecFlow, I was wondering about having multiple scenarios for the same feature as follows:
Register.feature
Feature: Register a new user
In order to use the system,
one must register with the system
so that one gets authorized and may login
Scenario: Register a new user using valid credentials
Given I am on the registration page
When I have entered my desired username "UserName" and password "password"
And I have confirmed my password "password"
And I click the register button
Then I shall get confirmation that I am now a registered user
Beside the fact that my scenario might have gotten a bit too fat, one must also manage to validate other scenarios within the registration process such as:
Input user name is too short
Input password is too short
Input password doesn't contain numbers
Input password doesn't match the confirm password
Just to name a few. I have read about tags using SpecFlow Feature File so that I could perhaps do as follows:
#shorterPasswordProvided
Scenario: Register a user using a password that is too short
Given I am on the registration page
When I have entered my desired user name
And I have provided a password that is too short "allo"
And I click the Register button
Then I shall get an error message which mentions about the password minimum length
#noCredentialsAtAll
Scenario: Register a user using no credentials at all
Given I am on the registration page
When I click on the Register button with no credentials entered
Then I shall get an error message that says I have to fill all required fields in
Then, using the [BeforeScenario("myTag")] should do the trick.
The hooks allows for the execution of a subset of the tests to be executed following certain rules. So, a When method could then be executed with a predefined context, that is, the hook for which it was meant to be executed, and that is mentioned through the BeforeScenario or the like attribute.
Have I understood correctly, or am I in fog here?
Am I pushing too far?
Am I missing something?
Are all the "too short password", "no credentials provided" considered different usage scenarios, or are they something else which could only fit somewhere else in the code, like the unit tests themselves?
I mean, all those scenarios belongs to the Register feature, and as such, they shall be defined in the same Register.feature SpecFlow Feature File, right?
Ok, you have a couple of questions, so I'll work through them:
Then, using the [BeforeScenario("myTag")] should do the trick.
The BeforeScenario hook attribute is used to run some code before the scenario executes. It's often used to set-up the environment for the scenario (e.g. populate the test database with pertinent data); if used for this purpose, then the use of AfterScenario can also be used to clean-up the result of BeforeScenario.
The hooks allows for the execution of a subset of the tests to be
executed following certain rules. So, a When method could then be
executed with a predefined context
If I understand you correctly, you want to be able to use a tag to control when a step within the scenario can be run/not-run. This is not possible with SpecFlow's hook attributes; there is a BeforeStep hook but this only enables you to execute code before the step is run, it doesn't allow the step to be ignored.
Are all the "too short password", "no credentials provided" considered
different usage scenarios, or are they something else which could only
fit somewhere else in the code, like the unit tests themselves?
In your example, yes these are different scenarios for your "Register a new user" feature. If you are taking a strict BDD approach to your development, then with your "outside-in inside-out" development approach you will also implement unit tests (by falling back to TDD as part of the BDD process) which will also cover the "too short password" and "no credentials provided" validation.
As for your scenario:
When I have entered my desired username "UserName" and password "password"
Instead of using this, use:
When I enter my username "UserName"
And I enter my password "password"
By doing this you will be able to re-use "When I enter my password" in "Register a user using a password that is too short". This leads me onto:
And I have provided a password that is too short "allo"
There is no need to have a separate step which states the password is too short. Just re-use:
When I enter my password "allo"
For the same reason, don't use:
When I click on the Register button with no credentials entered
just reuse:
When I click on the Register button