Merged DAVEW_V3.2 to HEAD

13659: Fix NTLMAuthenticationFilter to call super.afterPropertiesSet()
   13658: MOB-424: Utility to Dump JMX Data
      - new enterprise distributable jmx-dumper.jar
      - command line invocation via "java -jar jmx-dumper.jar"
      - admin web access via http://localhost:8080/alfresco/faces/jsp/admin/jmx-dumper.jsp
   13575: Preconfigured authentication stacks for alfresco, LDAP, Kerberos and NTLM. TODO: file server config.
   13493: Initial work to enable selection, configuration, testing and hot-swapping of different authentication subsystems via JMX or admin UI.
   13309: Changes to allow datasource and property configuration via JNDI
      - Move AVM catalina .jars into 3rd-party/lib/virtual-tomcat so that they don't get automatically included in the .war file and hence stop JNDI lookups from working
      - Allow JNDI lookup of datasource – use standard app server mechanisms for managing it but still fall back to 'normal' one
      - Allow properties to be overridden by JNDI env-entries as well as system properties. Including hibernate dialect ones. Web.xml can then declare required env-entries and these can be defined on deployment.
      - Rewire iBatis so that no config file edits are necessary when dialect is changed
      - Use proxy around datasource so that auto-commit is always activated for iBatis


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13668 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Dave Ward
2009-03-18 12:49:12 +00:00
parent ab582be914
commit cdfd0e7993
18 changed files with 756 additions and 238 deletions

View File

@@ -71,9 +71,16 @@ public class ContextListener implements ServletContextListener, HttpSessionListe
*/
public void contextInitialized(ServletContextEvent event)
{
// make sure that the spaces store in the repository exists
// make sure that the spaces store in the repository exists
this.servletContext = event.getServletContext();
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
// If no context has been initialised, exit silently so config changes can be made
if (ctx == null)
{
return;
}
ServiceRegistry registry = (ServiceRegistry) ctx.getBean(ServiceRegistry.SERVICE_REGISTRY);
TransactionService transactionService = registry.getTransactionService();
NodeService nodeService = registry.getNodeService();

View File

@@ -0,0 +1,79 @@
/*
* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.web.app;
import javax.servlet.ServletContextEvent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jndi.JndiTemplate;
/**
* A specialised {@link org.springframework.web.context.ContextLoaderListener} that can be disabled by a boolean
* <code>java:comp/env/properties/startup.enable</code> JNDI entry. If <code>startup.enable</code> is configured as
* false then the Spring Application Context is not created, allowing further configuration changes to be made after
* initial deployment.
*
* @author dward
*/
public class ContextLoaderListener extends org.springframework.web.context.ContextLoaderListener
{
/**
* The JNDI environment entry that controls global startup
*/
private static final String PROPERTY_ENABLE_STARTUP = "java:comp/env/properties/startup.enable";
protected final static Log log = LogFactory.getLog(ContextLoaderListener.class);
private boolean enableStartup;
public ContextLoaderListener()
{
try
{
this.enableStartup = (Boolean) new JndiTemplate().lookup(ContextLoaderListener.PROPERTY_ENABLE_STARTUP,
Boolean.class);
}
catch (Exception e)
{
this.enableStartup = true;
}
}
@Override
public void contextInitialized(ServletContextEvent event)
{
if (this.enableStartup)
{
super.contextInitialized(event);
}
else
{
ContextLoaderListener.log
.warn("The "
+ ContextLoaderListener.PROPERTY_ENABLE_STARTUP
+ " environment entry is false. Please configure the environment entries for this application and then restart the server.");
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -26,9 +26,7 @@ package org.alfresco.web.app.servlet;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
@@ -36,7 +34,9 @@ import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.web.app.Application;
import org.alfresco.config.ConfigService;
import org.alfresco.repo.web.filter.beans.DependencyInjectedFilter;
import org.alfresco.web.config.ClientConfigElement;
/**
* @author Kevin Roast
@@ -50,75 +50,55 @@ import org.alfresco.web.app.Application;
* Note that this filter is only active when the system is running in a servlet container -
* the AlfrescoFacesPortlet will be used for a JSR-168 Portal environment.
*/
public class AuthenticationFilter implements Filter
public class AuthenticationFilter implements DependencyInjectedFilter
{
/**
* @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
*/
public void init(FilterConfig config) throws ServletException
{
this.context = config.getServletContext();
}
/**
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException
{
HttpServletRequest httpReq = (HttpServletRequest)req;
HttpServletResponse httpRes = (HttpServletResponse)res;
// allow the login page to proceed
if (httpReq.getRequestURI().endsWith(getLoginPage()) == false)
{
AuthenticationStatus status =
AuthenticationHelper.authenticate(this.context, httpReq, httpRes, false);
private String loginPage;
/**
* @param configService
* the configService to set
*/
public void setConfigService(ConfigService configService)
{
ClientConfigElement clientConfig = (ClientConfigElement) configService.getGlobalConfig().getConfigElement(
ClientConfigElement.CONFIG_ELEMENT_ID);
if (clientConfig != null)
{
loginPage = clientConfig.getLoginPage();
}
}
public void doFilter(ServletContext context, ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException
{
HttpServletRequest httpReq = (HttpServletRequest) req;
HttpServletResponse httpRes = (HttpServletResponse) res;
// allow the login page to proceed
if (!httpReq.getRequestURI().endsWith(this.loginPage))
{
AuthenticationStatus status = AuthenticationHelper.authenticate(context, httpReq, httpRes, false);
if (status == AuthenticationStatus.Success || status == AuthenticationStatus.Guest)
{
// continue filter chaining
chain.doFilter(req, res);
}
else
{
// authentication failed - so end servlet execution and redirect to login page
// also save the requested URL so the login page knows where to redirect too later
BaseServlet.redirectToLoginPage(httpReq, httpRes, context);
}
}
else
{
BaseServlet.setLanguageFromRequestHeader(httpReq, context);
if (status == AuthenticationStatus.Success || status == AuthenticationStatus.Guest)
{
// continue filter chaining
chain.doFilter(req, res);
}
else
{
// authentication failed - so end servlet execution and redirect to login page
// also save the requested URL so the login page knows where to redirect too later
BaseServlet.redirectToLoginPage(httpReq, httpRes, context);
}
}
else
{
BaseServlet.setLanguageFromRequestHeader(httpReq, context);
// continue filter chaining
chain.doFilter(req, res);
}
}
/**
* @see javax.servlet.Filter#destroy()
*/
public void destroy()
{
// nothing to do
}
/**
* @return The login page url
*/
private String getLoginPage()
{
if (this.loginPage == null)
{
this.loginPage = Application.getLoginPage(this.context);
}
return this.loginPage;
}
private String loginPage = null;
private ServletContext context;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 Alfresco Software Limited.
* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -25,67 +25,24 @@
package org.alfresco.web.app.servlet;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.Principal;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import java.util.Vector;
import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import javax.security.sasl.RealmCallback;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.transaction.UserTransaction;
import org.alfresco.config.ConfigService;
import org.alfresco.filesys.ServerConfigurationBean;
import org.alfresco.i18n.I18NUtil;
import org.alfresco.jlan.server.auth.kerberos.KerberosDetails;
import org.alfresco.jlan.server.auth.kerberos.SessionSetupPrivilegedAction;
import org.alfresco.jlan.server.auth.spnego.NegTokenInit;
import org.alfresco.jlan.server.auth.spnego.NegTokenTarg;
import org.alfresco.jlan.server.auth.spnego.OID;
import org.alfresco.jlan.server.auth.spnego.SPNEGO;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.SessionUser;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.NTLMMode;
import org.alfresco.repo.webdav.auth.BaseKerberosAuthenticationFilter;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.cmr.security.PersonService;
import org.alfresco.service.transaction.TransactionService;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.LoginBean;
import org.alfresco.web.bean.repository.User;
import org.alfresco.web.config.ClientConfigElement;
import org.alfresco.web.config.LanguagesConfigElement;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.ietf.jgss.Oid;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
/**
* Kerberos Authentication Filter Class
@@ -110,36 +67,39 @@ public class KerberosAuthenticationFilter extends BaseKerberosAuthenticationFilt
// List of available locales (from the web-client configuration)
private List<String> m_languages;
private List<String> m_languages;
/**
* Initialize the filter
*
* @param args FilterConfig
* @exception ServletException
* @param configService the configService to set
*/
public void init(FilterConfig args) throws ServletException
public void setConfigService(ConfigService configService)
{
// Call the base Kerberos filter initialization
super.init( args);
// Setup the authentication context
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(m_context);
m_configService = (ConfigService)ctx.getBean("webClientConfigService");
m_configService = configService;
}
/* (non-Javadoc)
* @see org.alfresco.repo.webdav.auth.BaseKerberosAuthenticationFilter#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception
{
// Call the base Kerberos filter initialization
super.afterPropertiesSet();
// Get a list of the available locales
LanguagesConfigElement config = (LanguagesConfigElement) m_configService.
getConfig("Languages").getConfigElement(LanguagesConfigElement.CONFIG_ELEMENT_ID);
LanguagesConfigElement config = (LanguagesConfigElement) m_configService.getConfig("Languages")
.getConfigElement(LanguagesConfigElement.CONFIG_ELEMENT_ID);
m_languages = config.getLanguages();
// Set hte login page address
setLoginPage( Application.getLoginPage(m_context));
ClientConfigElement clientConfig = (ClientConfigElement) m_configService.getGlobalConfig().getConfigElement(
ClientConfigElement.CONFIG_ELEMENT_ID);
if (clientConfig != null)
{
setLoginPage(clientConfig.getLoginPage());
}
}
/* (non-Javadoc)

View File

@@ -28,8 +28,6 @@ import java.io.IOException;
import java.util.List;
import java.util.Locale;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@@ -41,11 +39,10 @@ import org.alfresco.repo.webdav.auth.BaseNTLMAuthenticationFilter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.web.app.Application;
import org.alfresco.web.bean.repository.User;
import org.alfresco.web.config.ClientConfigElement;
import org.alfresco.web.config.LanguagesConfigElement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
/**
* Web-client NTLM Authentication Filter Class
@@ -61,38 +58,42 @@ public class NTLMAuthenticationFilter extends BaseNTLMAuthenticationFilter
// Debug logging
private static Log logger = LogFactory.getLog(NTLMAuthenticationFilter.class);
// Various services required by NTLM authenticator
private ConfigService m_configService;
protected ConfigService m_configService;
// List of available locales (from the web-client configuration)
private List<String> m_languages;
/**
* Initialize the filter
*
* @param args FilterConfig
* @exception ServletException
* @param configService the configService to set
*/
public void init(FilterConfig args) throws ServletException
public void setConfigService(ConfigService configService)
{
super.init(args);
// Setup the authentication context
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(m_context);
m_configService = (ConfigService)ctx.getBean("webClientConfigService");
// Get a list of the available locales
LanguagesConfigElement config = (LanguagesConfigElement) m_configService.
getConfig("Languages").getConfigElement(LanguagesConfigElement.CONFIG_ELEMENT_ID);
m_languages = config.getLanguages();
setLoginPage( Application.getLoginPage(m_context));
m_configService = configService;
}
/* (non-Javadoc)
* @see org.alfresco.repo.webdav.auth.BaseNTLMAuthenticationFilter#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception
{
// Call the base NTLM filter initialization
super.afterPropertiesSet();
// Get a list of the available locales
LanguagesConfigElement config = (LanguagesConfigElement) m_configService.getConfig("Languages")
.getConfigElement(LanguagesConfigElement.CONFIG_ELEMENT_ID);
m_languages = config.getLanguages();
ClientConfigElement clientConfig = (ClientConfigElement) m_configService.getGlobalConfig().getConfigElement(
ClientConfigElement.CONFIG_ELEMENT_ID);
if (clientConfig != null)
{
setLoginPage(clientConfig.getLoginPage());
}
}
/* (non-Javadoc)
* @see org.alfresco.repo.webdav.auth.BaseSSOAuthenticationFilter#createUserObject(java.lang.String, java.lang.String, org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
*/
@Override

View File

@@ -27,20 +27,16 @@ package org.alfresco.web.app.servlet;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.alfresco.config.ConfigService;
import org.alfresco.util.URLDecoder;
import org.alfresco.web.scripts.Match;
import org.alfresco.web.scripts.RuntimeContainer;
import org.alfresco.web.scripts.Description.RequiredAuthentication;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
/**
* WebScript aware NTLM Authentication Filter Class.
@@ -53,45 +49,26 @@ import org.springframework.web.context.support.WebApplicationContextUtils;
*/
public class WebScriptNTLMAuthenticationFilter extends NTLMAuthenticationFilter
{
private RuntimeContainer container;
private RuntimeContainer container;
/**
* Initialize the filter
*
* @param args FilterConfig
* @exception ServletException
* @param container the container to set
*/
public void init(FilterConfig args) throws ServletException
public void setContainer(RuntimeContainer container)
{
super.init(args);
ApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(args.getServletContext());
ConfigService configService = (ConfigService)context.getBean("web.config");
String containerName = args.getInitParameter("container");
if (containerName == null)
{
containerName = "webscripts.container";
}
container = (RuntimeContainer)context.getBean(containerName);
this.container = container;
}
/**
* Run the filter
*
* @param sreq ServletRequest
* @param sresp ServletResponse
* @param chain FilterChain
*
* @exception IOException
* @exception ServletException
/* (non-Javadoc)
* @see org.alfresco.repo.webdav.auth.BaseNTLMAuthenticationFilter#doFilter(javax.servlet.ServletContext, javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
public void doFilter(ServletRequest sreq, ServletResponse sres, FilterChain chain)
throws IOException, ServletException
@Override
public void doFilter(ServletContext context, ServletRequest sreq, ServletResponse sresp, FilterChain chain)
throws IOException, ServletException
{
// Get the HTTP request/response
HttpServletRequest req = (HttpServletRequest)sreq;
HttpServletResponse res = (HttpServletResponse)sres;
// find a webscript match for the requested URI
String requestURI = req.getRequestURI();
@@ -114,6 +91,6 @@ public class WebScriptNTLMAuthenticationFilter extends NTLMAuthenticationFilter
}
}
super.doFilter(sreq, sres, chain);
super.doFilter(context, sreq, sresp, chain);
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (C) 2005-2009 Alfresco Software Limited.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* As a special exception to the terms and conditions of version 2.0 of
* the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's
* FLOSS exception. You should have received a copy of the text describing
* the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing"
*/
package org.alfresco.web.bean.jmx;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import javax.faces.context.FacesContext;
import javax.management.MBeanServerConnection;
import org.alfresco.repo.management.JmxDumpUtil;
import org.alfresco.web.app.servlet.FacesHelper;
/**
* Backing bean to allow an admin user to dump all JMX Beans and their properties.
*/
public class JmxDumperBean implements Serializable
{
private static final long serialVersionUID = -8690237774052781181L;
// supporting repository services
/** The MBean server. */
transient private MBeanServerConnection mbeanServer;
/**
* Sets the mbean server.
*
* @param mbeanServer
* the mbeanServer to set
*/
public void setMbeanServer(MBeanServerConnection mbeanServer)
{
this.mbeanServer = mbeanServer;
}
/**
* Gets the mbean server.
*
* @return the mbeanServer
*/
private MBeanServerConnection getMbeanServer()
{
if (this.mbeanServer == null)
{
this.mbeanServer = (MBeanServerConnection) FacesHelper.getManagedBean(FacesContext.getCurrentInstance(),
"alfrescoMBeanServer");
}
return this.mbeanServer;
}
/**
* Gets the command result.
*
* @return the result
* @throws IOException
* Signals that an I/O exception has occurred.
*/
public String getResult() throws IOException
{
StringWriter result = new StringWriter();
PrintWriter out = new PrintWriter(result);
JmxDumpUtil.dumpConnection(getMbeanServer(), out);
out.close();
return result.toString();
}
}