mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-14 17:58:59 +00:00
Refactor subsystems for authentication chaining
- An authentication chain of size 1 configured by default - DefaultChildApplicationContextManager supports dynamic configuration of the authentication chain via Spring or JMX. Any number of instances of any type allowed in chain. - SubsystemChainingAuthenticationComponent and SubsystemChainingAuthenticationService iterate across configured chain for Authentication - SSO (NTLM / Kerberos) and CIFS authentication independently activatable for any component in chain (where supported). - SubsystemChainingProxyFactory used to proxy directly to first active CIFS authenticator or SSO filter in the chain - CIFS server knows not to bother starting if authentication chain doesn't have an active CIFS authenticator (e.g. LDAP only) - Rationalization of subsystem configuration folder structure and JMX object naming - Classpath based extension mechanism for community edition - alfresco/extension/subsystems/<category>/<typeName>/<id>/*.properties in classpath can be used to configure specific subsystem instances - Simplification of JMX infrastructure. No longer Spring bean definition based, thus allowing dynamic creation/registration of new instances at runtime. - New AuthenticationChainTest unit test git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@14030 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -32,14 +32,37 @@ import javax.servlet.ServletException;
|
|||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
|
|
||||||
|
import org.alfresco.repo.management.subsystems.ActivateableBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Benign filter that does nothing more than invoke the filter chain. Allows strategic points of the filter chain to
|
* A Benign filter that does nothing more than invoke the filter chain. Allows strategic points of the filter chain to
|
||||||
* be configured in and out according to the authentication subsystem in use.
|
* be configured in and out according to the authentication subsystem in use.
|
||||||
*
|
*
|
||||||
* @author dward
|
* @author dward
|
||||||
*/
|
*/
|
||||||
public class NullFilter implements DependencyInjectedFilter
|
public class NullFilter implements DependencyInjectedFilter, ActivateableBean
|
||||||
{
|
{
|
||||||
|
private boolean isActive = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activates or deactivates the bean
|
||||||
|
*
|
||||||
|
* @param active
|
||||||
|
* <code>true</code> if the bean is active and initialization should complete
|
||||||
|
*/
|
||||||
|
public void setActive(boolean active)
|
||||||
|
{
|
||||||
|
this.isActive = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.management.subsystems.ActivateableBean#isActive()
|
||||||
|
*/
|
||||||
|
public boolean isActive()
|
||||||
|
{
|
||||||
|
return this.isActive;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.alfresco.repo.web.filter.beans.DependencyInjectedFilter#doFilter(javax.servlet.ServletContext,
|
* @see org.alfresco.repo.web.filter.beans.DependencyInjectedFilter#doFilter(javax.servlet.ServletContext,
|
||||||
@@ -50,4 +73,6 @@ public class NullFilter implements DependencyInjectedFilter
|
|||||||
{
|
{
|
||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -60,6 +60,7 @@ import org.alfresco.repo.security.authentication.AuthenticationException;
|
|||||||
import org.alfresco.repo.security.authentication.MD4PasswordEncoder;
|
import org.alfresco.repo.security.authentication.MD4PasswordEncoder;
|
||||||
import org.alfresco.repo.security.authentication.MD4PasswordEncoderImpl;
|
import org.alfresco.repo.security.authentication.MD4PasswordEncoderImpl;
|
||||||
import org.alfresco.repo.security.authentication.NTLMMode;
|
import org.alfresco.repo.security.authentication.NTLMMode;
|
||||||
|
import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator;
|
||||||
import org.alfresco.repo.security.authentication.ntlm.NTLMPassthruToken;
|
import org.alfresco.repo.security.authentication.ntlm.NTLMPassthruToken;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@@ -114,6 +115,9 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication
|
|||||||
|
|
||||||
// Disable NTLMv2 support
|
// Disable NTLMv2 support
|
||||||
private boolean m_disableNTLMv2 = false;
|
private boolean m_disableNTLMv2 = false;
|
||||||
|
|
||||||
|
// SSO enabled authentication component (required)
|
||||||
|
private NLTMAuthenticator nltmAuthenticator;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,8 +139,13 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication
|
|||||||
|
|
||||||
// Check that the authentication component supports the required mode
|
// Check that the authentication component supports the required mode
|
||||||
|
|
||||||
if (authenticationComponent.getNTLMMode() != NTLMMode.MD4_PROVIDER &&
|
if (!(authenticationComponent instanceof NLTMAuthenticator))
|
||||||
authenticationComponent.getNTLMMode() != NTLMMode.PASS_THROUGH)
|
{
|
||||||
|
throw new ServletException("Authentication component does not support NTLM");
|
||||||
|
}
|
||||||
|
this.nltmAuthenticator = (NLTMAuthenticator)this.authenticationComponent;
|
||||||
|
if (nltmAuthenticator.getNTLMMode() != NTLMMode.MD4_PROVIDER &&
|
||||||
|
nltmAuthenticator.getNTLMMode() != NTLMMode.PASS_THROUGH)
|
||||||
{
|
{
|
||||||
throw new ServletException("Required authentication mode not available");
|
throw new ServletException("Required authentication mode not available");
|
||||||
}
|
}
|
||||||
@@ -154,7 +163,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication
|
|||||||
// Set the NTLM flags depending on the authentication component supporting MD4 passwords,
|
// Set the NTLM flags depending on the authentication component supporting MD4 passwords,
|
||||||
// or is using passthru auth
|
// or is using passthru auth
|
||||||
|
|
||||||
if (authenticationComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER && m_disableNTLMv2 == false)
|
if (nltmAuthenticator.getNTLMMode() == NTLMMode.MD4_PROVIDER && m_disableNTLMv2 == false)
|
||||||
{
|
{
|
||||||
// Allow the client to use an NTLMv2 logon
|
// Allow the client to use an NTLMv2 logon
|
||||||
|
|
||||||
@@ -388,7 +397,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication
|
|||||||
byte[] challenge = null;
|
byte[] challenge = null;
|
||||||
NTLMPassthruToken authToken = null;
|
NTLMPassthruToken authToken = null;
|
||||||
|
|
||||||
if (authenticationComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
if (nltmAuthenticator.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
||||||
{
|
{
|
||||||
// Generate a random 8 byte challenge
|
// Generate a random 8 byte challenge
|
||||||
|
|
||||||
@@ -411,7 +420,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication
|
|||||||
authToken = new NTLMPassthruToken(domain);
|
authToken = new NTLMPassthruToken(domain);
|
||||||
|
|
||||||
// Run the first stage of the passthru authentication to get the challenge
|
// Run the first stage of the passthru authentication to get the challenge
|
||||||
authenticationComponent.authenticate(authToken);
|
nltmAuthenticator.authenticate(authToken);
|
||||||
|
|
||||||
// Get the challenge from the token
|
// Get the challenge from the token
|
||||||
if (authToken.getChallenge() != null)
|
if (authToken.getChallenge() != null)
|
||||||
@@ -531,7 +540,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Check if we are using local MD4 password hashes or passthru authentication
|
// Check if we are using local MD4 password hashes or passthru authentication
|
||||||
if (authenticationComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
if (nltmAuthenticator.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
||||||
{
|
{
|
||||||
// Check if guest logons are allowed and this is a guest logon
|
// Check if guest logons are allowed and this is a guest logon
|
||||||
if (m_allowGuest && userName.equalsIgnoreCase(authenticationComponent.getGuestUserName()))
|
if (m_allowGuest && userName.equalsIgnoreCase(authenticationComponent.getGuestUserName()))
|
||||||
@@ -594,7 +603,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Run the second stage of the passthru authentication
|
// Run the second stage of the passthru authentication
|
||||||
authenticationComponent.authenticate(authToken);
|
nltmAuthenticator.authenticate(authToken);
|
||||||
authenticated = true;
|
authenticated = true;
|
||||||
|
|
||||||
// Check if the user has been logged on as guest
|
// Check if the user has been logged on as guest
|
||||||
@@ -1005,7 +1014,7 @@ public abstract class BaseNTLMAuthenticationFilter extends BaseSSOAuthentication
|
|||||||
tx.begin();
|
tx.begin();
|
||||||
|
|
||||||
// Get the stored MD4 hashed password for the user, or null if the user does not exist
|
// Get the stored MD4 hashed password for the user, or null if the user does not exist
|
||||||
md4hash = authenticationComponent.getMD4HashedPassword(userName);
|
md4hash = nltmAuthenticator.getMD4HashedPassword(userName);
|
||||||
}
|
}
|
||||||
catch (Throwable ex)
|
catch (Throwable ex)
|
||||||
{
|
{
|
||||||
|
@@ -42,6 +42,7 @@ import org.alfresco.jlan.server.config.SecurityConfigSection;
|
|||||||
import org.alfresco.jlan.util.IPAddress;
|
import org.alfresco.jlan.util.IPAddress;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.SessionUser;
|
import org.alfresco.repo.SessionUser;
|
||||||
|
import org.alfresco.repo.management.subsystems.ActivateableBean;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
@@ -61,7 +62,7 @@ import org.springframework.beans.factory.InitializingBean;
|
|||||||
* @author gkspencer
|
* @author gkspencer
|
||||||
* @author kroast
|
* @author kroast
|
||||||
*/
|
*/
|
||||||
public abstract class BaseSSOAuthenticationFilter implements DependencyInjectedFilter, InitializingBean
|
public abstract class BaseSSOAuthenticationFilter implements DependencyInjectedFilter, ActivateableBean, InitializingBean
|
||||||
{
|
{
|
||||||
// Constants
|
// Constants
|
||||||
//
|
//
|
||||||
@@ -112,6 +113,8 @@ public abstract class BaseSSOAuthenticationFilter implements DependencyInjectedF
|
|||||||
|
|
||||||
private String m_lastConfiguredServerName;
|
private String m_lastConfiguredServerName;
|
||||||
private String m_lastResolvedServerName;
|
private String m_lastResolvedServerName;
|
||||||
|
|
||||||
|
private boolean m_isActive = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param serverConfiguration the serverConfiguration to set
|
* @param serverConfiguration the serverConfiguration to set
|
||||||
@@ -159,7 +162,27 @@ public abstract class BaseSSOAuthenticationFilter implements DependencyInjectedF
|
|||||||
public void setTransactionService(TransactionService transactionService)
|
public void setTransactionService(TransactionService transactionService)
|
||||||
{
|
{
|
||||||
this.transactionService = transactionService;
|
this.transactionService = transactionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activates or deactivates the bean
|
||||||
|
*
|
||||||
|
* @param active
|
||||||
|
* <code>true</code> if the bean is active and initialization should complete
|
||||||
|
*/
|
||||||
|
public void setActive(boolean active)
|
||||||
|
{
|
||||||
|
this.m_isActive = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
* @see org.alfresco.repo.management.subsystems.ActivateableBean#isActive()
|
||||||
|
*/
|
||||||
|
public boolean isActive()
|
||||||
|
{
|
||||||
|
return m_isActive;
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||||
|
Reference in New Issue
Block a user