[keycloak-user] Possibility to set new Provider in authentication flow for non-unique usernames

Dominik Guhr pinguwien at gmail.com
Wed Jan 24 06:51:27 EST 2018


So, further investigation notes:

I think I should call the Provider like it's done here: 
https://github.com/keycloak/keycloak/blob/master/examples/providers/user-storage-jpa/src/main/java/org/keycloak/examples/storage/user/EjbExampleUserStorageProviderFactory.java 
in the create method, which allows me to call the corresponding 
isValid(...) method of the required providers and only set the boolean 
return value of validatePassword to false if the credentials doesn't 
match in any of the providers.

But to call this for ldap-providers set by admin interface, I need two 
things:

a) a Componentmodel.
Concrete Question: Anyone knows how to get the right ComponentModel 
instance to use from my AuthenticationFlowContext of 
AbstractUsernameFormAuthenticator.java? I've seen that it's possible to 
get a List of ComponentModels by calling 
context.getRealm().getComponents(), or by getComponent(String s), but I 
don't know which String would be the valid parameter or which Model I 
should take out of the List.

b) the lookup-path.
Concrete question 2: Anyone knows how to get it form the internally used 
Factories or s.th.?

My Providers are 2 ldap directories which I want to iterate over for the 
username.

Thanks in advance!

Best regards,
Dominik

Am 24.01.18 um 09:27 schrieb Dominik Guhr:
> Hi everyone,
> 
> I'm implementing an authentication SPI execution on top of the "normal" 
> username/password form of kc 3.4.3.Final. -> 
> https://github.com/keycloak/keycloak/blob/master/services/src/main/java/org/keycloak/authentication/authenticators/browser/UsernamePasswordForm.java 
> 
> 
> Sadly, usernames are not unique atm, so I need to change the execution, 
> so that it doesn't stop with "invalid credentials" for a user who was 
> found in one Provider.
> 
> Instead of giving the "invalid credentials"-error, I want my execution 
> to first check all other providers for the same username, and then check 
> the credentials against all matches. And just in case of no credentials 
> matching, it should fail, or login a new session for this user when one 
> is found in any of my (3) Providers, which are added by user federation 
> feature (2 ADs, one by a custom user storage SPI).
> 
> So I drilled it down to the method validatePassword(...) in 
> AbstractUsernameFormAuthenticator.java -> 
> https://github.com/keycloak/keycloak/blob/master/services/src/main/java/org/keycloak/authentication/authenticators/browser/AbstractUsernameFormAuthenticator.java 
> line 191, which I want to change accordingly. Sadly, I can't find a 
> method to get all Providers of the realm and check accordingly. The code 
> I want to change is:
> 
> if (password != null && !password.isEmpty() && 
> context.getSession().userCredentialManager().isValid(context.getRealm(), 
> user, credentials)) {
>              return true;
>          } else {...}
> 
> instead of just checking isValid() for one provider, which is what this 
> does atm, I want to check all Providers. Like this pseudocode:
> 
> if (password != null && !password.isEmpty() && 
> context.getSession().userCredentialManager().isValid(context.getRealm(), 
> user, credentials)) {
>              boolean isValid = false;
>          List<Provider> realmProviders = context.getAllProviders();
>          for(Provider provider : realmProviders){
>              isValid = provider.isValid(...);
>          }
>              return isValid;
>          } else {...}
> Could anyone perhaps give me a hint in how to achieve this? I haven't 
> found a method yet to get all Providers and check for isValid in any of 
> the given ones.
> 
> Best regards,
> Dominik
> 
> p.s. I created a stackoverflow question here: 
> https://stackoverflow.com/questions/48399622/keycloak-check-password-in-more-than-one-identity-provider 
> feel free to comment/answer there :)


More information about the keycloak-user mailing list