package org.apereo.cas.ticket.proxy.support; import org.apereo.cas.CasProtocolConstants; import org.apereo.cas.authentication.Credential; import org.apereo.cas.authentication.HttpBasedServiceCredential; import org.apereo.cas.ticket.TicketGrantingTicket; import org.apereo.cas.ticket.UniqueTicketIdGenerator; import org.apereo.cas.ticket.proxy.ProxyGrantingTicket; import org.apereo.cas.ticket.proxy.ProxyHandler; import org.apereo.cas.util.DefaultUniqueTicketIdGenerator; import org.apereo.cas.util.http.HttpClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URL; /** * Proxy Handler to handle the default callback functionality of CAS 2.0. * <p> * The default behavior as defined in the CAS 2 Specification is to callback the * URL provided and give it a pgtIou and a pgtId. * </p> * * @author Scott Battaglia * @since 3.0.0 */ public class Cas20ProxyHandler implements ProxyHandler { private static final Logger LOGGER = LoggerFactory.getLogger(Cas20ProxyHandler.class); private static final int BUFFER_LENGTH_ADDITIONAL_CHARGE = 15; private final UniqueTicketIdGenerator uniqueTicketIdGenerator; private final HttpClient httpClient; /** * Initializes the ticket id generator to {@link DefaultUniqueTicketIdGenerator}. * @param httpClient http client * @param uniqueTicketIdGenerator ticket id generator */ public Cas20ProxyHandler(final HttpClient httpClient, final UniqueTicketIdGenerator uniqueTicketIdGenerator) { this.httpClient = httpClient; this.uniqueTicketIdGenerator = uniqueTicketIdGenerator; } @Override public String handle(final Credential credential, final TicketGrantingTicket proxyGrantingTicketId) { final HttpBasedServiceCredential serviceCredentials = (HttpBasedServiceCredential) credential; final String proxyIou = this.uniqueTicketIdGenerator.getNewTicketId(ProxyGrantingTicket.PROXY_GRANTING_TICKET_IOU_PREFIX); final URL callbackUrl = serviceCredentials.getCallbackUrl(); final String serviceCredentialsAsString = callbackUrl.toExternalForm(); final int bufferLength = serviceCredentialsAsString.length() + proxyIou.length() + proxyGrantingTicketId.getId().length() + BUFFER_LENGTH_ADDITIONAL_CHARGE; final StringBuilder stringBuffer = new StringBuilder(bufferLength) .append(serviceCredentialsAsString); if (callbackUrl.getQuery() != null) { stringBuffer.append('&'); } else { stringBuffer.append('?'); } stringBuffer.append(CasProtocolConstants.PARAMETER_PROXY_GRANTING_TICKET_IOU) .append('=') .append(proxyIou) .append('&') .append(CasProtocolConstants.PARAMETER_PROXY_GRANTING_TICKET_ID) .append('=') .append(proxyGrantingTicketId); if (this.httpClient.isValidEndPoint(stringBuffer.toString())) { LOGGER.debug("Sent ProxyIou of [{}] for service: [{}]", proxyIou, serviceCredentials); return proxyIou; } LOGGER.debug("Failed to send ProxyIou of [{}] for service: [{}]", proxyIou, serviceCredentials); return null; } @Override public boolean canHandle(final Credential credential) { return true; } }