NIHVIVO-1207 Move all of the configurable operations of external authentication into ExternalAuthHelper.

This commit is contained in:
jeb228 2010-11-18 22:12:31 +00:00
parent 6b874e59ab
commit 32e2a1ae29
8 changed files with 105 additions and 102 deletions

View file

@ -35,7 +35,7 @@ public class FakeSelfEditingIdentifierFactory implements IdentifierBundleFactory
NetId netIdToken = new NetId(netid); NetId netIdToken = new NetId(netid);
ib.add(netIdToken); ib.add(netIdToken);
ExternalAuthHelper helper = ExternalAuthHelper.getBean(request); ExternalAuthHelper helper = ExternalAuthHelper.getHelper(request);
String uri = helper.getIndividualUriFromNetId(wdf.getIndividualDao(), netid); String uri = helper.getIndividualUriFromNetId(wdf.getIndividualDao(), netid);
if( uri != null ){ if( uri != null ){
Individual ind = wdf.getIndividualDao().getIndividualByURI(uri); Individual ind = wdf.getIndividualDao().getIndividualByURI(uri);

View file

@ -115,7 +115,7 @@ public class SelfEditingIdentifierFactory implements IdentifierBundleFactory {
IndividualDao indDao = wdf.getIndividualDao(); IndividualDao indDao = wdf.getIndividualDao();
ExternalAuthHelper helper = ExternalAuthHelper.getBean(request); ExternalAuthHelper helper = ExternalAuthHelper.getHelper(request);
String uri = helper.getIndividualUriFromNetId(indDao, username); String uri = helper.getIndividualUriFromNetId(indDao, username);
if (uri == null) { if (uri == null) {
log.debug("could not find an Individual with a netId of " log.debug("could not find an Individual with a netId of "

View file

@ -389,7 +389,7 @@ public class EntityController extends VitroHttpServlet {
if (netIdStr==null || netIdStr.equals("")) if (netIdStr==null || netIdStr.equals(""))
netIdStr = vreq.getParameter("netid"); netIdStr = vreq.getParameter("netid");
if ( netIdStr != null ){ if ( netIdStr != null ){
uri = ExternalAuthHelper.getBean(vreq).getIndividualUriFromNetId(iwDao, netIdStr); uri = ExternalAuthHelper.getHelper(vreq).getIndividualUriFromNetId(iwDao, netIdStr);
return iwDao.getIndividualByURI(uri); return iwDao.getIndividualByURI(uri);
} }

View file

@ -20,6 +20,10 @@ import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.Messag
public class BaseLoginServlet extends HttpServlet { public class BaseLoginServlet extends HttpServlet {
private static final Log log = LogFactory.getLog(BaseLoginServlet.class); private static final Log log = LogFactory.getLog(BaseLoginServlet.class);
/** A general purpose error message for the user to see. */
protected static final Message MESSAGE_LOGIN_FAILED = new LoginProcessBean.Message(
"External login failed.", LoginProcessBean.MLevel.ERROR);
protected Authenticator getAuthenticator(HttpServletRequest req) { protected Authenticator getAuthenticator(HttpServletRequest req) {
return Authenticator.getInstance(req); return Authenticator.getInstance(req);
} }

View file

@ -2,6 +2,9 @@
package edu.cornell.mannlib.vitro.webapp.controller.authenticate; package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.servlet.ServletRequest; import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
@ -14,7 +17,7 @@ import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
/** /**
* Capture the properties used by the External Authorization system, and use * Capture the properties used by the External Authorization system, and use
* them in common ways. * them to assist in the process.
* *
* The first time this bean is requested, it is created from the configuration * The first time this bean is requested, it is created from the configuration
* properties and cached in the session. After that, the cached version is used. * properties and cached in the session. After that, the cached version is used.
@ -23,16 +26,19 @@ public class ExternalAuthHelper {
private static final Log log = LogFactory.getLog(ExternalAuthHelper.class); private static final Log log = LogFactory.getLog(ExternalAuthHelper.class);
private static final ExternalAuthHelper DUMMY_HELPER = new ExternalAuthHelper( private static final ExternalAuthHelper DUMMY_HELPER = new ExternalAuthHelper(
null); null, null, null);
private static final String BEAN_ATTRIBUTE = ExternalAuthHelper.class private static final String BEAN_ATTRIBUTE = ExternalAuthHelper.class
.getName(); .getName();
/** /** This configuration property points to the external authorization server. */
* The configuration property that tells us what property associates an private static final String PROPERTY_EXTERNAL_AUTH_SERVER_URL = "externalAuth.serverUrl";
* Individual with a NetID
*/ /** This configuration property says what ties an Individual to a NetID */
private static final String PROPERTY_NETID_MATCHING_PROPERTY = "externalAuth.netidMatchingProperty"; private static final String PROPERTY_NETID_MATCHING_RELATION = "externalAuth.netidMatchingProperty";
/** This configuration property says which HTTP header holds the username. */
public static final String PROPERTY_EXTERNAL_AUTH_USERNAME_HEADER = "externalAuth.headerName";
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
// static methods // static methods
@ -44,7 +50,7 @@ public class ExternalAuthHelper {
* *
* Never returns null. * Never returns null.
*/ */
public static ExternalAuthHelper getBean(ServletRequest request) { public static ExternalAuthHelper getHelper(ServletRequest request) {
if (!(request instanceof HttpServletRequest)) { if (!(request instanceof HttpServletRequest)) {
log.trace("Not an HttpServletRequest: " + request); log.trace("Not an HttpServletRequest: " + request);
return DUMMY_HELPER; return DUMMY_HELPER;
@ -69,11 +75,15 @@ public class ExternalAuthHelper {
} }
private static ExternalAuthHelper buildBean() { private static ExternalAuthHelper buildBean() {
// TODO the ConfigurationProperties should be attached to the
// ServletContext.
String netidMatchingPropertyUri = ConfigurationProperties String netidMatchingPropertyUri = ConfigurationProperties
.getProperty(PROPERTY_NETID_MATCHING_PROPERTY); .getProperty(PROPERTY_NETID_MATCHING_RELATION);
return new ExternalAuthHelper(netidMatchingPropertyUri); String externalAuthServerUrl = ConfigurationProperties
.getProperty(PROPERTY_EXTERNAL_AUTH_SERVER_URL);
String externalAuthHeaderName = ConfigurationProperties
.getProperty(PROPERTY_EXTERNAL_AUTH_USERNAME_HEADER);
return new ExternalAuthHelper(netidMatchingPropertyUri,
externalAuthServerUrl, externalAuthHeaderName);
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@ -81,12 +91,21 @@ public class ExternalAuthHelper {
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
private final String netidMatchingPropertyUri; private final String netidMatchingPropertyUri;
private final String externalAuthServerUrl;
private final String externalAuthHeaderName;
public ExternalAuthHelper(String netidMatchingPropertyUri) { private ExternalAuthHelper(String netidMatchingPropertyUri,
if (netidMatchingPropertyUri == null) { String externalAuthServerUrl, String externalAuthHeaderName) {
this.netidMatchingPropertyUri = null; this.netidMatchingPropertyUri = trimThis(netidMatchingPropertyUri);
this.externalAuthServerUrl = trimThis(externalAuthServerUrl);
this.externalAuthHeaderName = trimThis(externalAuthHeaderName);
}
private String trimThis(String string) {
if (string == null) {
return null;
} else { } else {
this.netidMatchingPropertyUri = netidMatchingPropertyUri.trim(); return string.trim();
} }
} }
@ -107,10 +126,54 @@ public class ExternalAuthHelper {
return uri; return uri;
} }
public String buildExternalAuthRedirectUrl(String returnUrl) {
if (returnUrl == null) {
log.error("returnUrl is null.");
return null;
}
if (externalAuthServerUrl == null) {
log.error("User asked for external authentication, "
+ "but deploy.properties doesn't contain a value for '"
+ PROPERTY_EXTERNAL_AUTH_SERVER_URL + "'");
return null;
}
try {
String encodedReturnUrl = URLEncoder.encode(returnUrl, "UTF-8");
String externalAuthUrl = externalAuthServerUrl + "?target="
+ encodedReturnUrl;
log.debug("externalAuthUrl is '" + externalAuthUrl + "'");
return externalAuthUrl;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e); // No UTF-8? Really?
}
}
public String getExternalUsername(HttpServletRequest request) {
if (request == null) {
log.error("request is null.");
return null;
}
if (externalAuthHeaderName == null) {
log.error("User asked for external authentication, "
+ "but deploy.properties doesn't contain a value for '"
+ PROPERTY_EXTERNAL_AUTH_USERNAME_HEADER + "'");
return null;
}
String username = request.getHeader(externalAuthHeaderName);
log.debug("username=" + username);
return username;
}
@Override @Override
public String toString() { public String toString() {
return "ExternalAuthHelper[netidMatchingPropertyUri=" return "ExternalAuthHelper[netidMatchingPropertyUri="
+ netidMatchingPropertyUri + "]"; + netidMatchingPropertyUri + ", externalAuthServerUrl="
+ externalAuthServerUrl + ", externalAuthHeaderName="
+ externalAuthHeaderName + "]";
} }
} }

View file

@ -13,10 +13,8 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.Message;
import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao;
/** /**
@ -27,27 +25,7 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
private static final Log log = LogFactory private static final Log log = LogFactory
.getLog(LoginExternalAuthReturn.class); .getLog(LoginExternalAuthReturn.class);
/* This configuration property tells us what header contains the username. */
public static final String PROPERTY_EXTERNAL_AUTH_USERNAME_HEADER = "externalAuth.headerName";
/** The complaint we make if there is no such property. */
private static final Message MESSAGE_NO_EXTERNAL_AUTH_USERNAME = new LoginProcessBean.Message(
"deploy.properties doesn't contain a value for '"
+ PROPERTY_EXTERNAL_AUTH_USERNAME_HEADER + "'",
LoginProcessBean.MLevel.ERROR);
private static final Message MESSAGE_LOGIN_FAILED = new LoginProcessBean.Message(
"External login failed.", LoginProcessBean.MLevel.ERROR);
private final LoginRedirector loginRedirector = new LoginRedirector(); private final LoginRedirector loginRedirector = new LoginRedirector();
private String externalAuthUsernameHeader;
/** Get the configuration properties. */
@Override
public void init() throws ServletException {
externalAuthUsernameHeader = ConfigurationProperties
.getProperty(PROPERTY_EXTERNAL_AUTH_USERNAME_HEADER);
}
/** /**
* <pre> * <pre>
@ -65,13 +43,7 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
@Override @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { throws ServletException, IOException {
if (externalAuthUsernameHeader == null) { String username = ExternalAuthHelper.getHelper(req).getExternalUsername(req);
complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER,
MESSAGE_NO_EXTERNAL_AUTH_USERNAME);
return;
}
String username = req.getHeader(externalAuthUsernameHeader);
String uri = getAssociatedIndividualUri(username, req); String uri = getAssociatedIndividualUri(username, req);
if (username == null) { if (username == null) {
@ -101,7 +73,7 @@ public class LoginExternalAuthReturn extends BaseLoginServlet {
} }
IndividualDao indDao = new VitroRequest(req).getWebappDaoFactory() IndividualDao indDao = new VitroRequest(req).getWebappDaoFactory()
.getIndividualDao(); .getIndividualDao();
return ExternalAuthHelper.getBean(req).getIndividualUriFromNetId( return ExternalAuthHelper.getHelper(req).getIndividualUriFromNetId(
indDao, username); indDao, username);
} }

View file

@ -3,8 +3,6 @@
package edu.cornell.mannlib.vitro.webapp.controller.authenticate; package edu.cornell.mannlib.vitro.webapp.controller.authenticate;
import java.io.IOException; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Enumeration; import java.util.Enumeration;
import javax.servlet.ServletException; import javax.servlet.ServletException;
@ -14,9 +12,7 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import edu.cornell.mannlib.vitro.webapp.ConfigurationProperties;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean; import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean;
import edu.cornell.mannlib.vitro.webapp.controller.login.LoginProcessBean.Message;
/** /**
* Set up the external authorization process. * Set up the external authorization process.
@ -39,30 +35,6 @@ public class LoginExternalAuthSetup extends BaseLoginServlet {
/** This http header holds the referring page. */ /** This http header holds the referring page. */
private static final String HEADING_REFERRER = "referer"; private static final String HEADING_REFERRER = "referer";
/**
* The configuration property that points to the external authorization
* server.
*/
private static final String PROPERTY_EXTERNAL_AUTH_SERVER_URL = "externalAuth.serverUrl";
/**
* The complaint we make if there is no external authorization server
* property.
*/
private static final Message MESSAGE_NO_EXTERNAL_AUTH_SERVER = new LoginProcessBean.Message(
"deploy.properties doesn't contain a value for '"
+ PROPERTY_EXTERNAL_AUTH_SERVER_URL + "'",
LoginProcessBean.MLevel.ERROR);
private String extrnalAuthServerUrl;
/** Get the configuration property. */
@Override
public void init() throws ServletException {
extrnalAuthServerUrl = ConfigurationProperties
.getProperty(PROPERTY_EXTERNAL_AUTH_SERVER_URL);
}
/** /**
* Write down the referring page, record that we are logging in, and * Write down the referring page, record that we are logging in, and
* redirect to the external authorization server URL. * redirect to the external authorization server URL.
@ -72,18 +44,19 @@ public class LoginExternalAuthSetup extends BaseLoginServlet {
throws ServletException, IOException { throws ServletException, IOException {
storeTheReferringPage(req); storeTheReferringPage(req);
if (extrnalAuthServerUrl == null) {
log.debug("No external authorization server in deploy.properties");
complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER,
MESSAGE_NO_EXTERNAL_AUTH_SERVER);
return;
}
LoginProcessBean.getBean(req).setState( LoginProcessBean.getBean(req).setState(
LoginProcessBean.State.LOGGING_IN); LoginProcessBean.State.LOGGING_IN);
log.debug("Sending to external authorization server."); String returnUrl = buildReturnUrl(req);
resp.sendRedirect(buildExternalAuthRedirectUrl(req)); ExternalAuthHelper helper = ExternalAuthHelper.getHelper(req);
String redirectUrl = helper.buildExternalAuthRedirectUrl(returnUrl);
if (redirectUrl == null) {
complainAndReturnToReferrer(req, resp, ATTRIBUTE_REFERRER,
MESSAGE_LOGIN_FAILED);
}
resp.sendRedirect(redirectUrl);
} }
/** Remember where we came from - we'll need to go back there. */ /** Remember where we came from - we'll need to go back there. */
@ -97,18 +70,9 @@ public class LoginExternalAuthSetup extends BaseLoginServlet {
req.getSession().setAttribute(ATTRIBUTE_REFERRER, referrer); req.getSession().setAttribute(ATTRIBUTE_REFERRER, referrer);
} }
/** How do we get to the external authorization server and back? */ /** What is the URL of the LoginExternalAuthReturn servlet? */
private String buildExternalAuthRedirectUrl(HttpServletRequest req) { private String buildReturnUrl(HttpServletRequest req) {
try { return figureHomePageUrl(req) + RETURN_SERVLET_URL;
String returnUrl = figureHomePageUrl(req) + RETURN_SERVLET_URL;
String encodedReturnUrl = URLEncoder.encode(returnUrl, "UTF-8");
String externalAuthUrl = extrnalAuthServerUrl + "?target="
+ encodedReturnUrl;
log.debug("externalAuthUrl is '" + externalAuthUrl + "'");
return externalAuthUrl;
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e); // No UTF-8? Really?
}
} }
private void dumpRequestHeaders(HttpServletRequest req) { private void dumpRequestHeaders(HttpServletRequest req) {

View file

@ -366,7 +366,7 @@ public class IndividualController extends FreemarkerHttpServlet {
if (netIdStr==null || netIdStr.equals("")) if (netIdStr==null || netIdStr.equals(""))
netIdStr = vreq.getParameter("netid"); netIdStr = vreq.getParameter("netid");
if ( netIdStr != null ){ if ( netIdStr != null ){
uri = ExternalAuthHelper.getBean(vreq).getIndividualUriFromNetId(iwDao, netIdStr); uri = ExternalAuthHelper.getHelper(vreq).getIndividualUriFromNetId(iwDao, netIdStr);
return iwDao.getIndividualByURI(uri); return iwDao.getIndividualByURI(uri);
} }