/* vim: set ts=2 et sw=2 cindent fo=qroca: */
package com.globant.katari.cas;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.Validate;
/** Builds the urls of the different application services, such as web and CAS
* related urls.
*
* The possible urls are:
*
* - The main application url (the 'service', in CAS parlance). This url
* belongs to the application that needs an authenticated user.
*
* - The url of the servlet context path of the web service.
*
* - The login url. This is served by CAS. It is the url where the main service
* is redirected if the user is not authenticated.
*
* - The cas validator url. This is served by CAS. It is used to verify if a
* token was generated by the expected server.
*
* The builder tranforms the request url to the possible services, using the
* corresponding UrlTransformer according to the service. The UrlTransformers
* tranform the url up to the context path (http://server:port/context-path).
* Once the request is tranformed, the builder appends the correct url to it
* (loginUrl, serviceUrl or casValidatorUrl).
*/
public class CasServicesUrlBuilder {
/** An identity url transformer.
*/
private static final UrlTransformer IDENTITY = new UrlTransformer();
/** The service url fragment.
*
* The service corresponds to the url that the cas authentication service
* redirects the client to after a succesful authentication. It is never
* null.
*/
private String serviceUrl;
/** The CAS login url fragment.
*
* Usually something like <code>cas/login</code>.
*/
private String loginUrl;
/** The cas ticket validator url fragment.
*
* When the service receives a ticket, it uses this url to validate that the
* ticket came from the expected web application. It is never null.
*
* Usually something like <code>cas/proxyValidate</code>.
*/
private String casValidatorUrl;
/** Url to obtain a proxy-granting ticket from CAS.
*/
// private String proxyCallbackUrl = null;
/** The url tranformer to convert the request to the cas server base url.
*
* It is never null. It defaults to the identity tranformer.
*/
private UrlTransformer casUrlTransformer = IDENTITY;
/** The url tranformer to convert the request to the web server base url.
*
* It is never null. It defaults to the identity tranformer.
*/
private UrlTransformer validatorUrlTransformer = IDENTITY;
/** Builds a new service builder.
*
* @param theCasUrlTransformer The transformer that converts the request url
* to the cas url. It can be null, in which case the cas url is the same as
* the request url.
*
* @param theValidatorUrlTransformer The transformer that converts the
* request url to the cas ticket validator url. It can be null, in which
* case the validator url is the same as the request url.
*
* @param theServiceUrl The fragment of the url that cas redirects after a
* succesful login. It cannot be null.
*
* @param theLoginUrl The fragment of the url that acegi redirects to
* authenticate a user. It cannot be null.
*
* @param theCasValidatorUrl The fragment of the url that acegi uses to
* validate a ticket. It cannot be null.
*/
public CasServicesUrlBuilder(final UrlTransformer theCasUrlTransformer, final
UrlTransformer theValidatorUrlTransformer, final String theServiceUrl,
final String theLoginUrl, final String theCasValidatorUrl) {
Validate.notNull(theServiceUrl, "The service cannot be null");
Validate.notNull(theLoginUrl, "The login url cannot be null");
Validate.notNull(theCasValidatorUrl, "The cas validator url cannot be"
+ " null");
if (theCasUrlTransformer != null) {
casUrlTransformer = theCasUrlTransformer;
}
if (theValidatorUrlTransformer != null) {
validatorUrlTransformer = theValidatorUrlTransformer;
}
serviceUrl = theServiceUrl;
loginUrl = theLoginUrl;
casValidatorUrl = theCasValidatorUrl;
}
/** Builds the application service url.
*
* Usually something like
* <code>http://..../j_acegi_cas_security_check</code>. This is the url that
* cas redirects to after a successful login.
*
* @param request The http request object use to construct the full service
* url. It cannot be null.
*
* @return the service url. It never returns null.
*/
public String buildServiceUrl(final HttpServletRequest request) {
Validate.notNull(request, "The request cannot be null");
return createUrl(createServiceBaseUrl(request), serviceUrl);
}
/** Builds the CAS login full URL.
*
* Usually something like <code>http://..../cas/login</code>.
*
* @param request The http request object use to construct the full service
* url. It cannot be null.
*
* @return the login URL. It never returns null.
*/
public String buildLoginUrl(final HttpServletRequest request) {
Validate.notNull(request, "The request cannot be null");
return createUrl(casUrlTransformer.transform(request.getScheme(),
request.getServerName(), request.getServerPort(),
request.getContextPath()), loginUrl);
}
/** Builds the CAS ticket validator full URL.
*
* Usually something like <code>http://..../cas/proxyValidate</code>. It is
* used to verify if a ticket was generated by the expected cas server.
*
* @param request The http request object use to construct the full service
* url. It cannot be null.
*
* @return the login URL. It never returns null.
*/
public String buildCasValidatorUrl(final HttpServletRequest request) {
Validate.notNull(request, "The request cannot be null");
return createUrl(validatorUrlTransformer.transform(request.getScheme(),
request.getServerName(), request.getServerPort(),
request.getContextPath()), casValidatorUrl);
}
/** Optional callback URL to obtain a proxy-granting ticket from CAS.
*
* <P>This callback URL belongs to the Acegi Security System for Spring
* secured application. We suggest you use CAS'
* <code>ProxyTicketReceptor</code> servlet to receive this callback and
* manage the proxy-granting ticket list. The callback URL is usually
* something like
* <code>https://www.mycompany.com/application/casProxy/receptor</code>.</p>
* <P>If left <code>null</code>, the <code>CasAuthenticationToken</code> will
* not have a proxy granting ticket IOU and there will be no proxy-granting
* ticket callback. Accordingly, the Acegi Securty System for Spring secured
* application will be unable to obtain a proxy ticket to call another
* CAS-secured service on behalf of the user. This is not really an issue for
* most applications.</p>
*
* @param request The http request object used to construct the full proxy
* callback url.
*
* @return the proxy callback URL. This implementation always returns null.
*/
public String buildProxyCallbackUrl(final HttpServletRequest request) {
return null;
}
/*
public String buildProxyCallbackUrl(final HttpServletRequest request) {
String url = null;
if (proxyCallbackUrl != null && (!"".equals(proxyCallbackUrl))) {
url = casUrlTransformer.transform(request.getScheme(),
request.getServerName(), request.getServerPort(),
request.getContextPath());
// url = createUrl(createCasBaseUrl(request),
//proxyCallbackUrl).toString();
url += proxyCallbackUrl;
}
return url;
}
*/
/** Builds the web url.
*
* @param request The http request object used to construct the full proxy
* callback url.
*
* @return the web URL, or <code>null</code> if not used
*/
/*
public String buildWebUrl(final HttpServletRequest request) {
return validatorUrlTransformer.transform(request.getScheme(),
request.getServerName(), request.getServerPort(),
request.getContextPath());
}
*/
/** Creates the base url for the service (current web application) from the
* provided request.
*
* @param request The http request object. It cannot be null.
*
* @return Returns a url that can be used to build the urls of the service.
*/
private String createServiceBaseUrl(final HttpServletRequest request) {
Validate.notNull(request, "The request cannot be null");
return createUrl(request.getScheme() + "://" + request.getServerName()
+ ":" + request.getServerPort(), request.getContextPath());
}
/** Creates a new url based on a base url and a path fragment.
*
* @param base The base url. It cannot be null.
*
* @param path The path fragment. It cannot be null.
*
* @return Returns the new url formed by the concatenation of the base url
* and the path fragment, including the '/' if necessary.
*/
private String createUrl(final String base, final String path) {
Validate.notNull(base, "The base url cannot be null");
Validate.notNull(path, "The path fragment cannot be null");
String result = base;
if (!result.endsWith("/") && !path.startsWith("/")) {
result += "/";
}
result += path;
return result;
}
}