MT - initial checkin for MT-enabled Web Scripts

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@8293 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Jan Vonka
2008-02-15 15:29:27 +00:00
parent 0eaa1f5ba9
commit 213f696b97

View File

@@ -1,354 +1,359 @@
/* /*
* 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
* as published by the Free Software Foundation; either version 2 * as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version. * of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * 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 * 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 * the GPL, you may redistribute this Program in connection with Free/Libre
* and Open Source Software ("FLOSS") applications as described in Alfresco's * 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 recieved a copy of the text describing
* the FLOSS exception, and it is also available here: * the FLOSS exception, and it is also available here:
* http://www.alfresco.com/legal/licensing" * http://www.alfresco.com/legal/licensing"
*/ */
package org.alfresco.repo.security.authentication; package org.alfresco.repo.security.authentication;
import net.sf.acegisecurity.Authentication; import net.sf.acegisecurity.Authentication;
import net.sf.acegisecurity.GrantedAuthority; import net.sf.acegisecurity.GrantedAuthority;
import net.sf.acegisecurity.GrantedAuthorityImpl; import net.sf.acegisecurity.GrantedAuthorityImpl;
import net.sf.acegisecurity.UserDetails; import net.sf.acegisecurity.UserDetails;
import net.sf.acegisecurity.context.Context; import net.sf.acegisecurity.context.Context;
import net.sf.acegisecurity.context.ContextHolder; import net.sf.acegisecurity.context.ContextHolder;
import net.sf.acegisecurity.context.security.SecureContext; import net.sf.acegisecurity.context.security.SecureContext;
import net.sf.acegisecurity.context.security.SecureContextImpl; import net.sf.acegisecurity.context.security.SecureContextImpl;
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken; import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
import net.sf.acegisecurity.providers.dao.User; import net.sf.acegisecurity.providers.dao.User;
import org.alfresco.repo.tenant.TenantService; import org.alfresco.repo.tenant.TenantService;
import org.alfresco.service.cmr.security.PermissionService; import org.alfresco.service.cmr.security.PermissionService;
import org.apache.log4j.NDC; import org.apache.log4j.NDC;
public abstract class AuthenticationUtil public abstract class AuthenticationUtil
{ {
public interface RunAsWork<Result> public interface RunAsWork<Result>
{ {
/** /**
* Method containing the work to be done in the user transaction. * Method containing the work to be done in the user transaction.
* *
* @return Return the result of the operation * @return Return the result of the operation
*/ */
Result doWork() throws Exception; Result doWork() throws Exception;
} }
public static final String SYSTEM_USER_NAME = "System"; public static final String SYSTEM_USER_NAME = "System";
private static boolean mtEnabled = false; private static boolean mtEnabled = false;
private AuthenticationUtil() private AuthenticationUtil()
{ {
super(); super();
} }
public static void setMtEnabled(boolean mtEnabled) public static void setMtEnabled(boolean mtEnabled)
{ {
if (! AuthenticationUtil.mtEnabled) if (! AuthenticationUtil.mtEnabled)
{ {
AuthenticationUtil.mtEnabled = mtEnabled; AuthenticationUtil.mtEnabled = mtEnabled;
} }
} }
public static Authentication setCurrentUser(String userName) public static boolean isMtEnabled()
{ {
return setCurrentUser(userName, getDefaultUserDetails(userName)); return AuthenticationUtil.mtEnabled;
} }
/** public static Authentication setCurrentUser(String userName)
* Explicitly set the current user to be authenticated. {
* return setCurrentUser(userName, getDefaultUserDetails(userName));
* @param userName - String user id }
* @param providedDetails - provided details for the user
* /**
* @return Authentication * Explicitly set the current user to be authenticated.
*/ *
public static Authentication setCurrentUser(String userName, UserDetails providedDetails) * @param userName - String user id
throws AuthenticationException * @param providedDetails - provided details for the user
{ *
if (userName == null) * @return Authentication
{ */
throw new AuthenticationException("Null user name"); public static Authentication setCurrentUser(String userName, UserDetails providedDetails)
} throws AuthenticationException
{
try if (userName == null)
{ {
UserDetails ud = null; throw new AuthenticationException("Null user name");
if (userName.equals(SYSTEM_USER_NAME)) }
{
GrantedAuthority[] gas = new GrantedAuthority[1]; try
gas[0] = new GrantedAuthorityImpl("ROLE_SYSTEM"); {
ud = new User(SYSTEM_USER_NAME, "", true, true, true, true, gas); UserDetails ud = null;
} if (userName.equals(SYSTEM_USER_NAME))
else if (userName.equalsIgnoreCase(PermissionService.GUEST_AUTHORITY)) {
{ GrantedAuthority[] gas = new GrantedAuthority[1];
GrantedAuthority[] gas = new GrantedAuthority[0]; gas[0] = new GrantedAuthorityImpl("ROLE_SYSTEM");
ud = new User(PermissionService.GUEST_AUTHORITY.toLowerCase(), "", true, true, true, true, gas); ud = new User(SYSTEM_USER_NAME, "", true, true, true, true, gas);
} }
else else if (userName.equalsIgnoreCase(PermissionService.GUEST_AUTHORITY))
{ {
if (providedDetails.getUsername().equals(userName)) GrantedAuthority[] gas = new GrantedAuthority[0];
{ ud = new User(PermissionService.GUEST_AUTHORITY.toLowerCase(), "", true, true, true, true, gas);
ud = providedDetails; }
} else
else {
{ if (providedDetails.getUsername().equals(userName))
throw new AuthenticationException("Provided user details do not match the user name"); {
} ud = providedDetails;
} }
else
UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(ud, "", ud {
.getAuthorities()); throw new AuthenticationException("Provided user details do not match the user name");
auth.setDetails(ud); }
auth.setAuthenticated(true); }
return setCurrentAuthentication(auth);
} UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(ud, "", ud
catch (net.sf.acegisecurity.AuthenticationException ae) .getAuthorities());
{ auth.setDetails(ud);
throw new AuthenticationException(ae.getMessage(), ae); auth.setAuthenticated(true);
} return setCurrentAuthentication(auth);
} }
catch (net.sf.acegisecurity.AuthenticationException ae)
/** {
* Default implementation that makes an ACEGI object on the fly throw new AuthenticationException(ae.getMessage(), ae);
* }
* @param userName }
* @return
*/ /**
private static UserDetails getDefaultUserDetails(String userName) * Default implementation that makes an ACEGI object on the fly
{ *
GrantedAuthority[] gas = new GrantedAuthority[1]; * @param userName
gas[0] = new GrantedAuthorityImpl("ROLE_AUTHENTICATED"); * @return
UserDetails ud = new User(userName, "", true, true, true, true, gas); */
return ud; private static UserDetails getDefaultUserDetails(String userName)
} {
GrantedAuthority[] gas = new GrantedAuthority[1];
/** gas[0] = new GrantedAuthorityImpl("ROLE_AUTHENTICATED");
* Explicitly set the current authentication. UserDetails ud = new User(userName, "", true, true, true, true, gas);
* return ud;
* @param authentication }
* Authentication
*/ /**
public static Authentication setCurrentAuthentication(Authentication authentication) * Explicitly set the current authentication.
{ *
if (authentication == null) * @param authentication
{ * Authentication
clearCurrentSecurityContext(); */
return null; public static Authentication setCurrentAuthentication(Authentication authentication)
} {
else if (authentication == null)
{ {
Context context = ContextHolder.getContext(); clearCurrentSecurityContext();
SecureContext sc = null; return null;
if ((context == null) || !(context instanceof SecureContext)) }
{ else
sc = new SecureContextImpl(); {
ContextHolder.setContext(sc); Context context = ContextHolder.getContext();
} SecureContext sc = null;
else if ((context == null) || !(context instanceof SecureContext))
{ {
sc = (SecureContext) context; sc = new SecureContextImpl();
} ContextHolder.setContext(sc);
authentication.setAuthenticated(true); }
sc.setAuthentication(authentication); else
{
// Support for logging tenant domain / username (via log4j NDC) sc = (SecureContext) context;
String userName = SYSTEM_USER_NAME; }
if (authentication.getPrincipal() instanceof UserDetails) authentication.setAuthenticated(true);
{ sc.setAuthentication(authentication);
userName = ((UserDetails) authentication.getPrincipal()).getUsername();
} // Support for logging tenant domain / username (via log4j NDC)
String userName = SYSTEM_USER_NAME;
logNDC(userName); if (authentication.getPrincipal() instanceof UserDetails)
{
return authentication; userName = ((UserDetails) authentication.getPrincipal()).getUsername();
} }
}
logNDC(userName);
public static void logNDC(String userName)
{ return authentication;
NDC.remove(); }
}
if (mtEnabled == true)
{ public static void logNDC(String userName)
int idx = userName.indexOf(TenantService.SEPARATOR); {
if ((idx != -1) && (idx < (userName.length()-1))) NDC.remove();
{
NDC.push("Tenant:"+userName.substring(idx+1)+" User:"+userName.substring(0,idx)); if (isMtEnabled())
} {
else int idx = userName.indexOf(TenantService.SEPARATOR);
{ if ((idx != -1) && (idx < (userName.length()-1)))
NDC.push("User:"+userName); {
} NDC.push("Tenant:"+userName.substring(idx+1)+" User:"+userName.substring(0,idx));
} }
else else
{ {
NDC.push("User:"+userName); NDC.push("User:"+userName);
} }
} }
else
/** {
* Get the current authentication context NDC.push("User:"+userName);
* }
* @return Authentication }
* @throws AuthenticationException
*/ /**
public static Authentication getCurrentAuthentication() throws AuthenticationException * Get the current authentication context
{ *
Context context = ContextHolder.getContext(); * @return Authentication
if ((context == null) || !(context instanceof SecureContext)) * @throws AuthenticationException
{ */
return null; public static Authentication getCurrentAuthentication() throws AuthenticationException
} {
return ((SecureContext) context).getAuthentication(); Context context = ContextHolder.getContext();
} if ((context == null) || !(context instanceof SecureContext))
{
/** return null;
* Get the current user name. }
* return ((SecureContext) context).getAuthentication();
* @return String }
* @throws AuthenticationException
*/ /**
public static String getCurrentUserName() throws AuthenticationException * Get the current user name.
{ *
Context context = ContextHolder.getContext(); * @return String
if ((context == null) || !(context instanceof SecureContext)) * @throws AuthenticationException
{ */
return null; public static String getCurrentUserName() throws AuthenticationException
} {
return getUserName(((SecureContext) context).getAuthentication()); Context context = ContextHolder.getContext();
} if ((context == null) || !(context instanceof SecureContext))
{
/** return null;
* Get the current user name }
* return getUserName(((SecureContext) context).getAuthentication());
* @param authentication }
* Authentication
* @return String /**
*/ * Get the current user name
private static String getUserName(Authentication authentication) *
{ * @param authentication
String username; * Authentication
if (authentication.getPrincipal() instanceof UserDetails) * @return String
{ */
username = ((UserDetails) authentication.getPrincipal()).getUsername(); private static String getUserName(Authentication authentication)
} {
else String username;
{ if (authentication.getPrincipal() instanceof UserDetails)
username = authentication.getPrincipal().toString(); {
} username = ((UserDetails) authentication.getPrincipal()).getUsername();
}
return username; else
} {
username = authentication.getPrincipal().toString();
/** }
* Set the system user as the current user.
* return username;
* @return Authentication }
*/
public static Authentication setSystemUserAsCurrentUser() /**
{ * Set the system user as the current user.
return setCurrentUser(SYSTEM_USER_NAME); *
} * @return Authentication
*/
/** public static Authentication setSystemUserAsCurrentUser()
* Get the name of the system user {
* return setCurrentUser(SYSTEM_USER_NAME);
* @return String }
*/
public static String getSystemUserName() /**
{ * Get the name of the system user
return SYSTEM_USER_NAME; *
} * @return String
*/
/** public static String getSystemUserName()
* Get the name of the Guest User {
*/ return SYSTEM_USER_NAME;
public static String getGuestUserName() }
{
return PermissionService.GUEST_AUTHORITY.toLowerCase(); /**
} * Get the name of the Guest User
*/
/** public static String getGuestUserName()
* Remove the current security information {
*/ return PermissionService.GUEST_AUTHORITY.toLowerCase();
public static void clearCurrentSecurityContext() }
{
ContextHolder.setContext(null); /**
InMemoryTicketComponentImpl.clearCurrentSecurityContext(); * Remove the current security information
NDC.remove(); */
} public static void clearCurrentSecurityContext()
{
/** ContextHolder.setContext(null);
* Execute a unit of work as a given user. The thread's authenticated user will be InMemoryTicketComponentImpl.clearCurrentSecurityContext();
* returned to its normal state after the call. NDC.remove();
* }
* @param runAsWork the unit of work to do
* @param uid the user ID /**
* @return Returns the work's return value * Execute a unit of work as a given user. The thread's authenticated user will be
*/ * returned to its normal state after the call.
public static <R> R runAs(RunAsWork<R> runAsWork, String uid) *
{ * @param runAsWork the unit of work to do
String currentUser = AuthenticationUtil.getCurrentUserName(); * @param uid the user ID
* @return Returns the work's return value
R result = null; */
try public static <R> R runAs(RunAsWork<R> runAsWork, String uid)
{ {
if ((currentUser != null) && (mtEnabled == true)) String currentUser = AuthenticationUtil.getCurrentUserName();
{
int idx = currentUser.indexOf(TenantService.SEPARATOR); R result = null;
if ((idx != -1) && (idx < (currentUser.length()-1))) try
{ {
if (uid.equals(AuthenticationUtil.getSystemUserName())) if ((currentUser != null) && (isMtEnabled()))
{ {
uid = uid + TenantService.SEPARATOR + currentUser.substring(idx+1); int idx = currentUser.indexOf(TenantService.SEPARATOR);
} if ((idx != -1) && (idx < (currentUser.length()-1)))
} {
} if (uid.equals(AuthenticationUtil.getSystemUserName()))
{
AuthenticationUtil.setCurrentUser(uid); uid = uid + TenantService.SEPARATOR + currentUser.substring(idx+1);
result = runAsWork.doWork(); }
return result; }
} }
catch (Throwable exception)
{ AuthenticationUtil.setCurrentUser(uid);
result = runAsWork.doWork();
// Re-throw the exception return result;
if (exception instanceof RuntimeException) }
{ catch (Throwable exception)
throw (RuntimeException) exception; {
}
else // Re-throw the exception
{ if (exception instanceof RuntimeException)
throw new RuntimeException("Error during run as.", exception); {
} throw (RuntimeException) exception;
} }
finally else
{ {
AuthenticationUtil.clearCurrentSecurityContext(); throw new RuntimeException("Error during run as.", exception);
if (currentUser != null) }
{ }
AuthenticationUtil.setCurrentUser(currentUser); finally
} {
} AuthenticationUtil.clearCurrentSecurityContext();
} if (currentUser != null)
} {
AuthenticationUtil.setCurrentUser(currentUser);
}
}
}
}