mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merged V2.2 to HEAD
8014: Extended support for RunAs - real and effctive authorities 8032: Build Fix - there is a special check for the effective user 8094: Fix for NPE in AuthenticationUtil noticed on first upgrade from V2.1.x to V2.2 git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8471 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -30,6 +30,7 @@ import java.util.Map;
|
|||||||
import org.alfresco.repo.avm.AVMDAOs;
|
import org.alfresco.repo.avm.AVMDAOs;
|
||||||
import org.alfresco.repo.avm.AVMNodeConverter;
|
import org.alfresco.repo.avm.AVMNodeConverter;
|
||||||
import org.alfresco.repo.domain.PropertyValue;
|
import org.alfresco.repo.domain.PropertyValue;
|
||||||
|
import org.alfresco.repo.security.authentication.AuthenticationUtil;
|
||||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||||
import org.alfresco.repo.workflow.jbpm.JBPMNode;
|
import org.alfresco.repo.workflow.jbpm.JBPMNode;
|
||||||
import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler;
|
import org.alfresco.repo.workflow.jbpm.JBPMSpringActionHandler;
|
||||||
@@ -47,9 +48,7 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
import org.jbpm.graph.exe.ExecutionContext;
|
import org.jbpm.graph.exe.ExecutionContext;
|
||||||
import org.springframework.beans.factory.BeanFactory;
|
import org.springframework.beans.factory.BeanFactory;
|
||||||
|
|
||||||
public class AVMSubmitPackageHandler
|
public class AVMSubmitPackageHandler extends JBPMSpringActionHandler implements Serializable
|
||||||
extends JBPMSpringActionHandler
|
|
||||||
implements Serializable
|
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 4113360751217684995L;
|
private static final long serialVersionUID = 4113360751217684995L;
|
||||||
|
|
||||||
@@ -65,14 +64,15 @@ public class AVMSubmitPackageHandler
|
|||||||
private AVMLockingService fAVMLockingService;
|
private AVMLockingService fAVMLockingService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The AVMSubmitTransactionListener instance
|
* The AVMSubmitTransactionListener instance (for JMX notification of virtualization server after commit/rollback).
|
||||||
* (for JMX notification of virtualization server after commit/rollback).
|
|
||||||
*/
|
*/
|
||||||
private AVMSubmitTransactionListener fAVMSubmitTransactionListener;
|
private AVMSubmitTransactionListener fAVMSubmitTransactionListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize service references.
|
* Initialize service references.
|
||||||
* @param factory The BeanFactory to get references from.
|
*
|
||||||
|
* @param factory
|
||||||
|
* The BeanFactory to get references from.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void initialiseHandler(final BeanFactory factory)
|
protected void initialiseHandler(final BeanFactory factory)
|
||||||
@@ -87,10 +87,11 @@ public class AVMSubmitPackageHandler
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Do the actual work.
|
* Do the actual work.
|
||||||
* @param executionContext The context to get stuff from.
|
*
|
||||||
|
* @param executionContext
|
||||||
|
* The context to get stuff from.
|
||||||
*/
|
*/
|
||||||
public void execute(final ExecutionContext executionContext)
|
public void execute(final ExecutionContext executionContext) throws Exception
|
||||||
throws Exception
|
|
||||||
{
|
{
|
||||||
// TODO: Allow submit parameters to be passed into this action handler
|
// TODO: Allow submit parameters to be passed into this action handler
|
||||||
// rather than pulling directly from execution context
|
// rather than pulling directly from execution context
|
||||||
@@ -106,7 +107,6 @@ public class AVMSubmitPackageHandler
|
|||||||
final String description = (String) executionContext.getContextInstance().getVariable("bpm_workflowDescription");
|
final String description = (String) executionContext.getContextInstance().getVariable("bpm_workflowDescription");
|
||||||
final String tag = (String) executionContext.getContextInstance().getVariable("wcmwf_label");
|
final String tag = (String) executionContext.getContextInstance().getVariable("wcmwf_label");
|
||||||
|
|
||||||
|
|
||||||
final Map<QName, PropertyValue> dnsProperties = this.fAVMService.queryStorePropertyKey(targetPath.split(":")[0], QName.createQName(null, ".dns%"));
|
final Map<QName, PropertyValue> dnsProperties = this.fAVMService.queryStorePropertyKey(targetPath.split(":")[0], QName.createQName(null, ".dns%"));
|
||||||
String webProject = dnsProperties.keySet().iterator().next().getLocalName();
|
String webProject = dnsProperties.keySet().iterator().next().getLocalName();
|
||||||
webProject = webProject.substring(webProject.lastIndexOf('.') + 1, webProject.length());
|
webProject = webProject.substring(webProject.lastIndexOf('.') + 1, webProject.length());
|
||||||
@@ -130,9 +130,18 @@ public class AVMSubmitPackageHandler
|
|||||||
|
|
||||||
AlfrescoTransactionSupport.bindResource("staging_diffs", stagingDiffs);
|
AlfrescoTransactionSupport.bindResource("staging_diffs", stagingDiffs);
|
||||||
|
|
||||||
|
// Workflow does this as system as the staging area has restricted access
|
||||||
|
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>()
|
||||||
|
{
|
||||||
|
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
fAVMSyncService.update(stagingDiffs, null, false, false, true, true, tag, description);
|
fAVMSyncService.update(stagingDiffs, null, false, false, true, true, tag, description);
|
||||||
AVMDAOs.Instance().fAVMNodeDAO.flush();
|
AVMDAOs.Instance().fAVMNodeDAO.flush();
|
||||||
fAVMSyncService.flatten(pkgPath.getSecond(), targetPath);
|
fAVMSyncService.flatten(pkgPath.getSecond(), targetPath);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, AuthenticationUtil.getSystemUserName());
|
||||||
|
|
||||||
// flatten source folder where changes were submitted from
|
// flatten source folder where changes were submitted from
|
||||||
if (from != null && from.length() > 0)
|
if (from != null && from.length() > 0)
|
||||||
@@ -149,8 +158,7 @@ public class AVMSubmitPackageHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively remove locks from a path. Walking child folders looking for files
|
* Recursively remove locks from a path. Walking child folders looking for files to remove locks from.
|
||||||
* to remove locks from.
|
|
||||||
*/
|
*/
|
||||||
private void recursivelyRemoveLocks(final String webProject, final int version, final String path)
|
private void recursivelyRemoveLocks(final String webProject, final int version, final String path)
|
||||||
{
|
{
|
||||||
|
@@ -474,8 +474,9 @@ public class LockServiceImpl implements LockService,
|
|||||||
// Ensure we have found a node reference
|
// Ensure we have found a node reference
|
||||||
if (nodeRef != null && userName != null)
|
if (nodeRef != null && userName != null)
|
||||||
{
|
{
|
||||||
|
String effectiveUserName = AuthenticationUtil.getCurrentEffectiveUserName();
|
||||||
// Check to see if should just ignore this node - note: special MT System due to AuditableAspect
|
// Check to see if should just ignore this node - note: special MT System due to AuditableAspect
|
||||||
if (!(this.ignoreNodeRefs.contains(nodeRef) || tenantService.getBaseNameUser(userName).equals(AuthenticationUtil.getSystemUserName())))
|
if (!(this.ignoreNodeRefs.contains(nodeRef) || tenantService.getBaseNameUser(effectiveUserName).equals(AuthenticationUtil.getSystemUserName())))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 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 recieved 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 net.sf.acegisecurity.Authentication;
|
||||||
|
import net.sf.acegisecurity.context.security.SecureContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extensions for the Alfresco security context.
|
||||||
|
*
|
||||||
|
* This is based on the Linux model and supports real, effective and stored authorities
|
||||||
|
*
|
||||||
|
* The real authority is used for auditing and reporting who the user is etc.
|
||||||
|
* The effective authority is used for permission checks.
|
||||||
|
*
|
||||||
|
* RunAs support leaves the real authority and changes only the effective authority
|
||||||
|
* That means "special" code can run code as system but still be audited as Joe
|
||||||
|
*
|
||||||
|
* In the future scrips etc can support a setUId flag and run as the owner of the script.
|
||||||
|
* If the script chooses to do this ....
|
||||||
|
* A method invocation could do the same (after entry security checks)
|
||||||
|
*
|
||||||
|
* TODO: extent runAs to take a nodeRef context - it can then set the stored atc and set this as effective if required.
|
||||||
|
*
|
||||||
|
* @author andyh
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public interface AlfrescoSecureContext extends SecureContext
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the effective authentication - used for permission checks
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Authentication getEffectiveAuthentication();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the real authenticaiton - used for auditing and everything else
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Authentication getRealAuthentication();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the store authentication - used for setuid scripts and methods
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Authentication getStoredAuthentication();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the effective authentication held by the context
|
||||||
|
*
|
||||||
|
* @param effictiveAuthentication
|
||||||
|
*/
|
||||||
|
public void setEffectiveAuthentication(Authentication effictiveAuthentication);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the real authentication held by the context
|
||||||
|
*
|
||||||
|
* @param realAuthentication
|
||||||
|
*/
|
||||||
|
public void setRealAuthentication(Authentication realAuthentication);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the stored authentication held by the context
|
||||||
|
*
|
||||||
|
* @param storedAuthentication
|
||||||
|
*/
|
||||||
|
public void setStoredAuthentication(Authentication storedAuthentication);
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 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 recieved 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 net.sf.acegisecurity.Authentication;
|
||||||
|
import net.sf.acegisecurity.context.ContextInvalidException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hold an Alfresco extended security context
|
||||||
|
*
|
||||||
|
* @author andyh
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class AlfrescoSecureContextImpl implements AlfrescoSecureContext
|
||||||
|
{
|
||||||
|
Authentication storedAuthentication;
|
||||||
|
|
||||||
|
Authentication realAuthentication;
|
||||||
|
|
||||||
|
Authentication effectiveAuthentication;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ACEGI
|
||||||
|
*/
|
||||||
|
public Authentication getAuthentication()
|
||||||
|
{
|
||||||
|
return getEffectiveAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ACEGI
|
||||||
|
*/
|
||||||
|
public void setAuthentication(Authentication newAuthentication)
|
||||||
|
{
|
||||||
|
setEffectiveAuthentication(newAuthentication);
|
||||||
|
setRealAuthentication(newAuthentication);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ACEGI
|
||||||
|
*/
|
||||||
|
public void validate() throws ContextInvalidException
|
||||||
|
{
|
||||||
|
if (effectiveAuthentication == null)
|
||||||
|
{
|
||||||
|
throw new ContextInvalidException("Effective authentication not set");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Authentication getEffectiveAuthentication()
|
||||||
|
{
|
||||||
|
return effectiveAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Authentication getRealAuthentication()
|
||||||
|
{
|
||||||
|
return realAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Authentication getStoredAuthentication()
|
||||||
|
{
|
||||||
|
return storedAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEffectiveAuthentication(Authentication effictiveAuthentication)
|
||||||
|
{
|
||||||
|
this.effectiveAuthentication = effictiveAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRealAuthentication(Authentication realAuthentication)
|
||||||
|
{
|
||||||
|
this.realAuthentication = realAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStoredAuthentication(Authentication storedAuthentication)
|
||||||
|
{
|
||||||
|
this.storedAuthentication = storedAuthentication;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode()
|
||||||
|
{
|
||||||
|
final int PRIME = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = PRIME * result + ((effectiveAuthentication == null) ? 0 : effectiveAuthentication.hashCode());
|
||||||
|
result = PRIME * result + ((realAuthentication == null) ? 0 : realAuthentication.hashCode());
|
||||||
|
result = PRIME * result + ((storedAuthentication == null) ? 0 : storedAuthentication.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj)
|
||||||
|
{
|
||||||
|
if (this == obj)
|
||||||
|
return true;
|
||||||
|
if (obj == null)
|
||||||
|
return false;
|
||||||
|
if (getClass() != obj.getClass())
|
||||||
|
return false;
|
||||||
|
final AlfrescoSecureContextImpl other = (AlfrescoSecureContextImpl) obj;
|
||||||
|
if (effectiveAuthentication == null)
|
||||||
|
{
|
||||||
|
if (other.effectiveAuthentication != null)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (!effectiveAuthentication.equals(other.effectiveAuthentication))
|
||||||
|
return false;
|
||||||
|
if (realAuthentication == null)
|
||||||
|
{
|
||||||
|
if (other.realAuthentication != null)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (!realAuthentication.equals(other.realAuthentication))
|
||||||
|
return false;
|
||||||
|
if (storedAuthentication == null)
|
||||||
|
{
|
||||||
|
if (other.storedAuthentication != null)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (!storedAuthentication.equals(other.storedAuthentication))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
if (realAuthentication == null)
|
||||||
|
{
|
||||||
|
builder.append("Real authenticaion = null");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.append("Real authenticaion = " + realAuthentication.toString());
|
||||||
|
}
|
||||||
|
builder.append(", ");
|
||||||
|
|
||||||
|
if (effectiveAuthentication == null)
|
||||||
|
{
|
||||||
|
builder.append("Effective authenticaion = null");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.append("Effective authenticaion = " + effectiveAuthentication.toString());
|
||||||
|
}
|
||||||
|
builder.append(", ");
|
||||||
|
|
||||||
|
if (storedAuthentication == null)
|
||||||
|
{
|
||||||
|
builder.append("Stored authenticaion = null");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
builder.append("Stored authenticaion = " + storedAuthentication.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -79,16 +79,31 @@ public abstract class AuthenticationUtil
|
|||||||
return setCurrentUser(userName, getDefaultUserDetails(userName));
|
return setCurrentUser(userName, getDefaultUserDetails(userName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Authentication setCurrentRealUser(String userName)
|
||||||
|
{
|
||||||
|
return setCurrentRealUser(userName, getDefaultUserDetails(userName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Authentication setCurrentEffectiveUser(String userName)
|
||||||
|
{
|
||||||
|
return setCurrentEffectiveUser(userName, getDefaultUserDetails(userName));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Authentication setCurrentStoredUser(String userName)
|
||||||
|
{
|
||||||
|
return setCurrentStoredUser(userName, getDefaultUserDetails(userName));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Explicitly set the current user to be authenticated.
|
* Explicitly set the current user to be authenticated.
|
||||||
*
|
*
|
||||||
* @param userName - String user id
|
* @param userName -
|
||||||
* @param providedDetails - provided details for the user
|
* String user id
|
||||||
*
|
* @param providedDetails -
|
||||||
|
* provided details for the user
|
||||||
* @return Authentication
|
* @return Authentication
|
||||||
*/
|
*/
|
||||||
public static Authentication setCurrentUser(String userName, UserDetails providedDetails)
|
public static Authentication setCurrentUser(String userName, UserDetails providedDetails) throws AuthenticationException
|
||||||
throws AuthenticationException
|
|
||||||
{
|
{
|
||||||
if (userName == null)
|
if (userName == null)
|
||||||
{
|
{
|
||||||
@@ -96,6 +111,71 @@ public abstract class AuthenticationUtil
|
|||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
UsernamePasswordAuthenticationToken auth = getAuthenticationToken(userName, providedDetails);
|
||||||
|
return setCurrentAuthentication(auth);
|
||||||
|
}
|
||||||
|
catch (net.sf.acegisecurity.AuthenticationException ae)
|
||||||
|
{
|
||||||
|
throw new AuthenticationException(ae.getMessage(), ae);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Authentication setCurrentRealUser(String userName, UserDetails providedDetails) throws AuthenticationException
|
||||||
|
{
|
||||||
|
if (userName == null)
|
||||||
|
{
|
||||||
|
throw new AuthenticationException("Null user name");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UsernamePasswordAuthenticationToken auth = getAuthenticationToken(userName, providedDetails);
|
||||||
|
return setCurrentRealAuthentication(auth);
|
||||||
|
}
|
||||||
|
catch (net.sf.acegisecurity.AuthenticationException ae)
|
||||||
|
{
|
||||||
|
throw new AuthenticationException(ae.getMessage(), ae);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Authentication setCurrentEffectiveUser(String userName, UserDetails providedDetails) throws AuthenticationException
|
||||||
|
{
|
||||||
|
if (userName == null)
|
||||||
|
{
|
||||||
|
throw new AuthenticationException("Null user name");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UsernamePasswordAuthenticationToken auth = getAuthenticationToken(userName, providedDetails);
|
||||||
|
return setCurrentEffectiveAuthentication(auth);
|
||||||
|
}
|
||||||
|
catch (net.sf.acegisecurity.AuthenticationException ae)
|
||||||
|
{
|
||||||
|
throw new AuthenticationException(ae.getMessage(), ae);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Authentication setCurrentStoredUser(String userName, UserDetails providedDetails) throws AuthenticationException
|
||||||
|
{
|
||||||
|
if (userName == null)
|
||||||
|
{
|
||||||
|
throw new AuthenticationException("Null user name");
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UsernamePasswordAuthenticationToken auth = getAuthenticationToken(userName, providedDetails);
|
||||||
|
return setCurrentStoredAuthentication(auth);
|
||||||
|
}
|
||||||
|
catch (net.sf.acegisecurity.AuthenticationException ae)
|
||||||
|
{
|
||||||
|
throw new AuthenticationException(ae.getMessage(), ae);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UsernamePasswordAuthenticationToken getAuthenticationToken(String userName, UserDetails providedDetails)
|
||||||
{
|
{
|
||||||
UserDetails ud = null;
|
UserDetails ud = null;
|
||||||
if (userName.equals(SYSTEM_USER_NAME))
|
if (userName.equals(SYSTEM_USER_NAME))
|
||||||
@@ -121,16 +201,10 @@ public abstract class AuthenticationUtil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(ud, "", ud
|
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(ud, "", ud.getAuthorities());
|
||||||
.getAuthorities());
|
|
||||||
auth.setDetails(ud);
|
auth.setDetails(ud);
|
||||||
auth.setAuthenticated(true);
|
auth.setAuthenticated(true);
|
||||||
return setCurrentAuthentication(auth);
|
return auth;
|
||||||
}
|
|
||||||
catch (net.sf.acegisecurity.AuthenticationException ae)
|
|
||||||
{
|
|
||||||
throw new AuthenticationException(ae.getMessage(), ae);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -163,17 +237,18 @@ public abstract class AuthenticationUtil
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
Context context = ContextHolder.getContext();
|
Context context = ContextHolder.getContext();
|
||||||
SecureContext sc = null;
|
AlfrescoSecureContext sc = null;
|
||||||
if ((context == null) || !(context instanceof SecureContext))
|
if ((context == null) || !(context instanceof AlfrescoSecureContext))
|
||||||
{
|
{
|
||||||
sc = new SecureContextImpl();
|
sc = new AlfrescoSecureContextImpl();
|
||||||
ContextHolder.setContext(sc);
|
ContextHolder.setContext(sc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
sc = (SecureContext) context;
|
sc = (AlfrescoSecureContext) context;
|
||||||
}
|
}
|
||||||
authentication.setAuthenticated(true);
|
authentication.setAuthenticated(true);
|
||||||
|
// Sets real and effective
|
||||||
sc.setAuthentication(authentication);
|
sc.setAuthentication(authentication);
|
||||||
|
|
||||||
// Support for logging tenant domain / username (via log4j NDC)
|
// Support for logging tenant domain / username (via log4j NDC)
|
||||||
@@ -211,6 +286,84 @@ public abstract class AuthenticationUtil
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Authentication setCurrentRealAuthentication(Authentication authentication)
|
||||||
|
{
|
||||||
|
if (authentication == null)
|
||||||
|
{
|
||||||
|
clearCurrentSecurityContext();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Context context = ContextHolder.getContext();
|
||||||
|
AlfrescoSecureContext sc = null;
|
||||||
|
if ((context == null) || !(context instanceof AlfrescoSecureContext))
|
||||||
|
{
|
||||||
|
sc = new AlfrescoSecureContextImpl();
|
||||||
|
ContextHolder.setContext(sc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sc = (AlfrescoSecureContext) context;
|
||||||
|
}
|
||||||
|
authentication.setAuthenticated(true);
|
||||||
|
sc.setRealAuthentication(authentication);
|
||||||
|
return authentication;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Authentication setCurrentEffectiveAuthentication(Authentication authentication)
|
||||||
|
{
|
||||||
|
if (authentication == null)
|
||||||
|
{
|
||||||
|
clearCurrentSecurityContext();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Context context = ContextHolder.getContext();
|
||||||
|
AlfrescoSecureContext sc = null;
|
||||||
|
if ((context == null) || !(context instanceof AlfrescoSecureContext))
|
||||||
|
{
|
||||||
|
sc = new AlfrescoSecureContextImpl();
|
||||||
|
ContextHolder.setContext(sc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sc = (AlfrescoSecureContext) context;
|
||||||
|
}
|
||||||
|
authentication.setAuthenticated(true);
|
||||||
|
sc.setEffectiveAuthentication(authentication);
|
||||||
|
return authentication;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Authentication setCurrentStoredAuthentication(Authentication authentication)
|
||||||
|
{
|
||||||
|
if (authentication == null)
|
||||||
|
{
|
||||||
|
clearCurrentSecurityContext();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Context context = ContextHolder.getContext();
|
||||||
|
AlfrescoSecureContext sc = null;
|
||||||
|
if ((context == null) || !(context instanceof AlfrescoSecureContext))
|
||||||
|
{
|
||||||
|
sc = new AlfrescoSecureContextImpl();
|
||||||
|
ContextHolder.setContext(sc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sc = (AlfrescoSecureContext) context;
|
||||||
|
}
|
||||||
|
authentication.setAuthenticated(true);
|
||||||
|
sc.setStoredAuthentication(authentication);
|
||||||
|
return authentication;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current authentication context
|
* Get the current authentication context
|
||||||
*
|
*
|
||||||
@@ -218,13 +371,56 @@ public abstract class AuthenticationUtil
|
|||||||
* @throws AuthenticationException
|
* @throws AuthenticationException
|
||||||
*/
|
*/
|
||||||
public static Authentication getCurrentAuthentication() throws AuthenticationException
|
public static Authentication getCurrentAuthentication() throws AuthenticationException
|
||||||
|
{
|
||||||
|
return getCurrentRealAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current real authentication context
|
||||||
|
*
|
||||||
|
* @return Authentication
|
||||||
|
* @throws AuthenticationException
|
||||||
|
*/
|
||||||
|
public static Authentication getCurrentRealAuthentication() throws AuthenticationException
|
||||||
{
|
{
|
||||||
Context context = ContextHolder.getContext();
|
Context context = ContextHolder.getContext();
|
||||||
if ((context == null) || !(context instanceof SecureContext))
|
if ((context == null) || !(context instanceof AlfrescoSecureContext))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return ((SecureContext) context).getAuthentication();
|
return ((AlfrescoSecureContext) context).getRealAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current effective authentication context
|
||||||
|
*
|
||||||
|
* @return Authentication
|
||||||
|
* @throws AuthenticationException
|
||||||
|
*/
|
||||||
|
public static Authentication getCurrentEffectiveAuthentication() throws AuthenticationException
|
||||||
|
{
|
||||||
|
Context context = ContextHolder.getContext();
|
||||||
|
if ((context == null) || !(context instanceof AlfrescoSecureContext))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ((AlfrescoSecureContext) context).getEffectiveAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current stored authentication context
|
||||||
|
*
|
||||||
|
* @return Authentication
|
||||||
|
* @throws AuthenticationException
|
||||||
|
*/
|
||||||
|
public static Authentication getCurrentStoredAuthentication() throws AuthenticationException
|
||||||
|
{
|
||||||
|
Context context = ContextHolder.getContext();
|
||||||
|
if ((context == null) || !(context instanceof AlfrescoSecureContext))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ((AlfrescoSecureContext) context).getStoredAuthentication();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -234,13 +430,53 @@ public abstract class AuthenticationUtil
|
|||||||
* @throws AuthenticationException
|
* @throws AuthenticationException
|
||||||
*/
|
*/
|
||||||
public static String getCurrentUserName() throws AuthenticationException
|
public static String getCurrentUserName() throws AuthenticationException
|
||||||
|
{
|
||||||
|
return getCurrentRealUserName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCurrentRealUserName() throws AuthenticationException
|
||||||
{
|
{
|
||||||
Context context = ContextHolder.getContext();
|
Context context = ContextHolder.getContext();
|
||||||
if ((context == null) || !(context instanceof SecureContext))
|
if ((context == null) || !(context instanceof AlfrescoSecureContext))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return getUserName(((SecureContext) context).getAuthentication());
|
AlfrescoSecureContext ctx = (AlfrescoSecureContext) context;
|
||||||
|
if (ctx.getRealAuthentication() == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getUserName(ctx.getRealAuthentication());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCurrentEffectiveUserName() throws AuthenticationException
|
||||||
|
{
|
||||||
|
Context context = ContextHolder.getContext();
|
||||||
|
if ((context == null) || !(context instanceof AlfrescoSecureContext))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
AlfrescoSecureContext ctx = (AlfrescoSecureContext) context;
|
||||||
|
if (ctx.getEffectiveAuthentication() == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getUserName(ctx.getEffectiveAuthentication());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCurrentStoredUserName() throws AuthenticationException
|
||||||
|
{
|
||||||
|
Context context = ContextHolder.getContext();
|
||||||
|
if ((context == null) || !(context instanceof AlfrescoSecureContext))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
AlfrescoSecureContext ctx = (AlfrescoSecureContext) context;
|
||||||
|
if (ctx.getStoredAuthentication() == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getUserName(ctx.getStoredAuthentication());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -304,33 +540,42 @@ public abstract class AuthenticationUtil
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a unit of work as a given user. The thread's authenticated user will be
|
* Execute a unit of work as a given user. The thread's authenticated user will be returned to its normal state
|
||||||
* returned to its normal state after the call.
|
* after the call.
|
||||||
*
|
*
|
||||||
* @param runAsWork the unit of work to do
|
* @param runAsWork
|
||||||
* @param uid the user ID
|
* the unit of work to do
|
||||||
|
* @param uid
|
||||||
|
* the user ID
|
||||||
* @return Returns the work's return value
|
* @return Returns the work's return value
|
||||||
*/
|
*/
|
||||||
public static <R> R runAs(RunAsWork<R> runAsWork, String uid)
|
public static <R> R runAs(RunAsWork<R> runAsWork, String uid)
|
||||||
{
|
{
|
||||||
String currentUser = AuthenticationUtil.getCurrentUserName();
|
String effectiveUser = AuthenticationUtil.getCurrentEffectiveUserName();
|
||||||
|
String realUser = AuthenticationUtil.getCurrentRealUserName();
|
||||||
|
|
||||||
R result = null;
|
R result = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if ((currentUser != null) && (isMtEnabled()))
|
|
||||||
|
if ((realUser != null) && (isMtEnabled()))
|
||||||
{
|
{
|
||||||
int idx = currentUser.indexOf(TenantService.SEPARATOR);
|
int idx = realUser.indexOf(TenantService.SEPARATOR);
|
||||||
if ((idx != -1) && (idx < (currentUser.length()-1)))
|
if ((idx != -1) && (idx < (realUser.length() - 1)))
|
||||||
{
|
{
|
||||||
if (uid.equals(AuthenticationUtil.getSystemUserName()))
|
if (uid.equals(AuthenticationUtil.getSystemUserName()))
|
||||||
{
|
{
|
||||||
uid = uid + TenantService.SEPARATOR + currentUser.substring(idx+1);
|
uid = uid + TenantService.SEPARATOR + realUser.substring(idx + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AuthenticationUtil.setCurrentUser(uid);
|
if (realUser == null)
|
||||||
|
{
|
||||||
|
AuthenticationUtil.setCurrentRealUser(uid);
|
||||||
|
}
|
||||||
|
AuthenticationUtil.setCurrentEffectiveUser(uid);
|
||||||
|
|
||||||
result = runAsWork.doWork();
|
result = runAsWork.doWork();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -349,10 +594,13 @@ public abstract class AuthenticationUtil
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
AuthenticationUtil.clearCurrentSecurityContext();
|
if (realUser == null)
|
||||||
if (currentUser != null)
|
|
||||||
{
|
{
|
||||||
AuthenticationUtil.setCurrentUser(currentUser);
|
AuthenticationUtil.clearCurrentSecurityContext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AuthenticationUtil.setCurrentEffectiveUser(effectiveUser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -392,9 +392,19 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
perm = permIn;
|
perm = permIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(AuthenticationUtil.getCurrentEffectiveUserName() == null)
|
||||||
|
{
|
||||||
|
return AccessStatus.DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(AuthenticationUtil.getCurrentEffectiveUserName().equals(AuthenticationUtil.getSystemUserName()))
|
||||||
|
{
|
||||||
|
return AccessStatus.ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the current authentications
|
// Get the current authentications
|
||||||
// Use the smart authentication cache to improve permissions performance
|
// Use the smart authentication cache to improve permissions performance
|
||||||
Authentication auth = authenticationComponent.getCurrentAuthentication();
|
Authentication auth = AuthenticationUtil.getCurrentEffectiveAuthentication();
|
||||||
final Set<String> authorisations = getAuthorisations(auth, nodeRef);
|
final Set<String> authorisations = getAuthorisations(auth, nodeRef);
|
||||||
|
|
||||||
// If the node does not support the given permission there is no point
|
// If the node does not support the given permission there is no point
|
||||||
@@ -496,9 +506,19 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
return AccessStatus.DENIED;
|
return AccessStatus.DENIED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(AuthenticationUtil.getCurrentEffectiveUserName() == null)
|
||||||
|
{
|
||||||
|
return AccessStatus.DENIED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(AuthenticationUtil.getCurrentEffectiveUserName().equals(AuthenticationUtil.getSystemUserName()))
|
||||||
|
{
|
||||||
|
return AccessStatus.ALLOWED;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the current authentications
|
// Get the current authentications
|
||||||
// Use the smart authentication cache to improve permissions performance
|
// Use the smart authentication cache to improve permissions performance
|
||||||
Authentication auth = authenticationComponent.getCurrentAuthentication();
|
Authentication auth = AuthenticationUtil.getCurrentEffectiveAuthentication();
|
||||||
if (auth == null)
|
if (auth == null)
|
||||||
{
|
{
|
||||||
throw new IllegalStateException("Unauthenticated");
|
throw new IllegalStateException("Unauthenticated");
|
||||||
|
@@ -89,6 +89,34 @@ public class PermissionServiceTest extends AbstractPermissionTest
|
|||||||
allowAndyReadChildren = new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ_CHILDREN), "andy", AccessStatus.ALLOWED);
|
allowAndyReadChildren = new SimplePermissionEntry(rootNodeRef, getPermission(PermissionService.READ_CHILDREN), "andy", AccessStatus.ALLOWED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testRunAsRealAndEffectiveUsers()
|
||||||
|
{
|
||||||
|
runAs("admin");
|
||||||
|
|
||||||
|
final NodeRef n1 = nodeService.createNode(rootNodeRef, ContentModel.ASSOC_CHILDREN, QName.createQName("{namespace}one"), ContentModel.TYPE_FOLDER).getChildRef();
|
||||||
|
|
||||||
|
runAs("andy");
|
||||||
|
assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.DENIED);
|
||||||
|
|
||||||
|
assertEquals("andy", AuthenticationUtil.getCurrentRealUserName());
|
||||||
|
assertEquals("andy", AuthenticationUtil.getCurrentEffectiveUserName());
|
||||||
|
|
||||||
|
AuthenticationUtil.runAs(new AuthenticationUtil.RunAsWork<Object>() {
|
||||||
|
|
||||||
|
public Object doWork() throws Exception
|
||||||
|
{
|
||||||
|
assertTrue(permissionService.hasPermission(n1, getPermission(PermissionService.CONTRIBUTOR)) == AccessStatus.ALLOWED);
|
||||||
|
|
||||||
|
assertEquals("andy", AuthenticationUtil.getCurrentRealUserName());
|
||||||
|
assertEquals("admin", AuthenticationUtil.getCurrentEffectiveUserName());
|
||||||
|
return null;
|
||||||
|
}}, "admin");
|
||||||
|
|
||||||
|
assertEquals("andy", AuthenticationUtil.getCurrentRealUserName());
|
||||||
|
assertEquals("andy", AuthenticationUtil.getCurrentEffectiveUserName());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void testDefaultModelPermissions()
|
public void testDefaultModelPermissions()
|
||||||
{
|
{
|
||||||
runAs("admin");
|
runAs("admin");
|
||||||
|
Reference in New Issue
Block a user