protected void trackAuthenticationPrincipal(final Ticket ticket) {
        val userId = digestIdentifier(getPrincipalIdFrom(ticket));
        if (StringUtils.isNotBlank(userId) && ticket instanceof TicketGrantingTicket) {
            val generator = redisKeyGeneratorFactory.getRedisKeyGenerator(Principal.class.getName()).orElseThrow();
            val redisPrincipalPattern = generator.forId(userId);
            val ops = casRedisTemplates.getSessionsRedisTemplate().boundZSetOps(redisPrincipalPattern);
            val now = Instant.now(Clock.systemUTC());
            if (casProperties.getTicket().getTgt().getCore().isOnlyTrackMostRecentSession()) {
                ops.expireAt(now);
            } else {
                ops.removeRangeByScore(0, Long.valueOf(now.getEpochSecond()).doubleValue() + 1);
            }
            val timeout = RedisKeyGenerator.getTicketExpirationInSeconds(ticket);
            val digestedId = digestIdentifier(ticket.getId());
            ops.add(digestedId, Long.valueOf(now.getEpochSecond() + timeout).doubleValue());

            if (ticket.getExpirationPolicy() instanceof final IdleExpirationPolicy iep) {
                ops.expireAt(iep.getIdleExpirationTime(ticket).toInstant());
            } else {
                ops.expire(timeout, TimeUnit.SECONDS);
            }
        }
    }
Key-value ticket registry implementation that stores tickets in redis.

@author Misagh Moayyed
@author Jerome Leleu
@since 5.1.0
support/cas-server-support-redis-ticket-registry/src/main/java/org/apereo/cas/ticket/registry/RedisTicketRegistry.java