Warm tip: This article is reproduced from stackoverflow.com, please click
java keycloak

Problem Implementing a custom Keycloak Authenticator SPI

发布于 2020-03-27 10:16:48

I'm trying to implement a custom keycloack Authenticator SPI for authentication purposes against an external Identity provider. The users already exist on the keycloak store, I only need connection to the custom SPI to authenticate them.

I'm following section 8.3 of the official guide https://www.keycloak.org/docs/latest/server_development/index.html#_auth_spi_walkthrough, which is very similar to what I need.

The problem I'm running into is that after the authentication flow runs into the "action" method of the custom Authenticator, an exception is thrown from the AuthenticationProcessor Class, which after inspection, comes from following check:

 // org.keycloak.authentication.AuthenticationProcessor - line 876
    if (authenticationSession.getAuthenticatedUser() == null) {
         throw new AuthenticationFlowException(AuthenticationFlowError.UNKNOWN_USER);
    } 

after seeing this problem, my idea for trying solving it, was getting the user (already verified against the externl Identity Provider) from the keycloak store, and pushing it into the AuthenticationSession, like this:

// Connect against external Service Provider
// and asume "USER_ID" represents an already validated User

// AuthenticationFlowContext = afc is given as parameter
UserFederationManager ufm = afc.getSession().users();   // <-- PROBLEM
UserModel userFound = ufm.getUserById("USER_ID", afc.getRealm());

if (userFound != null) {
    // get reference to the authSession
    AuthenticationSessionModel asm = afc.getAuthenticationSession();
    // set authenticated user on the session
    asm.setAuthenticatedUser(userFound );
    return true;
}
return false;

The problem with the above code, is that a Java NoSuchMethodExceptionError is thrown regarding the users() method of the org.keaycloak.models.KeycloackSession class. Like this:

11:26:32,628 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-14) Uncaught server error: java.lang.NoSuchMethodError: org.keycloak.models.KeycloakSession.users()Lorg/keycloak/models/UserFederationManager;

Any suggestion that you could make to help me solve this would be greatly appreciated!

Questioner
tony _008
Viewed
383
tony _008 2019-07-03 21:23

It seems the problem was that I was using an org.keycloak.models.UserFederationManager instance, instead of an org.keycloak.models.UserProvider instance. The UserFederationManager implements the UserProvider, and it seems the more general type works better than the more specific type under the injection mechanism this keycloak is using

 // UserFederationManager ufm = afc.getSession().users();   // <-- PROBLEM
 // UserProvider ufm = afc.getSession().users();            // <-- WORKS

Even though it works now, both of your suggestions are valid because my build version is indeed diferent that the one on the runtime, I'll solve that to avoid further Bugs.

Thanks your input Guys!