I am developing an application with Keycloak and I would like to generate access tokens with custom lifespans. Is it possible to pass a parameter to the token generation request that specifies the desired lifespan? For example, I would like to be able to pass the parameter duration: 1000 to generate an access token that will expire in 1000 seconds.
If this is not possible, is there any workaround?
One possibility would be to create a custom claim that stores the desired lifespan. However, this would require me to write my own functions to handle the lifespan, which may not be ideal.
Another possibility mentioned in this question, is to change the default lifespan using the Admin API, but that's not the point. I want to keep this default lifespan for most tokens.
Any help would be appreciated.
I achieved the ability to establish a personalized expiration time for each access token generated by utilizing a custom claim. Within the body, along with other credentials, I included the custom claim in the form-url-encoded format.
The claim retrieves the value from the request using the specified key. Inside the org.keycloak.representations.IDToken, there exists a function called exp(long) that essentially overrides the default expiration of the keycloak realm.
Before passing the time, it needs to be converted into Unix epoch format, which is the time format used by JWT (JSON Web Tokens) for storing time.
The following code represents the implementation within the setClaim function, which is utilized for creating a custom claim. If you are unfamiliar with the process of creating a custom claim, you can refer to this article for guidance .
@Override
protected void setClaim(IDToken token, ProtocolMapperModel mappingModel,
UserSessionModel userSession, KeycloakSession keycloakSession,
ClientSessionContext clientSessionCtx) {
int claimValue = 0;
// Get encoded value from request
String encodedClaimValue = keycloakSession.getContext().getHttpRequest().getDecodedFormParameters().getFirst("custom_exp");
if (encodedClaimValue != null) {
claimValue = Integer.parseInt(org.keycloak.common.util.Encode.decode(encodedClaimValue));
// Get the current local date and time
LocalDateTime currentTime = LocalDateTime.now();
// Add minutes to the current time
LocalDateTime futureTime = currentTime.plusMinutes(claimValue);
// Convert the future time to Unix epoch timestamp
long unixEpochTimestamp = futureTime.toEpochSecond(ZoneOffset.UTC);
// Override default Expiration
token.exp(unixEpochTimestamp);
}
}