简体   繁体   English

Keycloak 自定义身份验证器脚本 - 如何在脚本上下文中获取用户的访问令牌或外部 idp 令牌?

[英]Keycloak custom authenticator script - how to get the access token or external idp token of the user within the script context?

I'm trying to implement an Authenticator Execution Script in Keycloak 6.0.X, which retrieves an external IDP token for the user and transforms it before adding it back into the jwt/access token.我正在尝试在 Keycloak 6.0.X 中实现一个身份验证器执行脚本,它为用户检索外部 IDP 令牌并在将其添加回 jwt/访问令牌之前对其进行转换。 The script runs asa 'Post Login Flow' Execution.该脚本作为“登录后流程”执行运行。

I'm so far unable to access either the user access token or the external IDP token directly within the script.到目前为止,我无法直接在脚本中访问用户访问令牌或外部 IDP 令牌。

    /*
    * Template for JavaScript based authenticator's.
    * See org.keycloak.authentication.authenticators.browser.ScriptBasedAuthenticatorFactory
    */

    // import enum for error lookup
    AuthenticationFlowError = Java.type("org.keycloak.authentication.AuthenticationFlowError");

    /**
    * An example authenticate function.
    *
    * The following variables are available for convenience:
    * user - current user {@see org.keycloak.models.UserModel}
    * realm - current realm {@see org.keycloak.models.RealmModel}
    * session - current KeycloakSession {@see org.keycloak.models.KeycloakSession}
    * httpRequest - current HttpRequest {@see org.jboss.resteasy.spi.HttpRequest}
    * script - current script {@see org.keycloak.models.ScriptModel}
    * authenticationSession - current authentication session {@see org.keycloak.sessions.AuthenticationSessionModel}
    * LOG - current logger {@see org.jboss.logging.Logger}
    *
    * You one can extract current http request headers via:
    * httpRequest.getHttpHeaders().getHeaderString("Forwarded")
    *
    * @param context {@see org.keycloak.authentication.AuthenticationFlowContext}
    */

function authenticate(context) {

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

    var federatedIdentity = session.users().getFederatedIdentities(user, realm);
    LOG.info(script.name + " federatedIdentity= " + federatedIdentity);

    var token = federatedIdentity.getToken();

    var authShouldFail = false;
    if (authShouldFail) {

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

    context.success();
}

I'm able to successfully get the FederatedIdentityModel which according to the docs should have a getToken() method however the script fails at this method call with the following error:我能够成功获得 FederatedIdentityModel,根据文档应该有一个 getToken() 方法,但是脚本在此方法调用时失败,并出现以下错误:

TypeError: federatedIdentity.getToken is not a function in eval类型错误:federatedIdentity.getToken 不是 eval 中的函数

I've tried using Object.getOwnPropertyNames(session) to see what fields and methods are available on these variables but it turns our they're not Javascript Objects at all..我已经尝试使用Object.getOwnPropertyNames(session)来查看这些变量上有哪些字段和方法可用,但结果表明它们根本不是 Javascript 对象。

TypeError: org.keycloak.services.DefaultKeycloakSession@2f2807cd is not an Object in eval类型错误:org.keycloak.services.DefaultKeycloakSession@2f2807cd 不是 eval 中的对象

More digging reveals:更多挖掘揭示:

session instanceof Object returns false while typeof session returns 'object' session instanceof Object返回falsetypeof session返回'object'

Any ideas or inspiration would be much appreciated!任何想法或灵感将不胜感激!

getFederatedIdentities返回一个 Set,因此您需要:

var federatedIdentity = session.users().getFederatedIdentities(user, realm).toArray()[0];

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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