support for Tomcat: more authentication mechanisms.  Just need to do the abstract class now.
This commit is contained in:
Scott Battaglia 2010-09-01 03:56:46 +00:00
parent 9ffca231a0
commit cd3ecb8e3c
9 changed files with 271 additions and 180 deletions

View File

@ -8,6 +8,8 @@ package org.jasig.cas.client.util;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.cas.client.proxy.ProxyGrantingTicketStorage;
import org.jasig.cas.client.validation.ProxyList;
import org.jasig.cas.client.validation.ProxyListEditor;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
@ -338,4 +340,14 @@ public final class CommonUtils {
throw new IllegalArgumentException(e);
}
}
public static ProxyList createProxyList(final String proxies) {
if (CommonUtils.isBlank(proxies)) {
return new ProxyList();
}
final ProxyListEditor editor = new ProxyListEditor();
editor.setAsText(proxies);
return (ProxyList) editor.getValue();
}
}

View File

@ -102,7 +102,7 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
if (CommonUtils.isNotBlank(allowAnyProxy) || CommonUtils.isNotBlank(allowedProxyChains)) {
final Cas20ProxyTicketValidator v = new Cas20ProxyTicketValidator(casServerUrlPrefix);
v.setAcceptAnyProxy(parseBoolean(allowAnyProxy));
v.setAllowedProxyChains(createProxyList(allowedProxyChains));
v.setAllowedProxyChains(CommonUtils.createProxyList(allowedProxyChains));
validator = v;
} else {
validator = new Cas20ServiceTicketValidator(casServerUrlPrefix);
@ -130,16 +130,6 @@ public class Cas20ProxyReceivingTicketValidationFilter extends AbstractTicketVal
return validator;
}
protected final ProxyList createProxyList(final String proxies) {
if (CommonUtils.isBlank(proxies)) {
return new ProxyList();
}
final ProxyListEditor editor = new ProxyListEditor();
editor.setAsText(proxies);
return (ProxyList) editor.getValue();
}
public void destroy() {
super.destroy();
this.timer.cancel();

View File

@ -0,0 +1,104 @@
package org.jasig.cas.client.tomcat;
import org.apache.catalina.authenticator.AuthenticatorBase;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.TicketValidationException;
import org.jasig.cas.client.validation.TicketValidator;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
/**
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 3.1.12
*/
public abstract class AbstractAuthenticator extends AuthenticatorBase {
private static final String INFO = "org.jasig.cas.client.tomcat.AbstractAuthenticator/1.0";
private static final Log log = LogFactory.getLog(AbstractAuthenticator.class);
private String casServerLoginUrl;
private String casServerUrlPrefix;
private boolean encode;
private boolean renew;
protected abstract String getArtifactParameterName();
protected abstract String getServiceParameterName();
protected abstract TicketValidator getTicketValidator();
private String serverName;
private String serviceUrl;
protected final String getCasServerUrlPrefix() {
return this.casServerUrlPrefix;
}
public String getInfo() {
return INFO;
}
public final boolean authenticate(final Request request, final HttpServletResponse response, final LoginConfig loginConfig) throws IOException {
final Assertion assertion = (Assertion) request.getSession(true).getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
if (assertion != null) {
return isKnownUser(assertion, request, response);
}
final String token = request.getParameter(getArtifactParameterName());
final String service = CommonUtils.constructServiceUrl(request, response, this.serviceUrl, this.serverName, getArtifactParameterName(), true);
if (CommonUtils.isBlank(token)) {
final String redirectUrl = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), service, false, false);
response.sendRedirect(redirectUrl);
return false;
}
try {
final Assertion newAssertion = getTicketValidator().validate(token, service);
request.getSession(true).setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, newAssertion);
return isKnownUser(newAssertion, request, response);
} catch (final TicketValidationException e) {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, e.getMessage());
return false;
}
}
protected boolean isKnownUser(final Assertion assertion, final Request request, final HttpServletResponse response) throws IOException {
final String userName = assertion.getPrincipal().getName();
final Principal principal = request.getUserPrincipal();
if (principal == null) {
// principal not already known; look it up via the configured realm
principal = realm.getPrincipal(userName);
if (principal != null) {
// register it so that Tomcat can reuse it without another realm lookup
register(request, response, principal, "CAS", userName, null);
}
}
if (principal == null) {
log.warn("unknown CAS user " + userName + " for "
+ request.getRequestURI());
response.sendError(Response.SC_UNAUTHORIZED);
return false;
}
request.setUserPrincipal(principal);
return true;
}
}

View File

@ -0,0 +1,49 @@
package org.jasig.cas.client.tomcat;
/**
*
*
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 3.1.12
*/
public abstract class AbstractCasAuthenticator extends AbstractAuthenticator {
private String encoding;
private String proxyCallbackUrl;
private boolean renew;
protected final String getEncoding() {
return this.encoding;
}
public final void setEncoding(final String encoding) {
this.encoding = encoding;
}
protected final String getProxyCallbackUrl() {
return this.proxyCallbackUrl;
}
public final void setProxyCallbackUrl(final String proxyCallbackUrl) {
this.proxyCallbackUrl = proxyCallbackUrl;
}
protected final boolean isRenew() {
return this.renew;
}
public void setRenew(final boolean renew) {
this.renew = renew;
}
protected final String getArtifactParameterName() {
return "ticket";
}
protected final String getServiceParameterName() {
return "Service";
}
}

View File

@ -0,0 +1,27 @@
package org.jasig.cas.client.tomcat;
import org.apache.catalina.LifecycleException;
import org.jasig.cas.client.validation.Cas10TicketValidator;
import org.jasig.cas.client.validation.TicketValidator;
/**
* Authenticator that handles CAS 1.0 responses.
*
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 3.1.12
*/
public class Cas10CasAuthenticator extends AbstractCasAuthenticator {
private TicketValidator ticketValidator;
protected TicketValidator getTicketValidator() {
return this.ticketValidator;
}
protected void startInternal() throws LifecycleException {
super.startInternal();
this.ticketValidator = new Cas10TicketValidator(getCasServerUrlPrefix());
}
}

View File

@ -0,0 +1,32 @@
package org.jasig.cas.client.tomcat;
import org.apache.catalina.LifecycleException;
import org.jasig.cas.client.validation.Cas20ServiceTicketValidator;
import org.jasig.cas.client.validation.TicketValidator;
/**
* Authenticator that handles the CAS 2 protocol.
*
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 3.1.12
*/
public final class Cas20CasAuthenticator extends AbstractCasAuthenticator {
private Cas20ServiceTicketValidator ticketValidator;
protected TicketValidator getTicketValidator() {
return this.ticketValidator;
}
protected void startInternal() throws LifecycleException {
super.startInternal();
this.ticketValidator = new Cas20ServiceTicketValidator(getCasServerUrlPrefix());
if (getEncoding() != null) {
this.ticketValidator.setEncoding(getEncoding());
}
this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl());
this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage());
this.ticketValidator.setRenew(isRenew());
}
}

View File

@ -0,0 +1,46 @@
package org.jasig.cas.client.tomcat;
import org.apache.catalina.LifecycleException;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.validation.Cas20ProxyTicketValidator;
import org.jasig.cas.client.validation.TicketValidator;
/**
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 3.1.12
*/
public final class Cas20ProxyCasAuthenticator extends AbstractCasAuthenticator {
private Cas20ProxyTicketValidator ticketValidator;
private boolean acceptAnyProxy;
private String allowedProxyChains;
public void setAcceptAnyProxy(final boolean acceptAnyProxy) {
this.acceptAnyProxy = acceptAnyProxy;
}
public void setAllowedProxyChains(final String allowedProxyChains) {
this.allowedProxyChains = allowedProxyChains;
}
protected TicketValidator getTicketValidator() {
return this.ticketValidator;
}
protected void startInternal() throws LifecycleException {
super.startInternal();
this.ticketValidator = new Cas20ProxyTicketValidator(getCasServerUrlPrefix());
this.ticketValidator.setRenew(isRenew());
this.ticketValidator.setProxyCallbackUrl(getProxyCallbackUrl());
this.ticketValidator.setProxyGrantingTicketStorage(ProxyCallbackValve.getProxyGrantingTicketStorage());
this.ticketValidator.setAcceptAnyProxy(this.acceptAnyProxy);
this.ticketValidator.setAllowedProxyChains(CommonUtils.createProxyList(this.allowedProxyChains));
if (getEncoding() != null) {
this.ticketValidator.setEncoding(getEncoding());
}
}
}

View File

@ -1,88 +0,0 @@
package org.jasig.cas.client.tomcat;
import org.apache.catalina.authenticator.AuthenticatorBase;
import org.apache.catalina.connector.Request;
import org.apache.catalina.deploy.LoginConfig;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jasig.cas.client.util.AbstractCasFilter;
import org.jasig.cas.client.util.CommonUtils;
import org.jasig.cas.client.validation.Assertion;
import org.jasig.cas.client.validation.TicketValidationException;
import org.jasig.cas.client.validation.TicketValidator;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.security.Principal;
/**
* @author Scott Battaglia
* @version $Revision$ $Date$
* @since 3.1.12
*/
public abstract class CasAuthenticator extends AuthenticatorBase {
private static final String INFO = "org.jasig.cas.client.tomcat.CasAuthenticator/1.0";
private static final Log log = LogFactory.getLog(CasAuthenticator.class);
private String serverName;
private String serviceUrl;
private String casServerLoginUrl;
private boolean encode;
private boolean renew;
protected abstract String getArtifactParameterName();
protected abstract String getServiceParameterName();
private TicketValidator ticketValidator;
public String getInfo() {
return INFO;
}
public boolean authenticate(final Request request, final HttpServletResponse httpServletResponse, final LoginConfig loginConfig) throws IOException {
final Assertion assertion = (Assertion) request.getSession(true).getAttribute(AbstractCasFilter.CONST_CAS_ASSERTION);
if (assertion != null) {
return isKnownUser(assertion);
}
return false; //To change body of implemented methods use File | Settings | File Templates.
}
protected boolean isKnownUser(final Assertion assertion) {
return true;
}
protected boolean isAuthenticatedRequest(final HttpServletRequest request, final HttpServletResponse response) throws IOException {
final String ticket = CommonUtils.safeGetParameter(request, getArtifactParameterName());
final String serviceUrl = CommonUtils.constructServiceUrl(request, response, this.serviceUrl, this.serverName, getArtifactParameterName(), this.encode);
if (CommonUtils.isBlank(ticket)) {
final String urlToRedirectTo = CommonUtils.constructRedirectUrl(this.casServerLoginUrl, getServiceParameterName(), serviceUrl, this.renew, false);
response.sendRedirect(urlToRedirectTo);
return false;
}
try {
final Assertion assertion = this.ticketValidator.validate(ticket, serviceUrl);
request.getSession(true).setAttribute(AbstractCasFilter.CONST_CAS_ASSERTION, assertion);
return isKnownUser(assertion);
} catch (final TicketValidationException e) {
return false;
}
}
}

View File

@ -1,81 +0,0 @@
package org.jasig.cas.client.tomcat;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
import org.apache.catalina.Realm;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.deploy.SecurityConstraint;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.security.Principal;
import java.security.cert.X509Certificate;
/**
* Created by IntelliJ IDEA.
* User: scottbattaglia
* Date: Jul 19, 2010
* Time: 11:11:28 PM
* To change this template use File | Settings | File Templates.
*/
public class CasRealm implements Realm {
// <description>/<version>
private static final String INFO = "org.jasig.cas.client.tomcat.CasRealm/1.0";
private Container container;
public Container getContainer() {
return this.container;
}
public void setContainer(final Container container) {
this.container = container;
}
public String getInfo() {
return INFO;
}
public void addPropertyChangeListener(PropertyChangeListener propertyChangeListener) {
//To change body of implemented methods use File | Settings | File Templates.
}
public Principal authenticate(String s, String s1) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public Principal authenticate(String s, String s1, String s2, String s3, String s4, String s5, String s6, String s7) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public Principal authenticate(X509Certificate[] x509Certificates) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
public void backgroundProcess() {
//To change body of implemented methods use File | Settings | File Templates.
}
public SecurityConstraint[] findSecurityConstraints(Request request, Context context) {
return new SecurityConstraint[0]; //To change body of implemented methods use File | Settings | File Templates.
}
public boolean hasResourcePermission(Request request, Response response, SecurityConstraint[] securityConstraints, Context context) throws IOException {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
public boolean hasRole(Principal principal, String s) {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
public boolean hasUserDataPermission(Request request, Response response, SecurityConstraint[] securityConstraints) throws IOException {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
public void removePropertyChangeListener(PropertyChangeListener propertyChangeListener) {
//To change body of implemented methods use File | Settings | File Templates.
}
}