使用API​​登录Keycloak

Akh*_*ati 17 openid-connect keycloak

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

  1. 我已将Application2与keycloak 集成,并且我可以使用Keycloak的登录页面登录此应用程序.

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

这可行吗?如果有,怎么样?

任何帮助将受到高度赞赏.

谢谢

sho*_*ser 16

您有效地要求您的用户相信Application1将安全地管理他们的密钥泄露凭证.不建议这样做,因为

  1. 如果用户被重定向到keycloak以输入其凭据,则可以获得更好的安全性.在理想的世界中,没有客户端应用程序应该处理或访问用户凭据.
  2. 它违背了单点登录的目的,用户只需输入他们需要访问的第一个应用程序的凭据(如果他们的会话未到期)

但是,如果您控制并且可以信任Application1并且由于遗留或其他原因需要执行此操作,那么您可以在Keycloak客户端定义上启用名为"Direct Access"的资源所有者凭据流,然后将用户的凭据作为form-urlencoded数据类型POST 到

https://<keycloak-url>/auth/realms/<realm>/protocol/openid-connect/token
Run Code Online (Sandbox Code Playgroud)

参数将是

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>
Run Code Online (Sandbox Code Playgroud)

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

  • 如果要进行休息呼叫,请在授权标头中传递令牌`curl http:// localhost:8080 / service / secured -H“ Authorization:bearer $ TOKEN”。请参阅[获取令牌并调用服务](http:/ /blog.keycloak.org/2015/10/getting-started-with-keycloak-securing.html) (2认同)

小智 6

如果我正确地回答了您的问题,您正在尝试通过另一个已登录的应用程序调用仅承载服务,您也没有提到您是否使用 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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