@Override
    public Stream<? extends Ticket> getSessionsWithAttributes(final Map<String, List<Object>> queryAttributes) {
        return getTickets(ticket -> {
            if (ticket instanceof final TicketGrantingTicket ticketGrantingTicket && !ticket.isExpired()
                && ticketGrantingTicket.getAuthentication() != null) {
                val attributes = collectAndDigestTicketAttributes(ticketGrantingTicket);

                return queryAttributes.entrySet().stream().anyMatch(queryEntry -> {
                    val attributeKey = digestIdentifier(queryEntry.getKey());

                    if (attributes.containsKey(attributeKey)) {

                        val authnAttributeValues = CollectionUtils.toCollection(attributes.get(attributeKey));

                        return authnAttributeValues.stream().anyMatch(value -> {
                            val attributeValue = value.toString();
                            return queryEntry.getValue()
                                .stream()
                                .map(queryValue -> digestIdentifier(queryValue.toString()))
                                .anyMatch(attributeValue::equalsIgnoreCase);
                        });
                    }
                    return false;
                });
            }
            return false;
        });
    }
Base ticket registry class that implements common ticket-related ops.

@author Scott Battaglia
@since 3.0.0
core/cas-server-core-tickets-api/src/main/java/org/apereo/cas/ticket/registry/AbstractTicketRegistry.java