Prifulnath
Prifulnath

Reputation: 567

Validating Username and Password in Keycloak

I am trying to validate a users username and password from keycloak backend because I have a custom authentication form. I was using the below code to validate the user, which is working as expected.

private UserModel getUserByUserNameAndPassword(AuthenticationFlowContext context, String username,
        String password) {
    RealmModel realm = context.getRealm();
    UserModel user = context.getSession().users().getUserByUsername(realm, username);
    if (user != null) {
        context.setUser(user);
        context.success();
    }
    return user;
}

But I cant validate the password of that user. Can somebody help me to use the password for validating the user.

Thanks in advance.

Upvotes: 0

Views: 1703

Answers (3)

Vujasinovic
Vujasinovic

Reputation: 1

here is my solution. I used credentialManager() method on UserModel.

UserProvider userProvider = context.getSession().getProvider(UserProvider.class);
UserModel user = userProvider.getUserByUsername(context.getRealm(), username);

boolean isPasswordValid = user.credentialManager().isValid(UserCredentialModel.password(password))

Upvotes: 0

Prifulnath
Prifulnath

Reputation: 567

Here is the solution worked for me. I used validatePassword function in the AbstractUsernameFormAuthenticator class.

My inputData from form parameter provide username and password.

private UserModel getUserByUserNameAndPassword(AuthenticationFlowContext context, String username) {
    RealmModel realm = context.getRealm();
    UserModel user = context.getSession().users().getUserByUsername(realm, username);
    MultivaluedMap<String, String> inputData = context.getHttpRequest().getDecodedFormParameters();
    boolean shouldClearUserFromCtxAfterBadPassword = !isUserAlreadySetBeforeUsernamePasswordAuth(context);

    if (user != null
            && validatePassword(context, user, inputData, shouldClearUserFromCtxAfterBadPassword)) {
        return user;
    } else {
        return null;
    }
}

Upvotes: 0

maio290
maio290

Reputation: 6742

The main issue you're probably facing on your way to implement is that you're trying to compare a plaintext password with a hashed and salted password.

Given that one of their integration tests looks like that: [Source]:

  UserProvider userProvider = session.getProvider(UserProvider.class);
  UserModel user = userProvider.getUserByUsername(userName, realm);
  return userProvider.validCredentials(session, realm, user, UserCredentialModel.password(password));

You should be able to do the following:

UserProvider userProvider = context.getSession().getProvider(UserProvider.class);
UserModel user = userProvider.getUserByUsername(userName, context.getRealm());
final booolean isValidPassword = userProvider.validCredentials(context.getSession(), context.getRealm(), user, UserCredentialModel.password(password));

Upvotes: 0

Related Questions