使用 API 登录 Keycloak

Posted

技术标签:

【中文标题】使用 API 登录 Keycloak【英文标题】:Login to Keycloak using API 【发布时间】:2018-06-21 13:49:38 【问题描述】:

我有 2 个不同的应用程序:Application1Application2

    我已将 Application2 与 keycloak 集成,我可以使用 Keycloak 的登录页面登录到此应用程序。

    现在我想要的是,如果我登录到我的 Application1(没有 keycloak),我应该能够调用 keycloak 的一些 API 来登录到 application2(不呈现 keycloak 的登录页面)。

可行吗?如果是,怎么做?

我们将不胜感激。

谢谢

【问题讨论】:

请参考[***.com/questions/49313554/…获取更多帮助 【参考方案1】:

您实际上是在要求您的用户相信 Application1 将安全地管理他们的 keycloak 凭据。不推荐这样做,因为

    如果用户被重定向到 keycloak 以输入他们的凭据,则可以实现更好的安全性。在理想情况下,任何客户端应用程序都不应处理或访问用户凭据。 它违背了单点登录的目的,用户只需要输入他们需要访问的第一个应用程序的凭据(假设他们的会话未过期)

但是,如果您控制并且可以信任 Application1 并且由于遗留或其他原因需要这样做,那么您可以在 Keycloak 客户端定义上启用名为“直接访问”的资源所有者凭据流,并且然后将用户的凭据作为form-urlencoded 数据类型发布到

https://<keycloak-url>/auth/realms/<realm>/protocol/openid-connect/token

参数将是

grant_type=password
client_id=<Application1's client id>
client_secret=<the client secret>
username=<the username>
password=<the password>
scope=<space delimited list of scope requests>

如果凭据无效,响应将是有效的 JWT 对象或 4xx 错误。

【讨论】:

谢谢 shonky。我能够从您刚才提到的 REST 服务中得到响应。我正在获取访问令牌、刷新令牌和其他一些参数。但是,我仍然无法直接登录到 keycloak 服务器。我错过了什么吗? 上面的 api 会给你一个访问令牌,你可以用它来调用你的应用程序2。如果您有访问令牌并获得 401,请检查您是否正确传递它(Bearer AccessToken),如果是,请检查 app2 端的日志。如果您收到 403 问题,则与角色和访问列表有关。只是指出上述方法不会让您访问 Keycloak 服务器(如果您想要,那么也许您需要详细说明用例) @Anunay 感谢您的宝贵回复。但我的疑问仍然存在。我在问如何使用我拥有的访问令牌调用 Application2。 如果你正在进行休息调用,在授权头中传递令牌curl http://localhost:8080/service/secured -H "Authorization: bearer $TOKEN"参考Obtain Token and invoke service 对我来说只使用参数grant_type、client_id、用户名、密码也可以【参考方案2】:

如果我的问题正确,您正试图通过另一个已经登录的应用程序调用仅承载服务,您也没有提及您是否使用 Spring Boot 或其他类似的框架,所以我假设你正在为你的服务器端应用程序使用 Spring Boot。

以下示例反映了一个经过身份验证的 API 对另一个 API 的简单调用,两者都使用 Spring Boot:

import org.keycloak.KeycloakPrincipal;
import org.keycloak.adapters.RefreshableKeycloakSecurityContext;
import org.keycloak.adapters.springsecurity.account.SimpleKeycloakAccount;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;

@Component
public class AnotherServiceClient 
    public TypeOfObjectReturnedByAnotherService getFromAnotherService() 
        RestTemplate restTemplate = new RestTemplate();
        String endpoint = "http://localhost:40030/another/service/url";
        String bearerToken = getAuthorizationToken();

        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "bearer " + bearerToken);

        HttpEntity entity = new HttpEntity(headers);

        ResponseEntity<TypeOfObjectReturnedByAnotherService> response = restTemplate.exchange(endpoint, HttpMethod.GET, entity, TypeOfObjectReturnedByAnotherService.class);

        return response.getBody();
    

    private String getAuthorizationToken() 
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        SimpleKeycloakAccount details = (SimpleKeycloakAccount) authentication.getDetails();

        KeycloakPrincipal<?> keycloakPrincipal = (KeycloakPrincipal<?>) details.getPrincipal();

        RefreshableKeycloakSecurityContext context = (RefreshableKeycloakSecurityContext) getPrincipal().getKeycloakSecurityContext();

        return context.getTokenString();
    

通过这种方式可以将您的原始服务生成的实际有效令牌发送到另一个服务。

【讨论】:

【参考方案3】:

YES- 您可以在不使用 keycloak 登录界面的情况下登录到 Application-1

可以使用各种客户端适配器来实现此目的。在这里你没有提到你的应用程序框架。

要了解有关 keyclaok 客户端适配器的更多信息:click here

例如,如果您选择 Node.js 适配器,那么您可以点击链接:node.js adapter

使用 node.js 适配器的 keycloak 实现,有关 REST api 和令牌验证机制的详细信息在此链接 click for example 中有很好的解释

【讨论】:

我正在使用 Java。【参考方案4】:

Application2中,您使用了一种名为The Authorization Code grant的授权类型;它是OAuth framework指定的几个grant types之一。

Application1 获取 Access Token 的方法称为password Grant,除非您信任您的应用,否则不再建议使用此授权。

您可以了解 here 以正确方式将 keycloak 与 javascript 应用程序集成的不同策略

【讨论】:

以上是关于使用 API 登录 Keycloak的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 nsjsonserilization 添加登录 api。?

Liferay 使用 API/Web 服务登录

如何使用 Django Rest Framework 创建登录 API?

保护使用通过 twitter 登录的应用程序的 API

如何使用邮递员测试 Django REST 框架登录保护 API?

REST API 登录模式