Community profiling - repository container WebScript auth txn improvements:

- Fix to return null when a ROLE_ authority is requested from AuthorityDAO - was making needless query to DB that always returned empty and missing caches due to null return value
 - RepositoryContainer improvements - reduce number of txns required during init from 2 to 1, optimized code path when runAs() user is the same as currently authenticated user
 - Optimized code paths through hot Dictionary/Namespace methods when MT is disabled
 - Javadoc corrections
 - small measurable difference to large scale Share test
 - notable improvement to “short” webscript tests – round trip time for a single low impact WebScript request improved

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@41585 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast
2012-09-14 10:07:01 +00:00
parent e7fefd8f6a
commit ac389dffb3

View File

@@ -253,22 +253,18 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
/* (non-Javadoc) /* (non-Javadoc)
* @see org.alfresco.web.scripts.RuntimeContainer#executeScript(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse, org.alfresco.web.scripts.Authenticator) * @see org.alfresco.web.scripts.RuntimeContainer#executeScript(org.alfresco.web.scripts.WebScriptRequest, org.alfresco.web.scripts.WebScriptResponse, org.alfresco.web.scripts.Authenticator)
*/ */
public void executeScript(WebScriptRequest scriptReq, WebScriptResponse scriptRes, Authenticator auth) public void executeScript(WebScriptRequest scriptReq, WebScriptResponse scriptRes, final Authenticator auth)
throws IOException throws IOException
{ {
WebScript script = scriptReq.getServiceMatch().getWebScript(); final boolean debug = logger.isDebugEnabled();
Description desc = script.getDescription(); final WebScript script = scriptReq.getServiceMatch().getWebScript();
final Description desc = script.getDescription();
// Escalate the webscript declared level of authentication to the container required authentication // Escalate the webscript declared level of authentication to the container required authentication
// eg. must be guest if MT is enabled unless credentials are empty // eg. must be guest if MT is enabled unless credentials are empty
RequiredAuthentication required = desc.getRequiredAuthentication();
RequiredAuthentication containerRequiredAuthentication = getRequiredAuthentication(); RequiredAuthentication containerRequiredAuthentication = getRequiredAuthentication();
final RequiredAuthentication required = (desc.getRequiredAuthentication().compareTo(containerRequiredAuthentication) < 0 && !auth.emptyCredentials() ? containerRequiredAuthentication : desc.getRequiredAuthentication());
if ((required.compareTo(containerRequiredAuthentication) < 0) && (! auth.emptyCredentials())) final boolean isGuest = scriptReq.isGuest();
{
required = containerRequiredAuthentication;
}
boolean isGuest = scriptReq.isGuest();
if (required == RequiredAuthentication.none) if (required == RequiredAuthentication.none)
{ {
@@ -283,53 +279,69 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
} }
else else
{ {
String currentUser = null;
try try
{ {
AuthenticationUtil.pushAuthentication(); AuthenticationUtil.pushAuthentication();
// //
// Determine if user already authenticated // Determine if user already authenticated
// //
currentUser = AuthenticationUtil.getFullyAuthenticatedUser(); if (debug)
if (logger.isDebugEnabled())
{ {
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
logger.debug("Current authentication: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser)); logger.debug("Current authentication: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
logger.debug("Authentication required: " + required); logger.debug("Authentication required: " + required);
logger.debug("Guest login requested: " + isGuest); logger.debug("Guest login requested: " + isGuest);
} }
// //
// Apply appropriate authentication to Web Script invocation // Apply appropriate authentication to Web Script invocation
// //
if (auth == null || auth.authenticate(required, isGuest)) RetryingTransactionCallback<Boolean> authWork = new RetryingTransactionCallback<Boolean>()
{ {
// The user will now have been authenticated, based on HTTP Auth, Ticket etc public Boolean execute() throws Exception
// Check that the user they authenticated as has appropriate access to the script
// Check to see if they supplied HTTP Auth or Ticket as guest, on a script that needs more
if (required == RequiredAuthentication.user || required == RequiredAuthentication.admin)
{ {
String authenticatedUser = AuthenticationUtil.getFullyAuthenticatedUser(); if (auth == null || auth.authenticate(required, isGuest))
if (authenticatedUser == null || authorityService.isGuestAuthority(authenticatedUser))
{ {
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script " + desc.getId() + " requires user authentication; however, a guest has attempted access."); // The user will now have been authenticated, based on HTTP Auth, Ticket etc
// Check that the user they authenticated as has appropriate access to the script
// Check to see if they supplied HTTP Auth or Ticket as guest, on a script that needs more
if (required == RequiredAuthentication.user || required == RequiredAuthentication.admin)
{
String authenticatedUser = AuthenticationUtil.getFullyAuthenticatedUser();
String runAsUser = AuthenticationUtil.getRunAsUser();
if ( (authenticatedUser == null) ||
(authenticatedUser.equals(runAsUser) && authorityService.hasGuestAuthority()) ||
(!authenticatedUser.equals(runAsUser) && authorityService.isGuestAuthority(authenticatedUser)) )
{
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script " + desc.getId() + " requires user authentication; however, a guest has attempted access.");
}
}
// Check to see if they're admin or system on an Admin only script
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.");
}
if (debug)
{
String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
logger.debug("Authentication: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
}
return true;
} }
} return false;
}
// Check to see if they're admin or system on an Admin only script };
if (required == RequiredAuthentication.admin && !(authorityService.hasAdminAuthority() || AuthenticationUtil.getFullyAuthenticatedUser().equals(AuthenticationUtil.getSystemUserName())))
{ if (retryingTransactionHelper.doInTransaction(authWork, true))
throw new WebScriptException(HttpServletResponse.SC_UNAUTHORIZED, "Web Script " + desc.getId() + " requires admin authentication; however, a non-admin has attempted access."); {
} // Execute Web Script if authentication passed
// The Web Script has its own txn management with potential runAs() user
if (logger.isDebugEnabled())
{
currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
logger.debug("Authentication: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
}
// Execute Web Script
transactionedExecuteAs(script, scriptReq, scriptRes); transactionedExecuteAs(script, scriptReq, scriptRes);
} }
} }
@@ -340,10 +352,10 @@ public class RepositoryContainer extends AbstractRuntimeContainer implements Ten
// //
AuthenticationUtil.popAuthentication(); AuthenticationUtil.popAuthentication();
if (logger.isDebugEnabled()) if (debug)
{ {
String user = AuthenticationUtil.getFullyAuthenticatedUser(); String currentUser = AuthenticationUtil.getFullyAuthenticatedUser();
logger.debug("Authentication reset: " + (user == null ? "unauthenticated" : "authenticated as " + user)); logger.debug("Authentication reset: " + (currentUser == null ? "unauthenticated" : "authenticated as " + currentUser));
} }
} }
} }