mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +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:
@@ -415,30 +415,6 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
||||
authenticationContext.clearCurrentSecurityContext();
|
||||
}
|
||||
|
||||
/**
|
||||
* The default is not to support Authentication token base authentication
|
||||
*/
|
||||
public Authentication authenticate(Authentication token) throws AuthenticationException
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Authentication via token not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* The should only be supported if getNTLMMode() is NTLMMode.MD4_PROVIDER.
|
||||
*/
|
||||
public String getMD4HashedPassword(String userName)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NTML mode - none - supports MD4 hash to integrate - or it can asct as an NTLM authentication
|
||||
*/
|
||||
public NTLMMode getNTLMMode()
|
||||
{
|
||||
return NTLMMode.NONE;
|
||||
}
|
||||
|
||||
class SetCurrentUserCallback implements RetryingTransactionHelper.RetryingTransactionCallback<Authentication>
|
||||
{
|
||||
AuthenticationException ae = null;
|
||||
@@ -527,7 +503,7 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
||||
*
|
||||
* @param defaultAdministratorUserNames
|
||||
*/
|
||||
public void setDefaultAdministratorUserNames(String defaultAdministratorUserNames)
|
||||
public void setDefaultAdministratorUserNameList(String defaultAdministratorUserNames)
|
||||
{
|
||||
Set<String> nameSet = new TreeSet<String>();
|
||||
if (defaultAdministratorUserNames.length() > 0)
|
||||
|
@@ -28,7 +28,6 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.repo.cache.SimpleCache;
|
||||
import org.alfresco.service.Managed;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
@@ -57,6 +56,7 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer
|
||||
this.sysAdminCache = sysAdminCache;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void preAuthenticationCheck(String userName) throws AuthenticationException
|
||||
{
|
||||
if (sysAdminCache != null)
|
||||
@@ -77,7 +77,6 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer
|
||||
}
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowedUsers(List<String> allowedUsers)
|
||||
{
|
||||
if (initialised)
|
||||
@@ -107,7 +106,6 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer
|
||||
}
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setMaxUsers(int maxUsers)
|
||||
{
|
||||
if (initialised)
|
||||
|
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* 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.repo.security.authentication;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
/**
|
||||
* A base class for chaining authentication components. Where appropriate, methods will 'chain' across multiple
|
||||
* {@link AuthenticationComponent} instances, as returned by {@link #getUsableAuthenticationComponents()}.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public abstract class AbstractChainingAuthenticationComponent extends AbstractAuthenticationComponent
|
||||
{
|
||||
|
||||
/**
|
||||
* Instantiates a new abstract chaining authentication component.
|
||||
*/
|
||||
public AbstractChainingAuthenticationComponent()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the authentication components across which methods will chain.
|
||||
*
|
||||
* @return the usable authentication components
|
||||
*/
|
||||
protected abstract Collection<AuthenticationComponent> getUsableAuthenticationComponents();
|
||||
|
||||
/**
|
||||
* Chain authentication with user name and password - tries all in order until one works, or fails.
|
||||
*
|
||||
* @param userName
|
||||
* the user name
|
||||
* @param password
|
||||
* the password
|
||||
*/
|
||||
@Override
|
||||
protected void authenticateImpl(String userName, char[] password)
|
||||
{
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
try
|
||||
{
|
||||
authComponent.authenticate(userName, password);
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Failed to authenticate");
|
||||
}
|
||||
|
||||
/**
|
||||
* If any implementation supports guest then guest is allowed.
|
||||
*
|
||||
* @return true, if implementation allows guest login
|
||||
*/
|
||||
@Override
|
||||
protected boolean implementationAllowsGuestLogin()
|
||||
{
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
if (authComponent.guestUserAuthenticationAllowed())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.security.authentication.AbstractAuthenticationComponent#setCurrentUser(java.lang.String,
|
||||
* org.alfresco.repo.security.authentication.AuthenticationComponent.UserNameValidationMode)
|
||||
*/
|
||||
@Override
|
||||
public Authentication setCurrentUser(String userName, UserNameValidationMode validationMode)
|
||||
{
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
try
|
||||
{
|
||||
return authComponent.setCurrentUser(userName, validationMode);
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Failed to set current user " + userName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current user - try all implementations - as some may check the user exists.
|
||||
*
|
||||
* @param userName
|
||||
* the user name
|
||||
* @return the authentication
|
||||
*/
|
||||
@Override
|
||||
public Authentication setCurrentUser(String userName)
|
||||
{
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
try
|
||||
{
|
||||
return authComponent.setCurrentUser(userName);
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Failed to set current user " + userName);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.security.authentication.AbstractAuthenticationComponent#getDefaultAdministratorUserNames()
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getDefaultAdministratorUserNames()
|
||||
{
|
||||
Set<String> defaultAdministratorUserNames = new TreeSet<String>();
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
defaultAdministratorUserNames.addAll(authComponent.getDefaultAdministratorUserNames());
|
||||
}
|
||||
return defaultAdministratorUserNames;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,521 @@
|
||||
/*
|
||||
* 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.repo.security.authentication;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
|
||||
/**
|
||||
* A base class for chaining authentication services. Where appropriate, methods will 'chain' across multiple
|
||||
* {@link AuthenticationService} instances, as returned by {@link #getUsableAuthenticationServices()}.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public abstract class AbstractChainingAuthenticationService extends AbstractAuthenticationService
|
||||
{
|
||||
|
||||
/**
|
||||
* Instantiates a new abstract chaining authentication service.
|
||||
*/
|
||||
public AbstractChainingAuthenticationService()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the mutable authentication service.
|
||||
*
|
||||
* @return the mutable authentication service
|
||||
*/
|
||||
public abstract AuthenticationService getMutableAuthenticationService();
|
||||
|
||||
/**
|
||||
* Gets the authentication services across which methods will chain.
|
||||
*
|
||||
* @return the usable authentication services
|
||||
*/
|
||||
protected abstract List<AuthenticationService> getUsableAuthenticationServices();
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#createAuthentication(java.lang.String, char[])
|
||||
*/
|
||||
public void createAuthentication(String userName, char[] password) throws AuthenticationException
|
||||
{
|
||||
if (getMutableAuthenticationService() == null)
|
||||
{
|
||||
throw new AuthenticationException(
|
||||
"Unable to create authentication as there is no suitable authentication service.");
|
||||
}
|
||||
getMutableAuthenticationService().createAuthentication(userName, password);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#updateAuthentication(java.lang.String, char[], char[])
|
||||
*/
|
||||
public void updateAuthentication(String userName, char[] oldPassword, char[] newPassword)
|
||||
throws AuthenticationException
|
||||
{
|
||||
if (getMutableAuthenticationService() == null)
|
||||
{
|
||||
throw new AuthenticationException(
|
||||
"Unable to update authentication as there is no suitable authentication service.");
|
||||
}
|
||||
getMutableAuthenticationService().updateAuthentication(userName, oldPassword, newPassword);
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#setAuthentication(java.lang.String, char[])
|
||||
*/
|
||||
public void setAuthentication(String userName, char[] newPassword) throws AuthenticationException
|
||||
{
|
||||
if (getMutableAuthenticationService() == null)
|
||||
{
|
||||
throw new AuthenticationException(
|
||||
"Unable to set authentication as there is no suitable authentication service.");
|
||||
}
|
||||
getMutableAuthenticationService().setAuthentication(userName, newPassword);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#deleteAuthentication(java.lang.String)
|
||||
*/
|
||||
public void deleteAuthentication(String userName) throws AuthenticationException
|
||||
{
|
||||
if (getMutableAuthenticationService() == null)
|
||||
{
|
||||
throw new AuthenticationException(
|
||||
"Unable to delete authentication as there is no suitable authentication service.");
|
||||
}
|
||||
getMutableAuthenticationService().deleteAuthentication(userName);
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#setAuthenticationEnabled(java.lang.String, boolean)
|
||||
*/
|
||||
public void setAuthenticationEnabled(String userName, boolean enabled) throws AuthenticationException
|
||||
{
|
||||
if (getMutableAuthenticationService() == null)
|
||||
{
|
||||
throw new AuthenticationException(
|
||||
"Unable to set authentication enabled as there is no suitable authentication service.");
|
||||
}
|
||||
getMutableAuthenticationService().setAuthenticationEnabled(userName, enabled);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#getAuthenticationEnabled(java.lang.String)
|
||||
*/
|
||||
public boolean getAuthenticationEnabled(String userName) throws AuthenticationException
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (authService.getAuthenticationEnabled(userName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#authenticate(java.lang.String, char[])
|
||||
*/
|
||||
public void authenticate(String userName, char[] password) throws AuthenticationException
|
||||
{
|
||||
preAuthenticationCheck(userName);
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
authService.authenticate(userName, password);
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Failed to authenticate");
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#authenticateAsGuest()
|
||||
*/
|
||||
public void authenticateAsGuest() throws AuthenticationException
|
||||
{
|
||||
preAuthenticationCheck(PermissionService.GUEST_AUTHORITY);
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
authService.authenticateAsGuest();
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Guest authentication not supported");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#guestUserAuthenticationAllowed()
|
||||
*/
|
||||
public boolean guestUserAuthenticationAllowed()
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
if (authService.guestUserAuthenticationAllowed())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// it isn't allowed in any of the authentication components
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#authenticationExists(java.lang.String)
|
||||
*/
|
||||
public boolean authenticationExists(String userName)
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
if (authService.authenticationExists(userName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// it doesn't exist in any of the authentication components
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#getCurrentUserName()
|
||||
*/
|
||||
public String getCurrentUserName() throws AuthenticationException
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
return authService.getCurrentUserName();
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#invalidateUserSession(java.lang.String)
|
||||
*/
|
||||
public void invalidateUserSession(String userName) throws AuthenticationException
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
authService.invalidateUserSession(userName);
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Unable to invalidate user session");
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#invalidateTicket(java.lang.String)
|
||||
*/
|
||||
public void invalidateTicket(String ticket) throws AuthenticationException
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
authService.invalidateTicket(ticket);
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Unable to invalidate ticket");
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#validate(java.lang.String)
|
||||
*/
|
||||
public void validate(String ticket) throws AuthenticationException
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
authService.validate(ticket);
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Unable to validate ticket");
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#getCurrentTicket()
|
||||
*/
|
||||
public String getCurrentTicket()
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
return authService.getCurrentTicket();
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#getNewTicket()
|
||||
*/
|
||||
public String getNewTicket()
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
return authService.getNewTicket();
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#clearCurrentSecurityContext()
|
||||
*/
|
||||
public void clearCurrentSecurityContext()
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
authService.clearCurrentSecurityContext();
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Failed to clear security context");
|
||||
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#isCurrentUserTheSystemUser()
|
||||
*/
|
||||
public boolean isCurrentUserTheSystemUser()
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
return authService.isCurrentUserTheSystemUser();
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#getDomains()
|
||||
*/
|
||||
public Set<String> getDomains()
|
||||
{
|
||||
HashSet<String> domains = new HashSet<String>();
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
domains.addAll(authService.getDomains());
|
||||
}
|
||||
return domains;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#getDomainsThatAllowUserCreation()
|
||||
*/
|
||||
public Set<String> getDomainsThatAllowUserCreation()
|
||||
{
|
||||
HashSet<String> domains = new HashSet<String>();
|
||||
if (getMutableAuthenticationService() != null)
|
||||
{
|
||||
domains.addAll(getMutableAuthenticationService().getDomainsThatAllowUserCreation());
|
||||
}
|
||||
return domains;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#getDomainsThatAllowUserDeletion()
|
||||
*/
|
||||
public Set<String> getDomainsThatAllowUserDeletion()
|
||||
{
|
||||
HashSet<String> domains = new HashSet<String>();
|
||||
if (getMutableAuthenticationService() != null)
|
||||
{
|
||||
domains.addAll(getMutableAuthenticationService().getDomainsThatAllowUserDeletion());
|
||||
}
|
||||
return domains;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#getDomiansThatAllowUserPasswordChanges()
|
||||
*/
|
||||
public Set<String> getDomiansThatAllowUserPasswordChanges()
|
||||
{
|
||||
HashSet<String> domains = new HashSet<String>();
|
||||
if (getMutableAuthenticationService() != null)
|
||||
{
|
||||
domains.addAll(getMutableAuthenticationService().getDomiansThatAllowUserPasswordChanges());
|
||||
}
|
||||
return domains;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.security.authentication.AbstractAuthenticationService#getUsersWithTickets(boolean)
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getUsersWithTickets(boolean nonExpiredOnly)
|
||||
{
|
||||
HashSet<String> users = new HashSet<String>();
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
if (authService instanceof AbstractAuthenticationService)
|
||||
{
|
||||
users.addAll(((AbstractAuthenticationService) authService).getUsersWithTickets(nonExpiredOnly));
|
||||
}
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.security.authentication.AbstractAuthenticationService#countTickets(boolean)
|
||||
*/
|
||||
@Override
|
||||
public int countTickets(boolean nonExpiredOnly)
|
||||
{
|
||||
int count = 0;
|
||||
for (TicketComponent tc : getTicketComponents())
|
||||
{
|
||||
count += tc.countTickets(nonExpiredOnly);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.security.authentication.AbstractAuthenticationService#invalidateTickets(boolean)
|
||||
*/
|
||||
@Override
|
||||
public int invalidateTickets(boolean nonExpiredOnly)
|
||||
{
|
||||
int count = 0;
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
if (authService instanceof AbstractAuthenticationService)
|
||||
{
|
||||
count += ((AbstractAuthenticationService) authService).invalidateTickets(nonExpiredOnly);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.security.authentication.AbstractAuthenticationService#getTicketComponents()
|
||||
*/
|
||||
@Override
|
||||
public Set<TicketComponent> getTicketComponents()
|
||||
{
|
||||
Set<TicketComponent> tcs = new HashSet<TicketComponent>();
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
if (authService instanceof AbstractAuthenticationService)
|
||||
{
|
||||
tcs.addAll(((AbstractAuthenticationService) authService).getTicketComponents());
|
||||
}
|
||||
}
|
||||
return tcs;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#getDefaultAdministratorUserNames()
|
||||
*/
|
||||
public Set<String> getDefaultAdministratorUserNames()
|
||||
{
|
||||
Set<String> defaultAdministratorUserNames = new TreeSet<String>();
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
defaultAdministratorUserNames.addAll(authService.getDefaultAdministratorUserNames());
|
||||
}
|
||||
return defaultAdministratorUserNames;
|
||||
}
|
||||
|
||||
}
|
@@ -41,15 +41,6 @@ public interface AuthenticationComponent extends AuthenticationContext
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
public void authenticate(String userName, char[] password) throws AuthenticationException;
|
||||
|
||||
/**
|
||||
* Authenticate using a token
|
||||
*
|
||||
* @param token Authentication
|
||||
* @return Authentication
|
||||
* @throws AuthenticationException
|
||||
*/
|
||||
public Authentication authenticate(Authentication token) throws AuthenticationException;
|
||||
|
||||
/**
|
||||
* Explicitly set the current user to be authenticated.
|
||||
@@ -76,16 +67,6 @@ public interface AuthenticationComponent extends AuthenticationContext
|
||||
*/
|
||||
public boolean guestUserAuthenticationAllowed();
|
||||
|
||||
/**
|
||||
* Get the enum that describes NTLM integration
|
||||
*/
|
||||
public NTLMMode getNTLMMode();
|
||||
|
||||
/**
|
||||
* Get the MD4 password hash, as required by NTLM based authentication methods.
|
||||
*/
|
||||
public String getMD4HashedPassword(String userName);
|
||||
|
||||
/**
|
||||
* Gets a set of user names who for this particular authentication system should be considered administrators by
|
||||
* default. If the security framework is case sensitive these values should be case sensitive user names. If the
|
||||
|
@@ -29,13 +29,15 @@ import java.io.StringWriter;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.AuthenticationManager;
|
||||
import net.sf.acegisecurity.UserDetails;
|
||||
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||
|
||||
import org.alfresco.service.Managed;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator;
|
||||
|
||||
public class AuthenticationComponentImpl extends AbstractAuthenticationComponent
|
||||
public class AuthenticationComponentImpl extends AbstractAuthenticationComponent implements NLTMAuthenticator
|
||||
{
|
||||
private MutableAuthenticationDao authenticationDao;
|
||||
|
||||
@@ -61,7 +63,6 @@ public class AuthenticationComponentImpl extends AbstractAuthenticationComponent
|
||||
*
|
||||
* @param authenticationDao
|
||||
*/
|
||||
@Managed(category = "Security")
|
||||
public void setAuthenticationDao(MutableAuthenticationDao authenticationDao)
|
||||
{
|
||||
this.authenticationDao = authenticationDao;
|
||||
@@ -107,16 +108,22 @@ public class AuthenticationComponentImpl extends AbstractAuthenticationComponent
|
||||
/**
|
||||
* Get the password hash from the DAO
|
||||
*/
|
||||
@Override
|
||||
public String getMD4HashedPassword(String userName)
|
||||
{
|
||||
return this.authenticationDao.getMD4HashedPassword(userName);
|
||||
}
|
||||
|
||||
/**
|
||||
* The default is not to support Authentication token base authentication
|
||||
*/
|
||||
public Authentication authenticate(Authentication token) throws AuthenticationException
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Authentication via token not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation supported MD4 password hashes.
|
||||
*/
|
||||
@Override
|
||||
public NTLMMode getNTLMMode()
|
||||
{
|
||||
return NTLMMode.MD4_PROVIDER;
|
||||
|
@@ -28,7 +28,6 @@ import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent.UserNameValidationMode;
|
||||
import org.alfresco.service.Managed;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
|
||||
public class AuthenticationServiceImpl extends AbstractAuthenticationService
|
||||
@@ -52,7 +51,6 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService
|
||||
super();
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAuthenticationDao(MutableAuthenticationDao authenticationDao)
|
||||
{
|
||||
this.authenticationDao = authenticationDao;
|
||||
@@ -63,7 +61,6 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService
|
||||
this.ticketComponent = ticketComponent;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAuthenticationComponent(AuthenticationComponent authenticationComponent)
|
||||
{
|
||||
this.authenticationComponent = authenticationComponent;
|
||||
|
@@ -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
|
||||
@@ -18,18 +18,19 @@
|
||||
* 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 recieved a copy of the text describing
|
||||
* 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.repo.security.authentication;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
import org.alfresco.service.Managed;
|
||||
import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator;
|
||||
|
||||
/**
|
||||
* A chaining authentication component is required for all the beans that qire up an authentication component and not an
|
||||
@@ -38,7 +39,7 @@ import org.alfresco.service.Managed;
|
||||
*
|
||||
* @author andyh
|
||||
*/
|
||||
public class ChainingAuthenticationComponentImpl extends AbstractAuthenticationComponent
|
||||
public class ChainingAuthenticationComponentImpl extends AbstractChainingAuthenticationComponent implements NLTMAuthenticator
|
||||
{
|
||||
/**
|
||||
* NLTM authentication mode - if unset - finds the first component that supports NTLM - if set - finds the first
|
||||
@@ -72,7 +73,6 @@ public class ChainingAuthenticationComponentImpl extends AbstractAuthenticationC
|
||||
*
|
||||
* @param authenticationComponents
|
||||
*/
|
||||
@Managed(category = "Security")
|
||||
public void setAuthenticationComponents(List<AuthenticationComponent> authenticationComponents)
|
||||
{
|
||||
this.authenticationComponents = authenticationComponents;
|
||||
@@ -93,44 +93,20 @@ public class ChainingAuthenticationComponentImpl extends AbstractAuthenticationC
|
||||
*
|
||||
* @param mutableAuthenticationComponent
|
||||
*/
|
||||
@Managed(category = "Security")
|
||||
public void setMutableAuthenticationComponent(AuthenticationComponent mutableAuthenticationComponent)
|
||||
{
|
||||
this.mutableAuthenticationComponent = mutableAuthenticationComponent;
|
||||
}
|
||||
|
||||
@Managed(category = "Security")
|
||||
public void setNtlmMode(NTLMMode ntlmMode)
|
||||
{
|
||||
this.ntlmMode = ntlmMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Chain authentication with user name and password - tries all in order until one works, or fails.
|
||||
*/
|
||||
@Override
|
||||
protected void authenticateImpl(String userName, char[] password)
|
||||
{
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
try
|
||||
{
|
||||
authComponent.authenticate(userName, password);
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Failed to authenticate");
|
||||
}
|
||||
|
||||
/**
|
||||
* NTLM passthrough authentication - if a mode is defined - the first PASS_THROUGH provider is used - if not, the
|
||||
* first component that supports NTLM is used if it supports PASS_THROUGH
|
||||
*/
|
||||
@Override
|
||||
public Authentication authenticate(Authentication token) throws AuthenticationException
|
||||
{
|
||||
if (this.ntlmMode != null)
|
||||
@@ -144,9 +120,14 @@ public class ChainingAuthenticationComponentImpl extends AbstractAuthenticationC
|
||||
case PASS_THROUGH:
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
if (authComponent.getNTLMMode() == NTLMMode.PASS_THROUGH)
|
||||
if (!(authComponent instanceof NLTMAuthenticator))
|
||||
{
|
||||
return authComponent.authenticate(token);
|
||||
continue;
|
||||
}
|
||||
NLTMAuthenticator ssoAuthenticator = (NLTMAuthenticator)authComponent;
|
||||
if (ssoAuthenticator.getNTLMMode() == NTLMMode.PASS_THROUGH)
|
||||
{
|
||||
return ssoAuthenticator.authenticate(token);
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("No NTLM passthrough authentication to use");
|
||||
@@ -158,11 +139,16 @@ public class ChainingAuthenticationComponentImpl extends AbstractAuthenticationC
|
||||
{
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
if (authComponent.getNTLMMode() != NTLMMode.NONE)
|
||||
if (!(authComponent instanceof NLTMAuthenticator))
|
||||
{
|
||||
if (authComponent.getNTLMMode() == NTLMMode.PASS_THROUGH)
|
||||
continue;
|
||||
}
|
||||
NLTMAuthenticator ssoAuthenticator = (NLTMAuthenticator)authComponent;
|
||||
if (ssoAuthenticator.getNTLMMode() != NTLMMode.NONE)
|
||||
{
|
||||
if (ssoAuthenticator.getNTLMMode() == NTLMMode.PASS_THROUGH)
|
||||
{
|
||||
return authComponent.authenticate(token);
|
||||
return ssoAuthenticator.authenticate(token);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -179,7 +165,6 @@ public class ChainingAuthenticationComponentImpl extends AbstractAuthenticationC
|
||||
/**
|
||||
* Get the MD4 password hash
|
||||
*/
|
||||
@Override
|
||||
public String getMD4HashedPassword(String userName)
|
||||
{
|
||||
if (this.ntlmMode != null)
|
||||
@@ -193,9 +178,14 @@ public class ChainingAuthenticationComponentImpl extends AbstractAuthenticationC
|
||||
case MD4_PROVIDER:
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
if (authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
||||
if (!(authComponent instanceof NLTMAuthenticator))
|
||||
{
|
||||
return authComponent.getMD4HashedPassword(userName);
|
||||
continue;
|
||||
}
|
||||
NLTMAuthenticator ssoAuthenticator = (NLTMAuthenticator)authComponent;
|
||||
if (ssoAuthenticator.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
||||
{
|
||||
return ssoAuthenticator.getMD4HashedPassword(userName);
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("No MD4 provider available");
|
||||
@@ -207,16 +197,21 @@ public class ChainingAuthenticationComponentImpl extends AbstractAuthenticationC
|
||||
{
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
if (authComponent.getNTLMMode() != NTLMMode.NONE)
|
||||
if (!(authComponent instanceof NLTMAuthenticator))
|
||||
{
|
||||
if (authComponent.getNTLMMode() == NTLMMode.PASS_THROUGH)
|
||||
continue;
|
||||
}
|
||||
NLTMAuthenticator ssoAuthenticator = (NLTMAuthenticator)authComponent;
|
||||
if (ssoAuthenticator.getNTLMMode() != NTLMMode.NONE)
|
||||
{
|
||||
if (ssoAuthenticator.getNTLMMode() == NTLMMode.PASS_THROUGH)
|
||||
{
|
||||
throw new AuthenticationException(
|
||||
"The first authentication component to support NTLM supports passthrough");
|
||||
}
|
||||
else
|
||||
{
|
||||
return authComponent.getMD4HashedPassword(userName);
|
||||
return ssoAuthenticator.getMD4HashedPassword(userName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,7 +223,6 @@ public class ChainingAuthenticationComponentImpl extends AbstractAuthenticationC
|
||||
/**
|
||||
* Get the NTLM mode - this is only what is set if one of the implementations provides support for that mode.
|
||||
*/
|
||||
@Override
|
||||
public NTLMMode getNTLMMode()
|
||||
{
|
||||
if (this.ntlmMode != null)
|
||||
@@ -240,7 +234,12 @@ public class ChainingAuthenticationComponentImpl extends AbstractAuthenticationC
|
||||
case PASS_THROUGH:
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
if (authComponent.getNTLMMode() == NTLMMode.PASS_THROUGH)
|
||||
if (!(authComponent instanceof NLTMAuthenticator))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
NLTMAuthenticator ssoAuthenticator = (NLTMAuthenticator)authComponent;
|
||||
if (ssoAuthenticator.getNTLMMode() == NTLMMode.PASS_THROUGH)
|
||||
{
|
||||
return NTLMMode.PASS_THROUGH;
|
||||
}
|
||||
@@ -249,7 +248,12 @@ public class ChainingAuthenticationComponentImpl extends AbstractAuthenticationC
|
||||
case MD4_PROVIDER:
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
if (authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
||||
if (!(authComponent instanceof NLTMAuthenticator))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
NLTMAuthenticator ssoAuthenticator = (NLTMAuthenticator)authComponent;
|
||||
if (ssoAuthenticator.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
||||
{
|
||||
return NTLMMode.MD4_PROVIDER;
|
||||
}
|
||||
@@ -263,74 +267,26 @@ public class ChainingAuthenticationComponentImpl extends AbstractAuthenticationC
|
||||
{
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
if (authComponent.getNTLMMode() != NTLMMode.NONE)
|
||||
if (!(authComponent instanceof NLTMAuthenticator))
|
||||
{
|
||||
return authComponent.getNTLMMode();
|
||||
continue;
|
||||
}
|
||||
NLTMAuthenticator ssoAuthenticator = (NLTMAuthenticator)authComponent;
|
||||
if (ssoAuthenticator.getNTLMMode() != NTLMMode.NONE)
|
||||
{
|
||||
return ssoAuthenticator.getNTLMMode();
|
||||
}
|
||||
}
|
||||
return NTLMMode.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If any implementation supports guest then guest is allowed
|
||||
*/
|
||||
@Override
|
||||
protected boolean implementationAllowsGuestLogin()
|
||||
{
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
if (authComponent.guestUserAuthenticationAllowed())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Authentication setCurrentUser(String userName, UserNameValidationMode validationMode)
|
||||
{
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
try
|
||||
{
|
||||
return authComponent.setCurrentUser(userName, validationMode);
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Failed to set current user " + userName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current user - try all implementations - as some may check the user exists
|
||||
*/
|
||||
@Override
|
||||
public Authentication setCurrentUser(String userName)
|
||||
{
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
try
|
||||
{
|
||||
return authComponent.setCurrentUser(userName);
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Failed to set current user " + userName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get authentication components
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private List<AuthenticationComponent> getUsableAuthenticationComponents()
|
||||
protected Collection<AuthenticationComponent> getUsableAuthenticationComponents()
|
||||
{
|
||||
if (this.mutableAuthenticationComponent == null)
|
||||
{
|
||||
|
@@ -25,459 +25,68 @@
|
||||
package org.alfresco.repo.security.authentication;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.alfresco.service.Managed;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
|
||||
/**
|
||||
* This class implements a simple chaining authentication service.
|
||||
*
|
||||
* It chains together other authentication services so that authentication can happen against more than one authentication service.
|
||||
*
|
||||
* The authentication services it uses are stored as a list.
|
||||
*
|
||||
* Each authentication service must belong to the same domain. This is checked at configuration time.
|
||||
*
|
||||
* Authentication will try each authentication service in order. If any allow authentication given the user name and password then the user will be accepted.
|
||||
*
|
||||
* Additions, deletions and password changes are made to one special authentication service. This service will be tried first for authentication. Users can not be created if they
|
||||
* exist in another authentication service.
|
||||
*
|
||||
* To avoid transactional issues in chaining, the services registered with this service must not have transactional wrappers. If not, errors will mark the transaction for roll back
|
||||
* and we can not chain down the list of authentication services.
|
||||
*
|
||||
* This class implements a simple chaining authentication service. It chains together other authentication services so
|
||||
* that authentication can happen against more than one authentication service. The authentication services it uses are
|
||||
* stored as a list. Each authentication service must belong to the same domain. This is checked at configuration time.
|
||||
* Authentication will try each authentication service in order. If any allow authentication given the user name and
|
||||
* password then the user will be accepted. Additions, deletions and password changes are made to one special
|
||||
* authentication service. This service will be tried first for authentication. Users can not be created if they exist
|
||||
* in another authentication service. To avoid transactional issues in chaining, the services registered with this
|
||||
* service must not have transactional wrappers. If not, errors will mark the transaction for roll back and we can not
|
||||
* chain down the list of authentication services.
|
||||
*
|
||||
* @author Andy Hind
|
||||
*/
|
||||
public class ChainingAuthenticationServiceImpl extends AbstractAuthenticationService
|
||||
public class ChainingAuthenticationServiceImpl extends AbstractChainingAuthenticationService
|
||||
{
|
||||
|
||||
private List<AuthenticationService> authenticationServices;
|
||||
List<AuthenticationService> authenticationServices;
|
||||
|
||||
private AuthenticationService mutableAuthenticationService;
|
||||
AuthenticationService mutableAuthenticationService;
|
||||
|
||||
public ChainingAuthenticationServiceImpl()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public List<AuthenticationService> getAuthenticationServices()
|
||||
{
|
||||
return authenticationServices;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAuthenticationServices(List<AuthenticationService> authenticationServices)
|
||||
{
|
||||
this.authenticationServices = authenticationServices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AuthenticationService getMutableAuthenticationService()
|
||||
{
|
||||
return mutableAuthenticationService;
|
||||
return this.mutableAuthenticationService;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setMutableAuthenticationService(AuthenticationService mutableAuthenticationService)
|
||||
{
|
||||
this.mutableAuthenticationService = mutableAuthenticationService;
|
||||
}
|
||||
|
||||
public void createAuthentication(String userName, char[] password) throws AuthenticationException
|
||||
@Override
|
||||
protected List<AuthenticationService> getUsableAuthenticationServices()
|
||||
{
|
||||
if (mutableAuthenticationService == null)
|
||||
if (this.mutableAuthenticationService == null)
|
||||
{
|
||||
throw new AuthenticationException(
|
||||
"Unable to create authentication as there is no suitable authentication service.");
|
||||
}
|
||||
mutableAuthenticationService.createAuthentication(userName, password);
|
||||
}
|
||||
|
||||
public void updateAuthentication(String userName, char[] oldPassword, char[] newPassword)
|
||||
throws AuthenticationException
|
||||
{
|
||||
if (mutableAuthenticationService == null)
|
||||
{
|
||||
throw new AuthenticationException(
|
||||
"Unable to update authentication as there is no suitable authentication service.");
|
||||
}
|
||||
mutableAuthenticationService.updateAuthentication(userName, oldPassword, newPassword);
|
||||
|
||||
}
|
||||
|
||||
public void setAuthentication(String userName, char[] newPassword) throws AuthenticationException
|
||||
{
|
||||
if (mutableAuthenticationService == null)
|
||||
{
|
||||
throw new AuthenticationException(
|
||||
"Unable to set authentication as there is no suitable authentication service.");
|
||||
}
|
||||
mutableAuthenticationService.setAuthentication(userName, newPassword);
|
||||
}
|
||||
|
||||
public void deleteAuthentication(String userName) throws AuthenticationException
|
||||
{
|
||||
if (mutableAuthenticationService == null)
|
||||
{
|
||||
throw new AuthenticationException(
|
||||
"Unable to delete authentication as there is no suitable authentication service.");
|
||||
}
|
||||
mutableAuthenticationService.deleteAuthentication(userName);
|
||||
|
||||
}
|
||||
|
||||
public void setAuthenticationEnabled(String userName, boolean enabled) throws AuthenticationException
|
||||
{
|
||||
if (mutableAuthenticationService == null)
|
||||
{
|
||||
throw new AuthenticationException(
|
||||
"Unable to set authentication enabled as there is no suitable authentication service.");
|
||||
}
|
||||
mutableAuthenticationService.setAuthenticationEnabled(userName, enabled);
|
||||
}
|
||||
|
||||
public boolean getAuthenticationEnabled(String userName) throws AuthenticationException
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
if (authService.getAuthenticationEnabled(userName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void authenticate(String userName, char[] password) throws AuthenticationException
|
||||
{
|
||||
preAuthenticationCheck(userName);
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
authService.authenticate(userName, password);
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Failed to authenticate");
|
||||
|
||||
}
|
||||
|
||||
public void authenticateAsGuest() throws AuthenticationException
|
||||
{
|
||||
preAuthenticationCheck(PermissionService.GUEST_AUTHORITY);
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
authService.authenticateAsGuest();
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Guest authentication not supported");
|
||||
}
|
||||
|
||||
public boolean guestUserAuthenticationAllowed()
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
if (authService.guestUserAuthenticationAllowed())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// it isn't allowed in any of the authentication components
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean authenticationExists(String userName)
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
if (authService.authenticationExists(userName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// it doesn't exist in any of the authentication components
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getCurrentUserName() throws AuthenticationException
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
return authService.getCurrentUserName();
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void invalidateUserSession(String userName) throws AuthenticationException
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
authService.invalidateUserSession(userName);
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Unable to invalidate user session");
|
||||
|
||||
}
|
||||
|
||||
public void invalidateTicket(String ticket) throws AuthenticationException
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
authService.invalidateTicket(ticket);
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Unable to invalidate ticket");
|
||||
|
||||
}
|
||||
|
||||
public void validate(String ticket) throws AuthenticationException
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
authService.validate(ticket);
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Unable to validate ticket");
|
||||
|
||||
}
|
||||
|
||||
public String getCurrentTicket()
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
return authService.getCurrentTicket();
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getNewTicket()
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
return authService.getNewTicket();
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void clearCurrentSecurityContext()
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
authService.clearCurrentSecurityContext();
|
||||
return;
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
throw new AuthenticationException("Failed to clear security context");
|
||||
|
||||
}
|
||||
|
||||
public boolean isCurrentUserTheSystemUser()
|
||||
{
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
try
|
||||
{
|
||||
return authService.isCurrentUserTheSystemUser();
|
||||
}
|
||||
catch (AuthenticationException e)
|
||||
{
|
||||
// Ignore and chain
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<AuthenticationService> getUsableAuthenticationServices()
|
||||
{
|
||||
if (mutableAuthenticationService == null)
|
||||
{
|
||||
return authenticationServices;
|
||||
return this.authenticationServices;
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrayList<AuthenticationService> services = new ArrayList<AuthenticationService>(
|
||||
authenticationServices == null ? 1 : (authenticationServices.size() + 1));
|
||||
services.add(mutableAuthenticationService);
|
||||
if (authenticationServices != null)
|
||||
this.authenticationServices == null ? 1 : this.authenticationServices.size() + 1);
|
||||
services.add(this.mutableAuthenticationService);
|
||||
if (this.authenticationServices != null)
|
||||
{
|
||||
services.addAll(authenticationServices);
|
||||
services.addAll(this.authenticationServices);
|
||||
}
|
||||
return services;
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> getDomains()
|
||||
{
|
||||
HashSet<String> domains = new HashSet<String>();
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
domains.addAll(authService.getDomains());
|
||||
}
|
||||
return domains;
|
||||
}
|
||||
|
||||
public Set<String> getDomainsThatAllowUserCreation()
|
||||
{
|
||||
HashSet<String> domains = new HashSet<String>();
|
||||
if (mutableAuthenticationService != null)
|
||||
{
|
||||
domains.addAll(mutableAuthenticationService.getDomainsThatAllowUserCreation());
|
||||
}
|
||||
return domains;
|
||||
}
|
||||
|
||||
public Set<String> getDomainsThatAllowUserDeletion()
|
||||
{
|
||||
HashSet<String> domains = new HashSet<String>();
|
||||
if (mutableAuthenticationService != null)
|
||||
{
|
||||
domains.addAll(mutableAuthenticationService.getDomainsThatAllowUserDeletion());
|
||||
}
|
||||
return domains;
|
||||
}
|
||||
|
||||
public Set<String> getDomiansThatAllowUserPasswordChanges()
|
||||
{
|
||||
HashSet<String> domains = new HashSet<String>();
|
||||
if (mutableAuthenticationService != null)
|
||||
{
|
||||
domains.addAll(mutableAuthenticationService.getDomiansThatAllowUserPasswordChanges());
|
||||
}
|
||||
return domains;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getUsersWithTickets(boolean nonExpiredOnly)
|
||||
{
|
||||
HashSet<String> users = new HashSet<String>();
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
if(authService instanceof AbstractAuthenticationService)
|
||||
{
|
||||
users.addAll( ((AbstractAuthenticationService)authService).getUsersWithTickets(nonExpiredOnly));
|
||||
}
|
||||
}
|
||||
return users;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countTickets(boolean nonExpiredOnly)
|
||||
{
|
||||
int count = 0;
|
||||
for(TicketComponent tc : getTicketComponents())
|
||||
{
|
||||
count += tc.countTickets(nonExpiredOnly);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int invalidateTickets(boolean nonExpiredOnly)
|
||||
{
|
||||
int count = 0;
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
if(authService instanceof AbstractAuthenticationService)
|
||||
{
|
||||
count += ((AbstractAuthenticationService)authService).invalidateTickets(nonExpiredOnly);
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<TicketComponent> getTicketComponents()
|
||||
{
|
||||
Set<TicketComponent> tcs = new HashSet<TicketComponent>();
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
if(authService instanceof AbstractAuthenticationService)
|
||||
{
|
||||
tcs.addAll(((AbstractAuthenticationService)authService).getTicketComponents());
|
||||
}
|
||||
}
|
||||
return tcs;
|
||||
}
|
||||
|
||||
public Set<String> getDefaultAdministratorUserNames()
|
||||
{
|
||||
Set<String> defaultAdministratorUserNames = new TreeSet<String>();
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
defaultAdministratorUserNames.addAll(authService.getDefaultAdministratorUserNames());
|
||||
}
|
||||
return defaultAdministratorUserNames;
|
||||
}
|
||||
}
|
||||
|
@@ -30,7 +30,6 @@ import net.sf.acegisecurity.UserDetails;
|
||||
import net.sf.acegisecurity.providers.dao.UsernameNotFoundException;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.Managed;
|
||||
import org.springframework.dao.DataAccessException;
|
||||
|
||||
/**
|
||||
@@ -430,97 +429,81 @@ public class DefaultMutableAuthenticationDao implements MutableAuthenticationDao
|
||||
// Bean IOC //
|
||||
// -------- //
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowCreateUser(boolean allowCreateUser)
|
||||
{
|
||||
this.allowCreateUser = allowCreateUser;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowDeleteUser(boolean allowDeleteUser)
|
||||
{
|
||||
this.allowDeleteUser = allowDeleteUser;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowGetAccountExpiryDate(boolean allowGetAccountExpiryDate)
|
||||
{
|
||||
this.allowGetAccountExpiryDate = allowGetAccountExpiryDate;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowGetAccountHasExpired(boolean allowGetAccountHasExpired)
|
||||
{
|
||||
this.allowGetAccountHasExpired = allowGetAccountHasExpired;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowGetAccountLocked(boolean allowGetAccountLocked)
|
||||
{
|
||||
this.allowGetAccountLocked = allowGetAccountLocked;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowGetCredentialsExpire(boolean allowGetCredentialsExpire)
|
||||
{
|
||||
this.allowGetCredentialsExpire = allowGetCredentialsExpire;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowGetCredentialsExpiryDate(boolean allowGetCredentialsExpiryDate)
|
||||
{
|
||||
this.allowGetCredentialsExpiryDate = allowGetCredentialsExpiryDate;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowGetCredentialsHaveExpired(boolean allowGetCredentialsHaveExpired)
|
||||
{
|
||||
this.allowGetCredentialsHaveExpired = allowGetCredentialsHaveExpired;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowGetEnabled(boolean allowGetEnabled)
|
||||
{
|
||||
this.allowGetEnabled = allowGetEnabled;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowSetAccountExpires(boolean allowSetAccountExpires)
|
||||
{
|
||||
this.allowSetAccountExpires = allowSetAccountExpires;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowSetAccountExpiryDate(boolean allowSetAccountExpiryDate)
|
||||
{
|
||||
this.allowSetAccountExpiryDate = allowSetAccountExpiryDate;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowSetAccountLocked(boolean allowSetAccountLocked)
|
||||
{
|
||||
this.allowSetAccountLocked = allowSetAccountLocked;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowSetCredentialsExpire(boolean allowSetCredentialsExpire)
|
||||
{
|
||||
this.allowSetCredentialsExpire = allowSetCredentialsExpire;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowSetCredentialsExpiryDate(boolean allowSetCredentialsExpiryDate)
|
||||
{
|
||||
this.allowSetCredentialsExpiryDate = allowSetCredentialsExpiryDate;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowSetEnabled(boolean allowSetEnabled)
|
||||
{
|
||||
this.allowSetEnabled = allowSetEnabled;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAllowUpdateUser(boolean allowUpdateUser)
|
||||
{
|
||||
this.allowUpdateUser = allowUpdateUser;
|
||||
|
@@ -24,6 +24,11 @@
|
||||
*/
|
||||
package org.alfresco.repo.security.authentication;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.repo.security.authentication.ntlm.NLTMAuthenticator;
|
||||
|
||||
|
||||
/**
|
||||
* This implementation of an AuthenticationComponent can be configured to accept or reject all attempts to login.
|
||||
@@ -37,7 +42,7 @@ package org.alfresco.repo.security.authentication;
|
||||
*
|
||||
* @author Andy Hind
|
||||
*/
|
||||
public class SimpleAcceptOrRejectAllAuthenticationComponentImpl extends AbstractAuthenticationComponent
|
||||
public class SimpleAcceptOrRejectAllAuthenticationComponentImpl extends AbstractAuthenticationComponent implements NLTMAuthenticator
|
||||
{
|
||||
private boolean accept = false;
|
||||
|
||||
@@ -70,7 +75,6 @@ public class SimpleAcceptOrRejectAllAuthenticationComponentImpl extends Abstract
|
||||
return accept;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMD4HashedPassword(String userName)
|
||||
{
|
||||
if(accept)
|
||||
@@ -83,11 +87,16 @@ public class SimpleAcceptOrRejectAllAuthenticationComponentImpl extends Abstract
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NTLMMode getNTLMMode()
|
||||
{
|
||||
return NTLMMode.MD4_PROVIDER;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The default is not to support Authentication token base authentication
|
||||
*/
|
||||
public Authentication authenticate(Authentication token) throws AuthenticationException
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Authentication via token not supported");
|
||||
}
|
||||
}
|
||||
|
@@ -40,7 +40,6 @@ import javax.security.sasl.RealmCallback;
|
||||
import org.alfresco.i18n.I18NUtil;
|
||||
import org.alfresco.repo.security.authentication.AbstractAuthenticationComponent;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.service.Managed;
|
||||
|
||||
/**
|
||||
* JAAS based authentication
|
||||
@@ -104,14 +103,12 @@ public class JAASAuthenticationComponent extends AbstractAuthenticationComponent
|
||||
|
||||
// Springification
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setJaasConfigEntryName(String jaasConfigEntryName)
|
||||
{
|
||||
this.jaasConfigEntryName = jaasConfigEntryName;
|
||||
}
|
||||
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setRealm(String realm)
|
||||
{
|
||||
this.realm = realm;
|
||||
|
@@ -29,7 +29,6 @@ import javax.naming.directory.InitialDirContext;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AbstractAuthenticationComponent;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.service.Managed;
|
||||
|
||||
/**
|
||||
* Currently expects the cn name of the user which is in a fixed location.
|
||||
@@ -51,25 +50,21 @@ public class LDAPAuthenticationComponentImpl extends AbstractAuthenticationCompo
|
||||
super();
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setLDAPInitialDirContextFactory(LDAPInitialDirContextFactory ldapInitialDirContextFactory)
|
||||
{
|
||||
this.ldapInitialContextFactory = ldapInitialDirContextFactory;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setUserNameFormat(String userNameFormat)
|
||||
{
|
||||
this.userNameFormat = userNameFormat;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setEscapeCommasInBind(boolean escapeCommasInBind)
|
||||
{
|
||||
this.escapeCommasInBind = escapeCommasInBind;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setEscapeCommasInUid(boolean escapeCommasInUid)
|
||||
{
|
||||
this.escapeCommasInUid = escapeCommasInUid;
|
||||
|
@@ -38,7 +38,6 @@ import javax.naming.directory.BasicAttributes;
|
||||
import javax.naming.directory.InitialDirContext;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.service.Managed;
|
||||
import org.alfresco.util.ApplicationContextHelper;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -61,7 +60,6 @@ public class LDAPInitialDirContextFactoryImpl implements LDAPInitialDirContextFa
|
||||
super();
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setInitialDirContextEnvironment(Map<String, String> initialDirContextEnvironment)
|
||||
{
|
||||
this.initialDirContextEnvironment = initialDirContextEnvironment;
|
||||
|
@@ -44,7 +44,6 @@ import javax.transaction.UserTransaction;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.importer.ExportSource;
|
||||
import org.alfresco.repo.importer.ExportSourceImporterException;
|
||||
import org.alfresco.service.Managed;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.namespace.NamespaceService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
@@ -85,25 +84,21 @@ public class LDAPPersonExportSource implements ExportSource
|
||||
super();
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setPersonQuery(String personQuery)
|
||||
{
|
||||
this.personQuery = personQuery;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setSearchBase(String searchBase)
|
||||
{
|
||||
this.searchBase = searchBase;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setUserIdAttributeName(String userIdAttributeName)
|
||||
{
|
||||
this.userIdAttributeName = userIdAttributeName;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setLDAPInitialDirContextFactory(LDAPInitialDirContextFactory ldapInitialDirContextFactory)
|
||||
{
|
||||
this.ldapInitialContextFactory = ldapInitialDirContextFactory;
|
||||
@@ -114,7 +109,6 @@ public class LDAPPersonExportSource implements ExportSource
|
||||
this.personService = personService;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAttributeDefaults(Map<String, String> attributeDefaults)
|
||||
{
|
||||
this.attributeDefaults = attributeDefaults;
|
||||
@@ -125,13 +119,11 @@ public class LDAPPersonExportSource implements ExportSource
|
||||
this.namespaceService = namespaceService;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setAttributeMapping(Map<String, String> attributeMapping)
|
||||
{
|
||||
this.attributeMapping = attributeMapping;
|
||||
}
|
||||
|
||||
@Managed(category="Security")
|
||||
public void setErrorOnMissingUID(boolean errorOnMissingUID)
|
||||
{
|
||||
this.errorOnMissingUID = errorOnMissingUID;
|
||||
@@ -175,7 +167,7 @@ public class LDAPPersonExportSource implements ExportSource
|
||||
|
||||
userSearchCtls.setCountLimit(Integer.MAX_VALUE);
|
||||
|
||||
NamingEnumeration searchResults = ctx.search(searchBase, personQuery, userSearchCtls);
|
||||
NamingEnumeration<SearchResult> searchResults = ctx.search(searchBase, personQuery, userSearchCtls);
|
||||
RESULT_LOOP: while (searchResults.hasMoreElements())
|
||||
{
|
||||
SearchResult result = (SearchResult) searchResults.next();
|
||||
|
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.repo.security.authentication.ntlm;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.repo.security.authentication.NTLMMode;
|
||||
|
||||
/**
|
||||
* An specialized {@link AuthenticationComponent} that is capable of handling NTLM authentication directly, either by
|
||||
* 'passing through' to a domain server or by validating an MD4 hashed password. Unlike other authentication methods,
|
||||
* these operations cannot be chained and must be handled by a specific authentication component.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public interface NLTMAuthenticator extends AuthenticationComponent
|
||||
{
|
||||
/**
|
||||
* Authenticate using a token.
|
||||
*
|
||||
* @param token
|
||||
* Authentication
|
||||
* @return Authentication
|
||||
* @throws AuthenticationException
|
||||
* the authentication exception
|
||||
*/
|
||||
public Authentication authenticate(Authentication token) throws AuthenticationException;
|
||||
|
||||
/**
|
||||
* Get the enum that describes NTLM integration.
|
||||
*
|
||||
* @return the NTLM mode
|
||||
*/
|
||||
public NTLMMode getNTLMMode();
|
||||
|
||||
/**
|
||||
* Get the MD4 password hash, as required by NTLM based authentication methods.
|
||||
*
|
||||
* @param userName
|
||||
* the user name
|
||||
* @return the m d4 hashed password
|
||||
*/
|
||||
public String getMD4HashedPassword(String userName);
|
||||
}
|
@@ -67,7 +67,7 @@ import org.springframework.beans.factory.InitializingBean;
|
||||
*
|
||||
* @author GKSpencer
|
||||
*/
|
||||
public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationComponent implements InitializingBean
|
||||
public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationComponent implements NLTMAuthenticator, InitializingBean
|
||||
{
|
||||
// Logging
|
||||
|
||||
|
@@ -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.repo.security.authentication.subsystems;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.management.subsystems.ChildApplicationContextManager;
|
||||
import org.alfresco.repo.security.authentication.AbstractChainingAuthenticationComponent;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* An authentication component that chains across beans in multiple child application contexts corresponding to
|
||||
* different 'subsystems' in a chain determined by a {@link ChildApplicationContextManager}.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class SubsystemChainingAuthenticationComponent extends AbstractChainingAuthenticationComponent
|
||||
{
|
||||
private ChildApplicationContextManager applicationContextManager;
|
||||
private String sourceBeanName;
|
||||
|
||||
/**
|
||||
* @param applicationContextManager
|
||||
* the applicationContextManager to set
|
||||
*/
|
||||
public void setApplicationContextManager(ChildApplicationContextManager applicationContextManager)
|
||||
{
|
||||
this.applicationContextManager = applicationContextManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the bean to look up in the child application contexts.
|
||||
*
|
||||
* @param sourceBeanName
|
||||
* the bean name
|
||||
*/
|
||||
public void setSourceBeanName(String sourceBeanName)
|
||||
{
|
||||
this.sourceBeanName = sourceBeanName;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see
|
||||
* org.alfresco.repo.security.authentication.AbstractChainingAuthenticationCompent#getUsableAuthenticationComponents
|
||||
* ()
|
||||
*/
|
||||
@Override
|
||||
protected Collection<AuthenticationComponent> getUsableAuthenticationComponents()
|
||||
{
|
||||
List<AuthenticationComponent> result = new LinkedList<AuthenticationComponent>();
|
||||
for (String instance : this.applicationContextManager.getInstanceIds())
|
||||
{
|
||||
ApplicationContext context = this.applicationContextManager.getApplicationContext(instance);
|
||||
try
|
||||
{
|
||||
result.add((AuthenticationComponent) context.getBean(sourceBeanName));
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException e)
|
||||
{
|
||||
// Ignore and continue
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.repo.security.authentication.subsystems;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.alfresco.repo.management.subsystems.ChildApplicationContextManager;
|
||||
import org.alfresco.repo.security.authentication.AbstractChainingAuthenticationService;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* An authentication service that chains across beans in multiple child application contexts corresponding to different
|
||||
* 'subsystems' in a chain determined by a {@link ChildApplicationContextManager}. The first authentication service in
|
||||
* the chain will always be considered to be the 'mutable' authentication service.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class SubsystemChainingAuthenticationService extends AbstractChainingAuthenticationService
|
||||
{
|
||||
/** The application context manager. */
|
||||
private ChildApplicationContextManager applicationContextManager;
|
||||
|
||||
/** The source bean name. */
|
||||
private String sourceBeanName;
|
||||
|
||||
/**
|
||||
* Sets the application context manager.
|
||||
*
|
||||
* @param applicationContextManager
|
||||
* the applicationContextManager to set
|
||||
*/
|
||||
public void setApplicationContextManager(ChildApplicationContextManager applicationContextManager)
|
||||
{
|
||||
this.applicationContextManager = applicationContextManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the bean to look up in the child application contexts.
|
||||
*
|
||||
* @param sourceBeanName
|
||||
* the bean name
|
||||
*/
|
||||
public void setSourceBeanName(String sourceBeanName)
|
||||
{
|
||||
this.sourceBeanName = sourceBeanName;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see
|
||||
* org.alfresco.repo.security.authentication.AbstractChainingAuthenticationService#getMutableAuthenticationService()
|
||||
*/
|
||||
@Override
|
||||
public AuthenticationService getMutableAuthenticationService()
|
||||
{
|
||||
for (String instance : this.applicationContextManager.getInstanceIds())
|
||||
{
|
||||
ApplicationContext context = this.applicationContextManager.getApplicationContext(instance);
|
||||
try
|
||||
{
|
||||
return (AuthenticationService) context.getBean(sourceBeanName);
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException e)
|
||||
{
|
||||
// Ignore and continue
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see
|
||||
* org.alfresco.repo.security.authentication.AbstractChainingAuthenticationService#getUsableAuthenticationServices()
|
||||
*/
|
||||
@Override
|
||||
protected List<AuthenticationService> getUsableAuthenticationServices()
|
||||
{
|
||||
List<AuthenticationService> result = new LinkedList<AuthenticationService>();
|
||||
for (String instance : this.applicationContextManager.getInstanceIds())
|
||||
{
|
||||
ApplicationContext context = this.applicationContextManager.getApplicationContext(instance);
|
||||
try
|
||||
{
|
||||
result.add((AuthenticationService) context.getBean(sourceBeanName));
|
||||
}
|
||||
catch (NoSuchBeanDefinitionException e)
|
||||
{
|
||||
// Ignore and continue
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user