Imagine,
Following are the 2 clients (2 micro-services) in keyclock.
Following is the role in rest-service-2
To do service to service call, ie: rest-service-1 calls rest-service-2
'rest-service-1' is configured with following values in Keycloak
Access Type: confidential
Service Account Enabled: Yes
Also, under 'Service Account Roles' for rest-service-1, following role is added/mapped
Role for client rest-service-2: service-2-user
After setting up the 2 clients and service account for calling client in keyclock. I created a Spring boot 2.0.3 project and used the following code to get the token.
@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);
}
Here is how I get access token
@Autowired
private AuthzClient authzClient;
public AccessTokenResponse token() {
return authzClient.obtainAccessToken();
}
Following is the token received:
{
"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"
}
Note: I replaced tokens for making it short/brief.
QUESTION:
How do use the refresh token stated above and get a new Access Token. Does AuthzClient support that? If so, how do I do that?
Do I need to create a new Instance of TokenCallable and get the token? If so how to instanciate TokenCallable?
Is TokenCallable thread safe?
You cannot do this explicitly by means of AuthzClient
class. However, you can use some low-level API from org.keycloak.authorization.client.util
package, i.e. the Http
class. For example:
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
);
}
This solution is fully thread-safe (see CloseableHttpClient
for the details).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With