CASC-33
support for Tomcat: more authentication mechanisms. Just need to do the abstract class now.
This commit is contained in:
parent
9ffca231a0
commit
cd3ecb8e3c
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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.
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue