Merged V3.0 to HEAD

12145: Merged V2.2 to V3.0 (AuthenticationUtil)
    12109: AuthenticationUtil and AuthenticationComponent refactor
  12152: Removed Lucene usage from lookup of 'sites' root folder
  12153: Fix InviteServiceTest by cleaning up leaking authentications
  12159: Fix for broken usage pattern of the Threadlocal values in recent AuthenticationUtil refactor.


git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@12508 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jan Vonka
2008-12-19 12:15:59 +00:00
parent 4fe9a4f345
commit 3ab0ccf0df
14 changed files with 53 additions and 35 deletions

View File

@@ -52,7 +52,7 @@ public class AuthenticationInterceptor extends AbstractSoapInterceptor
WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) secRes.get(WSSecurityEngineResult.TAG_PRINCIPAL); WSUsernameTokenPrincipal principal = (WSUsernameTokenPrincipal) secRes.get(WSSecurityEngineResult.TAG_PRINCIPAL);
// Authenticate // Authenticate
AuthenticationUtil.setCurrentUser(principal.getName()); AuthenticationUtil.setFullyAuthenticatedUser(principal.getName());
} }
} }

View File

@@ -183,7 +183,7 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
private void addRepoParameters(Map<String, Object> params) private void addRepoParameters(Map<String, Object> params)
{ {
if (AlfrescoTransactionSupport.getTransactionId() != null && if (AlfrescoTransactionSupport.getTransactionId() != null &&
AuthenticationUtil.getCurrentAuthentication() != null) AuthenticationUtil.getFullAuthentication() != null)
{ {
NodeRef rootHome = repository.getRootHome(); NodeRef rootHome = repository.getRootHome();
if (rootHome != null) if (rootHome != null)
@@ -239,10 +239,11 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
try try
{ {
AuthenticationUtil.pushAuthentication();
// //
// Determine if user already authenticated // Determine if user already authenticated
// //
currentUser = AuthenticationUtil.getCurrentUserName(); currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
{ {
logger.debug("Current authentication: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser)); logger.debug("Current authentication: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
@@ -255,7 +256,7 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
// //
if (auth == null || auth.authenticate(required, isGuest)) if (auth == null || auth.authenticate(required, isGuest))
{ {
if (required == RequiredAuthentication.admin && !(authorityService.hasAdminAuthority() || AuthenticationUtil.getCurrentUserName().equals(AuthenticationUtil.getSystemUserName()))) if (required == RequiredAuthentication.admin && !(authorityService.hasAdminAuthority() || AuthenticationUtil.getFullyAuthenticatedUser().equals(AuthenticationUtil.getSystemUserName())))
{ {
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script " + desc.getId() + " requires admin authentication; however, a non-admin has attempted access."); throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script " + desc.getId() + " requires admin authentication; however, a non-admin has attempted access.");
} }
@@ -269,14 +270,13 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
// //
// Reset authentication for current thread // Reset authentication for current thread
// //
AuthenticationUtil.clearCurrentSecurityContext(); AuthenticationUtil.popAuthentication();
if (currentUser != null)
{
AuthenticationUtil.setCurrentUser(currentUser);
}
if (logger.isDebugEnabled()) if (logger.isDebugEnabled())
logger.debug("Authentication reset: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser)); {
String user = AuthenticationUtil.getFullyAuthenticatedUser();
logger.debug("Authentication reset: " + (user == null ? "unauthenticated" : "authenticated as " + user));
}
} }
} }
} }

View File

@@ -74,7 +74,7 @@ public class TestWebScriptRepoServer extends TestWebScriptServer
try try
{ {
TestWebScriptServer testServer = getTestServer(); TestWebScriptServer testServer = getTestServer();
AuthenticationUtil.setSystemUserAsCurrentUser(); AuthenticationUtil.setRunAsUserSystem();
testServer.rep(); testServer.rep();
} }
catch(Throwable e) catch(Throwable e)

View File

@@ -103,7 +103,7 @@ public class SiteFeedRetrieverWebScript extends DeclarativeWebScript
SiteInfo siteInfo = siteService.getSite(siteId); SiteInfo siteInfo = siteService.getSite(siteId);
if (siteInfo == null) if (siteInfo == null)
{ {
String currentUser = AuthenticationUtil.getCurrentUserName(); String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
status.setCode(Status.STATUS_UNAUTHORIZED); status.setCode(Status.STATUS_UNAUTHORIZED);
logger.warn("Unable to get site feed entries for '" + siteId + "' (site does not exist or is private) - currently logged in as '" + currentUser +"'"); logger.warn("Unable to get site feed entries for '" + siteId + "' (site does not exist or is private) - currently logged in as '" + currentUser +"'");

View File

@@ -30,7 +30,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.alfresco.error.AlfrescoRuntimeException; import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.AuthenticationUtil; import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.service.cmr.activities.ActivityService; import org.alfresco.service.cmr.activities.ActivityService;
import org.alfresco.service.cmr.security.AuthorityService; import org.alfresco.service.cmr.security.AuthorityService;
@@ -95,10 +94,10 @@ public class UserFeedRetrieverWebScript extends DeclarativeWebScript
if ((feedUserId == null) || (feedUserId.length() == 0)) if ((feedUserId == null) || (feedUserId.length() == 0))
{ {
feedUserId = AuthenticationUtil.getCurrentUserName(); feedUserId = AuthenticationUtil.getFullyAuthenticatedUser();
} }
String currentUser = AuthenticationUtil.getCurrentUserName(); String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
if (! ((currentUser == null) || if (! ((currentUser == null) ||
(currentUser.equals(AuthenticationUtil.getSystemUserName())) || (currentUser.equals(AuthenticationUtil.getSystemUserName())) ||
(authorityService.isAdminAuthority(currentUser)) || (authorityService.isAdminAuthority(currentUser)) ||

View File

@@ -79,7 +79,7 @@ public class LoginTicket extends DeclarativeWebScript
String ticketUser = ticketComponent.validateTicket(ticket); String ticketUser = ticketComponent.validateTicket(ticket);
// do not go any further if tickets are different // do not go any further if tickets are different
if (!AuthenticationUtil.getCurrentUserName().equals(ticketUser)) if (!AuthenticationUtil.getFullyAuthenticatedUser().equals(ticketUser))
{ {
status.setRedirect(true); status.setRedirect(true);
status.setCode(HttpServletResponse.SC_NOT_FOUND); status.setCode(HttpServletResponse.SC_NOT_FOUND);

View File

@@ -89,7 +89,7 @@ public class LoginTicketDelete extends DeclarativeWebScript
String ticketUser = ticketComponent.validateTicket(ticket); String ticketUser = ticketComponent.validateTicket(ticket);
// do not go any further if tickets are different // do not go any further if tickets are different
if (!AuthenticationUtil.getCurrentUserName().equals(ticketUser)) if (!AuthenticationUtil.getFullyAuthenticatedUser().equals(ticketUser))
{ {
status.setCode(HttpServletResponse.SC_NOT_FOUND); status.setCode(HttpServletResponse.SC_NOT_FOUND);
status.setMessage("Ticket not found"); status.setMessage("Ticket not found");

View File

@@ -142,7 +142,7 @@ public class FacebookAuthenticatorFactory implements ServletAuthenticatorFactory
logger.debug("Facebook session established; authenticating as user " + user); logger.debug("Facebook session established; authenticating as user " + user);
// session has been established, authenticate as Facebook user id // session has been established, authenticate as Facebook user id
AuthenticationUtil.setCurrentUser(user); AuthenticationUtil.setFullyAuthenticatedUser(user);
return true; return true;
} }
} }

View File

@@ -82,7 +82,7 @@ public class CancelInviteAction extends JBPMSpringActionHandler
// throw http status 'forbidden' Web Script Exception if current user is not a Site Manager of the site // throw http status 'forbidden' Web Script Exception if current user is not a Site Manager of the site
// associated with the invite (identified by inviteID) // associated with the invite (identified by inviteID)
String currentUserName = AuthenticationUtil.getCurrentUserName(); String currentUserName = AuthenticationUtil.getFullyAuthenticatedUser();
String currentUserSiteRole = this.siteService.getMembersRole(siteShortName, currentUserName); String currentUserSiteRole = this.siteService.getMembersRole(siteShortName, currentUserName);
if ((currentUserSiteRole == null) || (currentUserSiteRole.equals(SiteModel.SITE_MANAGER) == false)) if ((currentUserSiteRole == null) || (currentUserSiteRole.equals(SiteModel.SITE_MANAGER) == false))
{ {

View File

@@ -91,7 +91,7 @@ public class InviteByTicket extends DeclarativeWebScript
String inviteTicket = req.getServiceMatch().getTemplateVars().get("inviteTicket"); String inviteTicket = req.getServiceMatch().getTemplateVars().get("inviteTicket");
// authenticate as system for the rest of the webscript // authenticate as system for the rest of the webscript
AuthenticationUtil.setSystemUserAsCurrentUser(); AuthenticationUtil.setRunAsUserSystem();
// find the workflow for the given id // find the workflow for the given id
WorkflowTask workflowTask = InviteHelper.findInviteStartTask(inviteId, workflowService); WorkflowTask workflowTask = InviteHelper.findInviteStartTask(inviteId, workflowService);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2005-2007 Alfresco Software Limited. * Copyright (C) 2005-2008 Alfresco Software Limited.
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
@@ -112,6 +112,12 @@ public class InviteServiceTest extends BaseWebScriptTest
protected void setUp() throws Exception protected void setUp() throws Exception
{ {
super.setUp(); super.setUp();
/**
* We don't want to be authenticated as 'system' but run as 'InviterUser', because then
* 'system' will be the creator for the sites and 'inviterUser' will be a nobody.
*/
AuthenticationUtil.clearCurrentSecurityContext();
// get references to services // get references to services
this.authorityService = (AuthorityService) getServer().getApplicationContext().getBean("AuthorityService"); this.authorityService = (AuthorityService) getServer().getApplicationContext().getBean("AuthorityService");
@@ -140,7 +146,7 @@ public class InviteServiceTest extends BaseWebScriptTest
// Create new invitee email address list // Create new invitee email address list
this.inviteeEmailAddrs = new ArrayList<String>(); this.inviteeEmailAddrs = new ArrayList<String>();
// //
// various setup operations which need to be run as system user // various setup operations which need to be run as system user
// //
@@ -158,6 +164,16 @@ public class InviteServiceTest extends BaseWebScriptTest
} }
}, AuthenticationUtil.getSystemUserName()); }, AuthenticationUtil.getSystemUserName());
// The creation of sites is heavily dependent on the authenticated user. We must ensure that,
// when doing the runAs below, the user both 'runAs' and 'fullyAuthenticated'. In order for
// this to be the case, the security context MUST BE EMPTY now. We could do the old
// "defensive clear", but really there should not be any lurking authentications on this thread
// after the context starts up. If there are, that is a bug, and we fail explicitly here.
String residuallyAuthenticatedUser = AuthenticationUtil.getFullyAuthenticatedUser();
assertNull(
"Residual authentication on context-initiating thread (this thread):" + residuallyAuthenticatedUser,
residuallyAuthenticatedUser);
// //
// various setup operations which need to be run as inviter user // various setup operations which need to be run as inviter user
// //
@@ -704,7 +720,7 @@ public class InviteServiceTest extends BaseWebScriptTest
public void testStartInviteForbiddenWhenInviterNotSiteManager() throws Exception public void testStartInviteForbiddenWhenInviterNotSiteManager() throws Exception
{ {
// inviter2 starts invite workflow, but he/she is not the site manager of the given site // inviter2 starts invite workflow, but he/she is not the site manager of the given site
AuthenticationUtil.setCurrentUser(USER_INVITER_2); AuthenticationUtil.setFullyAuthenticatedUser(USER_INVITER_2);
startInvite(INVITEE_FIRSTNAME, startInvite(INVITEE_FIRSTNAME,
INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_3, Status.STATUS_FORBIDDEN); INVITEE_LASTNAME, INVITEE_SITE_ROLE, SITE_SHORT_NAME_INVITE_3, Status.STATUS_FORBIDDEN);
} }
@@ -720,7 +736,7 @@ public class InviteServiceTest extends BaseWebScriptTest
// when inviter 2 (who is not Site Manager of the given site) tries to cancel invite // when inviter 2 (who is not Site Manager of the given site) tries to cancel invite
// http status FORBIDDEN must be returned // http status FORBIDDEN must be returned
AuthenticationUtil.setCurrentUser(USER_INVITER_2); AuthenticationUtil.setFullyAuthenticatedUser(USER_INVITER_2);
cancelInvite(inviteId, Status.STATUS_FORBIDDEN); cancelInvite(inviteId, Status.STATUS_FORBIDDEN);
} }

View File

@@ -93,7 +93,7 @@ public class PersonPut extends DeclarativeWebScript
catch (AccessDeniedException err) catch (AccessDeniedException err)
{ {
// catch security exception if the user does not have permissions // catch security exception if the user does not have permissions
String currentUserName = AuthenticationUtil.getCurrentUserName(); String currentUserName = AuthenticationUtil.getFullyAuthenticatedUser();
String personUserName = (String)nodeService.getProperty(person, ContentModel.PROP_USERNAME); String personUserName = (String)nodeService.getProperty(person, ContentModel.PROP_USERNAME);
throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR, "Current user: " throw new WebScriptException(Status.STATUS_INTERNAL_SERVER_ERROR, "Current user: "
+ currentUserName + " does not have the appropriate permissons to update " + currentUserName + " does not have the appropriate permissons to update "

View File

@@ -127,7 +127,7 @@ public class JSR168PortletAuthenticatorFactory implements PortletAuthenticatorFa
logger.debug("Authenticating as Guest"); logger.debug("Authenticating as Guest");
// authenticate as guest // authenticate as guest
AuthenticationUtil.setCurrentUser(AuthenticationUtil.getGuestUserName()); AuthenticationUtil.setFullyAuthenticatedUser(AuthenticationUtil.getGuestUserName());
} }
else else
{ {
@@ -144,7 +144,7 @@ public class JSR168PortletAuthenticatorFactory implements PortletAuthenticatorFa
{ {
throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "User " + portalUser + " is not a known Alfresco user"); throw new WebScriptException(HttpServletResponse.SC_FORBIDDEN, "User " + portalUser + " is not a known Alfresco user");
} }
AuthenticationUtil.setCurrentUser(portalUser); AuthenticationUtil.setFullyAuthenticatedUser(portalUser);
} }
catch (Throwable err) catch (Throwable err)
{ {

View File

@@ -46,6 +46,8 @@ import org.alfresco.model.ContentModel;
import org.alfresco.repo.SessionUser; import org.alfresco.repo.SessionUser;
import org.alfresco.repo.security.authentication.AuthenticationComponent; import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.AuthenticationException; import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.repo.security.authentication.AuthenticationUtil;
import org.alfresco.repo.security.authentication.AuthenticationUtil.RunAsWork;
import org.alfresco.service.ServiceRegistry; import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.repository.NodeService;
@@ -289,16 +291,17 @@ public abstract class BaseSSOAuthenticationFilter implements Filter
// Setup User object and Home space ID etc. // Setup User object and Home space ID etc.
NodeRef personNodeRef = m_personService.getPerson(userName); final NodeRef personNodeRef = m_personService.getPerson(userName);
// Use the system user context to do the user lookup // Use the system user context to do the user lookup
RunAsWork<String> getUserNameRunAsWork = new RunAsWork<String>()
m_authComponent.setCurrentUser(m_authComponent.getSystemUserName()); {
public String doWork() throws Exception
// User name should match the uid in the person entry found {
return (String) m_nodeService.getProperty(personNodeRef, ContentModel.PROP_USERNAME);
m_authComponent.setSystemUserAsCurrentUser(); }
userName = (String) m_nodeService.getProperty(personNodeRef, ContentModel.PROP_USERNAME); };
userName = AuthenticationUtil.runAs(getUserNameRunAsWork, AuthenticationUtil.SYSTEM_USER_NAME);
m_authComponent.setCurrentUser(userName); m_authComponent.setCurrentUser(userName);
String currentTicket = m_authService.getCurrentTicket(); String currentTicket = m_authService.getCurrentTicket();