package org.apereo.cas.ticket.factory; import org.apereo.cas.CipherExecutor; import org.apereo.cas.authentication.principal.Service; import org.apereo.cas.ticket.ExpirationPolicy; import org.apereo.cas.ticket.Ticket; import org.apereo.cas.ticket.TicketFactory; import org.apereo.cas.ticket.UniqueTicketIdGenerator; import org.apereo.cas.ticket.proxy.ProxyGrantingTicket; import org.apereo.cas.ticket.proxy.ProxyTicket; import org.apereo.cas.ticket.proxy.ProxyTicketFactory; import org.apereo.cas.util.DefaultUniqueTicketIdGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Map; /** * The {@link DefaultProxyTicketFactory} is responsible for * creating {@link ProxyTicket} objects. * * @author Misagh Moayyed * @since 4.2 */ public class DefaultProxyTicketFactory implements ProxyTicketFactory { private static final Logger LOGGER = LoggerFactory.getLogger(DefaultProxyTicketFactory.class); /** * Default instance for the ticket id generator. */ private final UniqueTicketIdGenerator defaultTicketIdGenerator = new DefaultUniqueTicketIdGenerator(); /** * Map to contain the mappings of service to {@link UniqueTicketIdGenerator}s. */ private final Map<String, UniqueTicketIdGenerator> uniqueTicketIdGeneratorsForService; /** * ExpirationPolicy for Service Tickets. */ private final ExpirationPolicy proxyTicketExpirationPolicy; private final CipherExecutor<String, String> cipherExecutor; private final boolean onlyTrackMostRecentSession; public DefaultProxyTicketFactory(final ExpirationPolicy expirationPolicy, final Map<String, UniqueTicketIdGenerator> ticketIdGenerators, final CipherExecutor<String, String> cipherExecutor, final boolean onlyTrackMostRecentSession) { this.proxyTicketExpirationPolicy = expirationPolicy; this.uniqueTicketIdGeneratorsForService = ticketIdGenerators; this.cipherExecutor = cipherExecutor; this.onlyTrackMostRecentSession = onlyTrackMostRecentSession; } @Override public <T extends Ticket> T create(final ProxyGrantingTicket proxyGrantingTicket, final Service service) { final String ticketId = produceTicketIdentifier(service); return produceTicket(proxyGrantingTicket, service, ticketId); } /** * Produce ticket. * * @param <T> the type parameter * @param proxyGrantingTicket the proxy granting ticket * @param service the service * @param ticketId the ticket id * @return the ticket */ protected <T extends Ticket> T produceTicket(final ProxyGrantingTicket proxyGrantingTicket, final Service service, final String ticketId) { final ProxyTicket serviceTicket = proxyGrantingTicket.grantProxyTicket( ticketId, service, this.proxyTicketExpirationPolicy, this.onlyTrackMostRecentSession); return (T) serviceTicket; } /** * Produce ticket identifier. * * @param service the service * @return the ticket id */ protected String produceTicketIdentifier(final Service service) { final String uniqueTicketIdGenKey = service.getClass().getName(); LOGGER.debug("Looking up ticket id generator for [{}]", uniqueTicketIdGenKey); UniqueTicketIdGenerator generator = this.uniqueTicketIdGeneratorsForService.get(uniqueTicketIdGenKey); if (generator == null) { generator = this.defaultTicketIdGenerator; LOGGER.debug("Ticket id generator not found for [{}]. Using the default generator...", uniqueTicketIdGenKey); } String ticketId = generator.getNewTicketId(ProxyTicket.PROXY_TICKET_PREFIX); if (this.cipherExecutor != null) { LOGGER.debug("Attempting to encode proxy ticket [{}]", ticketId); ticketId = this.cipherExecutor.encode(ticketId); LOGGER.debug("Encoded proxy ticket id [{}]", ticketId); } return ticketId; } @Override public <T extends TicketFactory> T get(final Class<? extends Ticket> clazz) { return (T) this; } }