Details
diff --git a/core/src/main/java/org/keycloak/representations/AccessTokenResponse.java b/core/src/main/java/org/keycloak/representations/AccessTokenResponse.java
index 109c35c..fd8ec0f 100755
--- a/core/src/main/java/org/keycloak/representations/AccessTokenResponse.java
+++ b/core/src/main/java/org/keycloak/representations/AccessTokenResponse.java
@@ -15,6 +15,9 @@ public class AccessTokenResponse {
@JsonProperty("expires_in")
protected long expiresIn;
+ @JsonProperty("refresh_expires_in")
+ protected long refreshExpiresIn;
+
@JsonProperty("refresh_token")
protected String refreshToken;
@@ -46,6 +49,14 @@ public class AccessTokenResponse {
this.expiresIn = expiresIn;
}
+ public long getRefreshExpiresIn() {
+ return refreshExpiresIn;
+ }
+
+ public void setRefreshExpiresIn(long refreshExpiresIn) {
+ this.refreshExpiresIn = refreshExpiresIn;
+ }
+
public String getRefreshToken() {
return refreshToken;
}
diff --git a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
index 7297f31..219f1a1 100755
--- a/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
+++ b/services/src/main/java/org/keycloak/protocol/oidc/TokenManager.java
@@ -413,6 +413,9 @@ public class TokenManager {
if (refreshToken != null) {
String encodedToken = new JWSBuilder().jsonContent(refreshToken).rsa256(realm.getPrivateKey());
res.setRefreshToken(encodedToken);
+ if (refreshToken.getExpiration() != 0) {
+ res.setRefreshExpiresIn(refreshToken.getExpiration() - Time.currentTime());
+ }
}
int notBefore = realm.getNotBefore();
if (client.getNotBefore() > notBefore) notBefore = client.getNotBefore();
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
index 27c2e51..f0e2339 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/oauth/AccessTokenTest.java
@@ -102,6 +102,7 @@ public class AccessTokenTest {
Assert.assertEquals(200, response.getStatusCode());
Assert.assertThat(response.getExpiresIn(), allOf(greaterThanOrEqualTo(250), lessThanOrEqualTo(300)));
+ Assert.assertThat(response.getRefreshExpiresIn(), allOf(greaterThanOrEqualTo(1750), lessThanOrEqualTo(1800)));
Assert.assertEquals("bearer", response.getTokenType());
diff --git a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
index 5fd7ad7..1625338 100755
--- a/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
+++ b/testsuite/integration/src/test/java/org/keycloak/testsuite/OAuthClient.java
@@ -403,6 +403,7 @@ public class OAuthClient {
private String accessToken;
private String tokenType;
private int expiresIn;
+ private int refreshExpiresIn;
private String refreshToken;
private String error;
@@ -421,6 +422,7 @@ public class OAuthClient {
accessToken = responseJson.getString("access_token");
tokenType = responseJson.getString("token_type");
expiresIn = responseJson.getInt("expires_in");
+ refreshExpiresIn = responseJson.getInt("refresh_expires_in");
if (responseJson.has(OAuth2Constants.REFRESH_TOKEN)) {
refreshToken = responseJson.getString(OAuth2Constants.REFRESH_TOKEN);
@@ -447,6 +449,10 @@ public class OAuthClient {
return expiresIn;
}
+ public int getRefreshExpiresIn() {
+ return refreshExpiresIn;
+ }
+
public int getStatusCode() {
return statusCode;
}