I am faced with an issue where I think I need a sliding expiration time for my access token. I am running on a glassfish server using the org.keycloak.adapters.servlet.KeycloakOIDCFilter to inspect all requests. The filter I have setup inspects the AccessToken and interrogates access by making sure the token is not expired by:
KeycloakSecurityContext kc = (KeycloakSecurityContext) req
.getAttribute(KeycloakSecurityContext.class.getName());
AccessToken token = RSATokenVerifier.create(kc.getIdTokenString()).getToken();
if(token.isExpired()) {
response.redirect("logout url");
}
This works fine. However, in my application, I have screens where users can spending up to an hour entering info where they could be kicked out before they are finished providing for a bad user experience. There are also cases where ajax calls are being made and the response is set to redirect to a logout page causing bad behavior.
I really think I need to always inspect the expiration, but I am unsure of how to request a new token when it is expired. I appreciate any help I can get. Thank you!
You need to have access to the Refresh Token as well. Once the Access Token is expired there is little you can do. I'll leave an example from our application below.
URL url = new URL(keycloakRootURL + "/realms/" + realmName + "/protocol/openid-connect/token");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setRequestProperty("Authorization", "Basic " + clientSecret);
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
String data = "grant_type=refresh_token&refresh_token=" + refreshToken;
try (OutputStream os = conn.getOutputStream(); BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"))) {
writer.write(data);
writer.flush();
}
conn.connect();
StringBuilder responseStr;
try (BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
String inputLine;
responseStr = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
responseStr.append(inputLine);
}
}
Object obj = parser.parse(responseStr.toString());
JSONObject result = (JSONObject) obj;
accessCreationTime = System.nanoTime();
return (String) result.get("access_token");