/* vim: set ts=2 et sw=2 cindent fo=qroca: */
package com.globant.katari.login.cas;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.acegisecurity.providers.cas.TicketValidator;
import org.acegisecurity.AuthenticationServiceException;
import org.acegisecurity.BadCredentialsException;
import org.acegisecurity.providers.cas.TicketResponse;
import org.acegisecurity.Authentication;
import edu.yale.its.tp.cas.client.ProxyTicketValidator;
/** A replacement of acegisecurity CasProxyTicketValidator that allows for more
* flexible service url configuration.
*
* Cas 3.1 is supposed to be more flexible in this subject. Anyway,
* acegisecurity is not yet supporting this. This is supposed to be ready for
* version 1.1.
*
* @see ProxyTicketValidator.
*/
public class CasProxyTicketValidator implements TicketValidator,
InitializingBean {
/** The class logger.
*/
private static Logger log = LoggerFactory.getLogger(
CasProxyTicketValidator.class);
/** Builder for the cas related urls (cas login, logout, etc).
*
* This must be set with setServicesUrlBuilder before using this class.
*/
private ServicesUrlBuilder servicesUrlBuilder = null;
/** Stores the certificates that the application will trust, even if not
* signed by a well known CA.
*
* If null, we will only accept certificates from well known CAs.
*/
private String trustStore = null;
/** {@inheritDoc}
*/
public void afterPropertiesSet() throws Exception {
if ((trustStore != null) && (!"".equals(trustStore))) {
log.debug(
"Setting system property 'javax.net.ssl.trustStore' to value [{}]",
trustStore);
System.setProperty("javax.net.ssl.trustStore", trustStore);
}
}
/** Not used, always returns null.
*
* @param serviceTicket ignored.
*
* @return null.
*/
public TicketResponse confirmTicketValid(final String serviceTicket) {
return null;
}
/** Attempts to validate presented ticket using CAS' ProxyTicketValidator
* class.
*
* @param authentication the acegi authentication. This implementation needs
* an instance of FullWebAuthenticationDetails that contains the request done
* by the user. It cannot be null.
*
* @return an object representing CAS response, never null.
*/
public TicketResponse confirmTicketValid(final Authentication
authentication) {
log.trace("Entering confirmTicketValid");
// Builds the relevant url based on the request url.
FullWebAuthenticationDetails details;
details = (FullWebAuthenticationDetails) authentication.getDetails();
log.debug("URL path: {}", details.getRequest().getRequestURL());
log.debug("Query string: {}", details.getRequest().getQueryString());
log.debug("Context path: {}", details.getRequest().getContextPath());
log.debug("Path info: {}", details.getRequest().getPathInfo());
String casValidate = servicesUrlBuilder.buildCasValidatorUrl();
String service = servicesUrlBuilder.buildServiceUrl(details.getRequest());
log.debug("Cas validate url: {}", casValidate);
log.debug("Service: {}", service);
ProxyTicketValidator proxyValidator = new ProxyTicketValidator();
String serviceTicket = authentication.getCredentials().toString();
proxyValidator.setCasValidateUrl(casValidate);
proxyValidator.setServiceTicket(serviceTicket);
proxyValidator.setService(service);
/*
if (super.getServiceProperties().isSendRenew()) {
log.warn("The current CAS ProxyTicketValidator does not support the"
+ " 'renew' property. The ticket cannot be validated as having been"
+ " issued by a 'renew' authentication. It is expected this will be"
+ " corrected in a future version of CAS' ProxyTicketValidator.");
}
*/
TicketResponse response = validateNow(proxyValidator);
log.trace("Leaving confirmTicketValid");
return response;
}
/** Perform the actual remote invocation.
*
* @param pv the populated <code>ProxyTicketValidator</code>
*
* @return the <code>TicketResponse</code>
*/
private TicketResponse validateNow(final ProxyTicketValidator pv) {
try {
pv.validate();
} catch (Exception e) {
throw new AuthenticationServiceException(e.getMessage(), e);
}
if (!pv.isAuthenticationSuccesful()) {
throw new BadCredentialsException(pv.getErrorCode() + ": "
+ pv.getErrorMessage());
}
return new TicketResponse(pv.getUser(), pv.getProxyList(), pv.getPgtIou());
}
/** Sets the services url builder, an object that creates the url of the
* different services.
*
* @param urlsBuilder the services url builder. It cannot be null.
*/
public void setServicesUrlBuilder(final ServicesUrlBuilder urlsBuilder) {
servicesUrlBuilder = urlsBuilder;
}
/** Optional property which will be used to set the system property
* <code>javax.net.ssl.trustStore</code>.
*
* @return the <code>javax.net.ssl.trustStore</code> that will be set
* during bean initialization, or <code>null</code> to leave the system
* property unchanged
*/
public String getTrustStore() {
return trustStore;
}
/*** Optional property which will be used to set the system property
* <code>javax.net.ssl.trustStore</code>.
*
* @param theTrustStore the trust store, ignored if null.
*/
public void setTrustStore(final String theTrustStore) {
trustStore = theTrustStore;
}
}