Keycloak - 从身份提供商登录获取电子邮件地址,而无需创建新帐户

时间:2018-03-26 11:54:32

标签: javascript openshift openid keycloak openshift-origin

我尝试将Google用作Keycloak的身份提供商,作为OpenShift的OAuth提供商。

first-broker-login的默认身份验证流程允许任何Google帐户访问Keycloak,因此我希望尽早在身份验证流程中插入脚本,以验证用户使用的电子邮件是否属于到特定的托管域。

我当前的脚本如下所示:

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();
}

在"创建用户之前使用此脚本如果是唯一的"验证步骤将出错,因为UserModel不存在,因为在此上下文中此流的此时没有用户存在。

将其移至流程的后续阶段(Create User If Unique之后)允许在流上下文中创建用户,并且脚本成功检测到流氓电子邮件,但是,流氓用户现在可以访问Keycloak (除非我在if语句中添加user.setEnabled(false);)。

我几天来一直在反对这一点,我不知所措。

Screenshot of Authentication Flow

修改:我尝试使用UserModel之类的语句修改脚本以绕过不存在的var email = context.getHttpRequest().getDecodedFormParameters().getFirst("email"); - 这只会返回null }

编辑2:登录时,我尝试使用的电子邮件地址位于错误日志中:

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

1 个答案:

答案 0 :(得分:0)

在与同事一起挖掘后,我们发现了解决方案。

错误日志的最后一行打印出一大堆变量,其中一个是identity_provider_identity=user@domain.com,在挖掘之后我们将其追溯到EventBuilder类,然后进入{{1} } 在Event类中是一个调用名为Event的散列映射的方法。

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; } 将返回客户端使用的电子邮件。