Keycloak 身份代理 API

Posted

技术标签:

【中文标题】Keycloak 身份代理 API【英文标题】:Keycloak Identity Broker API 【发布时间】:2019-11-08 14:39:11 【问题描述】:

所以我有一个使用 api 的客户端。 API 由 keycloak 保护。 用户正常登录,但我希望允许用户登录用户,而不必使用他们的社交媒体帐户(如 facebook 或 google)进入 keycloak 的登录页面。 我需要一个带有如何生成 url 的实现的 rest API,因此当用户在按钮中单击此 url 时,它将把用户带到相应的社交登录页面进行登录,而 keycloak 仍然充当代理。

以下是我的实现,它会生成一个 url,但不会将用户带到 google 页面登录

这是一个休息控制器

    @Secured("permitAll")
    @GetMapping(path = "/generator")
    public String brokerGenerator(HttpServletRequest httpServletRequest) throws ServletException 
        String provider = "google";
        String authServerRootUrl = "http://localhost:8080/";
        String realm = "realmName";
        String clientId = "clientName";
        String nonce = UUID.randomUUID().toString();
        MessageDigest md = null;

        try 
            md = MessageDigest.getInstance("SHA-256");
         catch (NoSuchAlgorithmException e) 
            throw new RuntimeException(e);
        

        String input = nonce + clientId + provider;
        byte[] check = md.digest(input.getBytes(StandardCharsets.UTF_8));
        String hash = Base64Url.encode(check);
        httpServletRequest.getSession().setAttribute("hash", hash);

        String redirectUri = "http://localhost:4200/dashboard"; 

        return KeycloakUriBuilder.fromUri(authServerRootUrl)
                .path("auth/realms/realmName/google/link")
                .queryParam("nonce", nonce)
                .queryParam("hash", hash)
                .queryParam("client_id", clientId)
                .queryParam("redirect_uri", redirectUri).build(realm, provider).toString();

    

【问题讨论】:

【参考方案1】:

Keycloak 开箱即用地支持这一点。见https://www.keycloak.org/docs/6.0/server_admin/#_client_suggested_idp

OIDC 应用程序可以通过指定他们想要使用的身份提供者的提示来绕过 Keycloak 登录页面。

这是通过在授权代码流授权端点中设置 kc_idp_hint 查询参数来完成的。

更新

在您的情况下,您应该使用普通的 Keycloak Auth Code Flow 端点,并且除了基本查询参数之外,还提供 kc_idp_hint 参数。这样,用户首先被重定向到 Keycloak 登录页面,然后 Keycloak 将他重定向到选择的身份提供者登录页面(在你的情况下是谷歌)。

这是一个重定向 URL 示例:

https://keycloak-domain/realms/REALM_NAME/protocol/openid-connect/auth?client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&state=STATE&response_type=code&scope=openid&nonce=NONCE&kc_idp_hint=google

根据此示例编辑您的代码:

return KeycloakUriBuilder.fromUri(authServerRootUrl)
    .path("realms/realmName/protocol/openid-connect/auth") // Url changed
    .queryParam("response_type", "code") // Autherization Code Flow
    .queryParam("scope", "openid") // Add additional scopes if needed
    .queryParam("kc_idp_hint", "google") // This should match IDP name registered in Keycloak
    .queryParam("nonce", nonce)
    .queryParam("hash", hash)
    .queryParam("client_id", clientId)
    .queryParam("redirect_uri", redirectUri).build(realm, provider).toString();

您可以手动启动 Keycloak 重定向以进行测试。开始正常的登录流程,当您重定向到 Keycloak 登录页面时,不要输入凭据,而是将 kc_idp_hint=google 添加到 URL 并按 ENTER。然后您将被重定向到 Google 登录页面。

【讨论】:

请您再详细说明一下。 好的,这很好,但是,我得到了 uri,我将它复制到浏览器并按下回车键。不是把我带到谷歌登录页面,而是把我带到重定向网址。不知道你懂不懂。 在您添加&kc_idp_hint=google 并按ENTER 后,您会被重定向回重定向URL?如果在所选领域中没有配置具有给定名称的 IDP,则会发生这种情况。 是的,它会生成一个类似 keycloak-domain/realms/REALM_NAME/protocol/openid-connect/… 的 url,但它会将我带到我的 queryParam 重定向 uri 中使用的重定向 url 清除 cookie 或最好在隐身模式下尝试。您的浏览器在之前的登录尝试中缓存了 Google/Keycloak 身份验证数据。

以上是关于Keycloak 身份代理 API的主要内容,如果未能解决你的问题,请参考以下文章

使用反向代理后面的 keycloak 进行身份验证失败

Keycloak:如何仅通过身份提供者登录

在 EC2 上部署的 docker 中使用 flask_oidc 和 nginx 反向代理的烧瓶应用程序在使用 keycloak 进行身份验证后给出未授权错误

keycloak 无效参数:redirect_uri 在反向代理后面

Keycloak 自定义用户联合和身份提供者工作顺序

为啥带有 Netflix Zuul 反向代理的 Keycloak OAUTH2 不传递令牌