Java客户端刷新keycloak令牌

Aru*_*ran 7 spring-security spring-boot keycloak keycloak-services

想象,

以下是 keyclock 中的 2 个客户端(2 个微服务)。

  • 休息服务-1
  • 休息服务-2

以下是rest-service-2中的作用

  • 服务 2 用户

做服务到服务调用,即:rest-service-1调用rest-service-2

“rest-service-1”在 Keycloak 中配置了以下值

Access Type: confidential
Service Account Enabled: Yes
Run Code Online (Sandbox Code Playgroud)

此外,在 rest-service-1 的“服务帐户角色”下,添加/映射了以下角色

Role for client rest-service-2: service-2-user
Run Code Online (Sandbox Code Playgroud)

在keyclock中设置2个客户端和服务帐户以调用客户端后。我创建了一个 Spring boot 2.0.3 项目并使用以下代码获取令牌。

@Bean
public AuthzClient authzClient(KeycloakSpringBootProperties kcProperties) {
  //org.keycloak.authorization.client.Configuration
  Configuration configuration =
      new Configuration(kcProperties.getAuthServerUrl(), 
                        kcProperties.getRealm(), 
                        kcProperties.getResource(),
                        kcProperties.getCredentials(), null);

  return AuthzClient.create(configuration);
}
Run Code Online (Sandbox Code Playgroud)

这是我获取访问令牌的方法

@Autowired
private AuthzClient authzClient;

public AccessTokenResponse token() {
  return authzClient.obtainAccessToken();
}
Run Code Online (Sandbox Code Playgroud)

以下是收到的令牌:

{
  "access_token": ${access-token},
  "expires_in": 300,
  "refresh_expires_in": 1800,
  "refresh_token": ${refresh-token},
  "token_type": "bearer",
  "id_token": null,
  "not-before-policy": 0,
  "session_state": "6f284b2f-5bb6-4018-8acd-b83923ebb7d7",
  "scope": "profile email"
}
Run Code Online (Sandbox Code Playgroud)

注意:我替换了令牌以使其简短/简短。

题:

如何使用上述刷新令牌并获取新的访问令牌。AuthzClient 支持吗?如果是这样,我该怎么做?

我是否需要创建一个新的 TokenCallable 实例并获取令牌?如果是这样,如何实例化 TokenCallable?

TokenCallable 线程安全吗?

mas*_*ick 6

您不能通过类显式地执行此操作AuthzClient。但是,您可以使用包中的一些低级 API org.keycloak.authorization.client.util,即Http类。例如:

public AccessTokenResponse refreshToken(String refreshToken) {
    String url = kcProperties.getAuthServerUrl() + "/realms/" + kcProperties.getRealm() + "/protocol/openid-connect/token";
    String clientId = kcProperties.getResource();
    String secret = (String) kcProperties.getCredentials().get("secret");
    Http http = new Http(kcConfig, (params, headers) -> {});

    return http.<AccessTokenResponse>post(url)
            .authentication()
                .client()
            .form()
                .param("grant_type", "refresh_token")
                .param("refresh_token", refreshToken)
                .param("client_id", clientId)
                .param("client_secret", secret)
            .response()
                .json(AccessTokenResponse.class)
            .execute();
}

@Bean
public org.keycloak.authorization.client.Configuration kcConfig() {
    return new org.keycloak.authorization.client.Configuration(
            kcProperties.getAuthServerUrl(),
            kcProperties.getRealm(),
            kcProperties.getResource(),
            kcProperties.getCredentials(),
            null
    );
}
Run Code Online (Sandbox Code Playgroud)

该解决方案是完全线程安全的(CloseableHttpClient详情请参阅 参考资料)。

  • 我想你误解了我的观点。AuthzClient 基本上是 Keycloak 的 REST 客户端。我的回答解释了如何使用刷新令牌通过 REST 从 Keycloak 服务器获取新令牌。 (2认同)