Java客户端刷新Keycloak令牌

时间:2018-06-28 21:18:58

标签: spring-boot spring-security keycloak keycloak-services

想象,

以下是关键时钟中的2个客户端(2个微服务)。

  • rest-service-1
  • rest-service-2

以下是rest-service-2中的角色

  • service-2-user

为服务呼叫提供服务,即:rest-service-1呼叫rest-service-2

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

Access Type: confidential
Service Account Enabled: Yes

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

Role for client rest-service-2: service-2-user

设置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);
}

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

@Autowired
private AuthzClient authzClient;

public AccessTokenResponse token() {
  return authzClient.obtainAccessToken();
}

以下是收到的令牌:

{
  "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"
}

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

问题:

  

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

     

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

     

TokenCallable线程安全吗?

1 个答案:

答案 0 :(得分:0)

您不能通过AuthzClient lib显式地执行此操作。但是,您可以使用其某些方法。这就是我解决的方法:

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();
}