【问题标题】:Keycloak impersonate with token-exchange使用令牌交换模拟 Keycloak
【发布时间】:2021-07-30 10:49:48
【问题描述】:

技术细节:

Keycloak 版本:12.0.2
Java 版本:1.8
Java 管理客户端:12.0.2
Keycloak Spring 启动器

说明

我有一个 Spring Boot 应用程序,内部人员可以使用其官方 java 依赖项创建和修改 Keycloak 用户。此应用程序还应包含模拟功能。

我尝试使用 Java Admin Client 进行模拟,模拟函数返回一个映射,其中包含布尔值“sameRealm”和指向 Keycloak 帐户页面的重定向 URL。使用这两个值,我无法访问模拟用户的会话,也无法真正将这些属性用于其他用途。

之后我尝试了 Keycloak Rest API 的模拟功能,不幸的是,API 在标头中返回了一些 Cookie,我似乎无法弄清楚如何使用这些 cookie,但我尝试创建这些 cookie 并设置它们但不幸的是它没有用。

最后,我尝试了一个令牌交换来接收一个有效的访问令牌,幸运的是这个功能可以工作。

代币兑换功能

       Keycloak keycloakService = KeycloakBuilder.builder()
        .serverUrl(serverUrl)
        .realm(realm)
        .clientId(clientId)
        .grantType(OAuth2Constants.CLIENT_CREDENTIALS)
        .clientSecret(clientSecret)
        .build();

       BasicCookieStore cookieStore = new BasicCookieStore();
       CloseableHttpClient httpClient = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build();

       HttpUriRequest reqBuild = RequestBuilder.post()
         .setUri(serverUrl + "/realms/intern/protocol/openid-connect/token")
         .addHeader("Content-Type", "application/x-www-form-urlencoded")
         .addParameter("client_id", "example")
         .addParameter("client_secret", "example") //
         .addParameter("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange")
         .addParameter("subject_token", keycloakService.tokenManager().getAccessTokenString())
         .addParameter("requested_token_type", "urn:ietf:params:oauth:token-type:access_token")
         .addParameter("requested_subject", userId)
         .addParameter("audience", "target-client")
         .build();

       HttpResponse res = httpClient.execute(reqBuild);
       String resBody = EntityUtils.toString(res.getEntity());
       System.out.println(resBody);

通过上面的代码,我从 Keycloak 收到了一个有效的访问令牌。但不幸的是,我不知道如何使用这个令牌来完成模拟过程。

设置如下:id.example.com 提供 Spring Boot Application,sso.id.example.com 运行 KeyCloak 实例。据我了解,我应该为 sso.id.example.com 创建一个 cookie

如果有人对我如何模拟用户然后获取关联会话有其他解决方案。我将不胜感激。

【问题讨论】:

    标签: java spring-boot keycloak


    【解决方案1】:

    您的 resBody.contentAccessTokenResponse 类型(假设您收到 200 响应),它具有 token 属性。令牌应该是您要模拟的用户的 auth_token。作为健全性检查,您可以使用 https://jwt.io/ 调试返回的 jwt 令牌,以确保它适用于正确的用户。

    您可以使用此令牌作为您冒充的人进行后续呼叫。

    我认为您不需要设置 cookie 存储,我确信您可以删除它并且它应该会继续工作。

    import org.keycloak.admin.client.Keycloak
    
    ...
    val keycloakService = KeycloakBuilder.builder()
            .serverUrl(serverUrl)
            .realm(realm)
            .clientId(clientId)
            .grantType(OAuth2Constants.CLIENT_CREDENTIALS)
            .clientSecret(clientSecret)
            .build();
    
    val httpClient = HttpClientBuilder.create().build();
    
    val reqBuild = RequestBuilder.post()
             .setUri(serverUrl + "/realms/intern/protocol/openid-connect/token")
             .addHeader("Content-Type", "application/x-www-form-urlencoded")
             .addParameter("client_id", "example")
             .addParameter("client_secret", "example") //
             .addParameter("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange")
             .addParameter("subject_token", keycloakService.tokenManager().getAccessTokenString())
             .addParameter("requested_token_type", "urn:ietf:params:oauth:token-type:access_token")
             .addParameter("requested_subject", userId)
             .addParameter("audience", "target-client")
             .build();
    
    val response = httpClient.execute(reqBuild)
    val entity = if (response.statusLine.statusCode == 200) {
        val mapper = ObjectMapper().registerModule(KotlinModule())
        mapper.readValue(response.entity.content, AccessTokenResponse::class.java)
    } else {
      // handle error
    }
    
    // this should log you in as the impersonated user
    val impersonated = Keycloak.getInstance(serverUrl, realm, clientId, entity.token).realm(realm)
    
    
    

    【讨论】:

      猜你喜欢
      • 2022-01-12
      • 2018-08-15
      • 2019-12-05
      • 2020-10-09
      • 1970-01-01
      • 2017-01-03
      • 2019-04-21
      • 1970-01-01
      • 2021-02-03
      相关资源
      最近更新 更多