Add information about token expiry to events

Closes #28311

Signed-off-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
Alexander Schwartz 2024-03-30 12:39:05 +01:00 committed by Alexander Schwartz
parent e7a4635620
commit 0e1a7c6f8e
2 changed files with 15 additions and 0 deletions

View file

@ -100,4 +100,6 @@ public interface Details {
String LOGOUT_TRIGGERED_BY_ACTION_TOKEN = "logout_triggered_by_action_token"; String LOGOUT_TRIGGERED_BY_ACTION_TOKEN = "logout_triggered_by_action_token";
String LOGOUT_TRIGGERED_BY_REQUIRED_ACTION = "logout_triggered_by_required_action"; String LOGOUT_TRIGGERED_BY_REQUIRED_ACTION = "logout_triggered_by_required_action";
String ACCESS_TOKEN_EXPIRATION_TIME = "access_token_expiration_time";
String AGE_OF_REFRESH_TOKEN = "age_of_refresh_token";
} }

View file

@ -99,6 +99,7 @@ import org.keycloak.util.TokenUtil;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -438,6 +439,8 @@ public class TokenManager {
responseBuilder.generateIDToken().generateAccessTokenHash(); responseBuilder.generateIDToken().generateAccessTokenHash();
} }
storeRefreshTimingInformation(event, refreshToken, validation.newToken);
return responseBuilder; return responseBuilder;
} }
@ -456,6 +459,16 @@ public class TokenManager {
}; };
} }
/**
* Store information to identify early token refreshes of clients which stress the IAM system.
*/
private void storeRefreshTimingInformation(EventBuilder event, RefreshToken refreshToken, AccessToken newToken) {
long expirationAccessToken = newToken.getExp() - newToken.getIat();
long ageOfRefreshToken = newToken.getIat() - refreshToken.getIat();
event.detail(Details.ACCESS_TOKEN_EXPIRATION_TIME, Long.toString(expirationAccessToken));
event.detail(Details.AGE_OF_REFRESH_TOKEN, Long.toString(ageOfRefreshToken));
}
private void validateTokenReuseForRefresh(KeycloakSession session, RealmModel realm, RefreshToken refreshToken, private void validateTokenReuseForRefresh(KeycloakSession session, RealmModel realm, RefreshToken refreshToken,
TokenValidation validation) throws OAuthErrorException { TokenValidation validation) throws OAuthErrorException {
if (realm.isRevokeRefreshToken()) { if (realm.isRevokeRefreshToken()) {