简体   繁体   中英

Keycloak - Get email address from Identity Provider Login without creating a new account

I'm trying to use Google as an Identity Provider for Keycloak as an OAuth provider for OpenShift.

The default authentication flow for the first-broker-login allows any Google account to gain access to Keycloak, so I want to insert a script as early as possible in the Authentication Flow to validate that the email being used by the user belongs to a specific Hosted Domain.

My current script looks like this:

AuthenticationFlowError = Java.type("org.keycloak.authentication.AuthenticationFlowError");

function authenticate(context) {

    var username = user ? user.username : "anonymous";
    LOG.info(script.name + " trace auth for: " + username);

    var authShouldPass = typeof user.email !== 'undefined' && user.email.endsWith("domain.com");
    if (!authShouldPass) {

        context.failure(AuthenticationFlowError.INVALID_USER);
        return;
    }

    context.success();
}

Using this script before the "Create User If Unique" authentication step will error out because the UserModel doesn't exist, because no user exists at this point of the flow in this context.

Moving this to a later stage in the flow (After Create User If Unique ) allows a user to be created in the flow context and the script succeeds in detecting the rogue email, however, a rogue user now has access to Keycloak (unless I add a user.setEnabled(false); in the if statement).

I've been bashing my head against this for several days now and I am at a loss.

Screenshot of Authentication Flow

Edit: I've tried modifying the script to bypass the non-existent UserModel by using statements such as var email = context.getHttpRequest().getDecodedFormParameters().getFirst("email"); - which just returns null

Edit 2: When logging in, the email address that I attempt to use is in the error logs:

07:11:34,374 WARN  [org.keycloak.events] (default task-5) \
type=IDENTITY_PROVIDER_FIRST_LOGIN_ERROR, \
realmId=openshift, clientId=account, \
userId=null, ipAddress=10.131.0.1, \
error=user_not_found, identity_provider=google, \
auth_method=openid-connect, redirect_uri=https://keycloak.domain.com/auth/realms/openshift/account/login-redirect, \
identity_provider_identity=user@domain.com, code_id=code

After digging with a coworker, we discovered the solution.

The last line of the Error Log prints out a whole bunch of variables, one of which is identity_provider_identity=user@domain.com , after digging we traced this through to the EventBuilder class and then into the Event class.
In the Event class is a method that calls a hashmap named details .

public Event clone() {
    Event clone = new Event();
    clone.time = time;
    clone.type = type;
    clone.realmId = realmId;
    clone.clientId = clientId;
    clone.userId = userId;
    clone.sessionId = sessionId;
    clone.ipAddress = ipAddress;
    clone.error = error;
    clone.details = details != null ? new HashMap<>(details) : null;
    return clone;
}

context.getEvent().event.details.get("identity_provider_identity") will return the email being used by the client.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM