mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged V3.2 to HEAD
Auto-reformat added 20 minutes of work! 17456: Fix for: ETHREEOH-1465: It's impossible to get the login history for a given user (Audit) 17463: Fixed ETHREEOH-3363: CLONE -Regression: readOnly settings causing bootstrap to fail git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@18144 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -135,13 +135,16 @@
|
|||||||
<Method name="setAuthentication" mode="all"/>
|
<Method name="setAuthentication" mode="all"/>
|
||||||
<Method name="deleteAuthentication" mode="all"/>
|
<Method name="deleteAuthentication" mode="all"/>
|
||||||
<Method name="setAuthenticationEnabled" mode="all"/>
|
<Method name="setAuthenticationEnabled" mode="all"/>
|
||||||
<Method name="authenticate" mode="all"/>
|
<Method name="authenticate" mode="all" auditInternal="true"/>
|
||||||
<Method name="authenticateAsGuest" mode="all"/>
|
<Method name="authenticateAsGuest" mode="all"/>
|
||||||
<Method name="authenticationExists" mode="all"/>
|
<Method name="authenticationExists" mode="all"/>
|
||||||
<Method name="invalidateUserSession" mode="all"/>
|
<Method name="invalidateUserSession" mode="all"/>
|
||||||
<Method name="invalidateTicket" mode="all"/>
|
<Method name="invalidateTicket" mode="all"/>
|
||||||
<Method name="validate" mode="all"/>
|
<Method name="validate" mode="all"/>
|
||||||
<Method name="clearCurrentSecurityContext" mode="all"/>
|
<Method name="clearCurrentSecurityContext" mode="all"/>
|
||||||
|
<!-- audit the creation of new tickets to follow SSO -->
|
||||||
|
<Method name="getNewTicket" mode="all" />
|
||||||
|
<Method name="getCurrentTicket" mode="none" auditInternal="true"/>
|
||||||
</Service>
|
</Service>
|
||||||
|
|
||||||
<Service name="AuthorityService" mode="none">
|
<Service name="AuthorityService" mode="none">
|
||||||
|
@@ -117,6 +117,9 @@
|
|||||||
<property name="sysAdminParams">
|
<property name="sysAdminParams">
|
||||||
<ref bean="sysAdminParams" />
|
<ref bean="sysAdminParams" />
|
||||||
</property>
|
</property>
|
||||||
|
<property name="auditComponent">
|
||||||
|
<ref bean="auditComponent" />
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- CIFS authentication -->
|
<!-- CIFS authentication -->
|
||||||
|
@@ -80,6 +80,9 @@
|
|||||||
<property name="sysAdminParams">
|
<property name="sysAdminParams">
|
||||||
<ref bean="sysAdminParams" />
|
<ref bean="sysAdminParams" />
|
||||||
</property>
|
</property>
|
||||||
|
<property name="auditComponent">
|
||||||
|
<ref bean="auditComponent" />
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
@@ -48,6 +48,9 @@
|
|||||||
<property name="sysAdminParams">
|
<property name="sysAdminParams">
|
||||||
<ref bean="sysAdminParams" />
|
<ref bean="sysAdminParams" />
|
||||||
</property>
|
</property>
|
||||||
|
<property name="auditComponent">
|
||||||
|
<ref bean="auditComponent" />
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
</beans>
|
</beans>
|
@@ -57,6 +57,9 @@
|
|||||||
<property name="sysAdminParams">
|
<property name="sysAdminParams">
|
||||||
<ref bean="sysAdminParams" />
|
<ref bean="sysAdminParams" />
|
||||||
</property>
|
</property>
|
||||||
|
<property name="auditComponent">
|
||||||
|
<ref bean="auditComponent" />
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- CIFS authentication -->
|
<!-- CIFS authentication -->
|
||||||
|
@@ -95,6 +95,9 @@
|
|||||||
<property name="sysAdminParams">
|
<property name="sysAdminParams">
|
||||||
<ref bean="sysAdminParams" />
|
<ref bean="sysAdminParams" />
|
||||||
</property>
|
</property>
|
||||||
|
<property name="auditComponent">
|
||||||
|
<ref bean="auditComponent" />
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- CIFS authentication and SMB session listener -->
|
<!-- CIFS authentication and SMB session listener -->
|
||||||
|
@@ -57,6 +57,12 @@ public class AuditBootstrap extends AbstractLifecycleBean
|
|||||||
@Override
|
@Override
|
||||||
protected void onBootstrap(ApplicationEvent event)
|
protected void onBootstrap(ApplicationEvent event)
|
||||||
{
|
{
|
||||||
|
// Don't bootstrap if the system is read-only
|
||||||
|
if (transactionService.isReadOnly())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
RetryingTransactionCallback<Void> callback = new RetryingTransactionCallback<Void>()
|
RetryingTransactionCallback<Void> callback = new RetryingTransactionCallback<Void>()
|
||||||
{
|
{
|
||||||
public Void execute() throws Throwable
|
public Void execute() throws Throwable
|
||||||
|
@@ -70,6 +70,14 @@ public interface AuditComponent
|
|||||||
* @since 2.1
|
* @since 2.1
|
||||||
*/
|
*/
|
||||||
public void audit(String source, String description, NodeRef key, Object... args);
|
public void audit(String source, String description, NodeRef key, Object... args);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an audit entry - without invoking the method invocation.
|
||||||
|
* Only the method arguments can be audited.
|
||||||
|
*
|
||||||
|
* @since 3.2
|
||||||
|
*/
|
||||||
|
void beforeMethodCallManualAudit(Class<?> clazz, Object target, String method, Object ... args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the audit trail for a node.
|
* Get the audit trail for a node.
|
||||||
|
@@ -64,11 +64,12 @@ import org.alfresco.service.cmr.repository.StoreRef;
|
|||||||
import org.alfresco.service.cmr.search.SearchParameters;
|
import org.alfresco.service.cmr.search.SearchParameters;
|
||||||
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
import org.alfresco.service.namespace.NamespacePrefixResolver;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
|
||||||
import org.alfresco.util.PathMapper;
|
import org.alfresco.util.PathMapper;
|
||||||
import org.aopalliance.intercept.MethodInvocation;
|
import org.aopalliance.intercept.MethodInvocation;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.springframework.aop.framework.ReflectiveMethodInvocation;
|
||||||
|
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default audit component implementation. TODO: Implement before, after and exception filtering. At the moment
|
* The default audit component implementation. TODO: Implement before, after and exception filtering. At the moment
|
||||||
@@ -234,7 +235,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
{
|
{
|
||||||
logger.debug("Auditing - " + serviceName + "." + methodName);
|
logger.debug("Auditing - " + serviceName + "." + methodName);
|
||||||
}
|
}
|
||||||
return auditImpl(mi);
|
return auditImpl(mi, true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -242,7 +243,7 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
{
|
{
|
||||||
logger.debug("UnknownService." + methodName);
|
logger.debug("UnknownService." + methodName);
|
||||||
}
|
}
|
||||||
return auditImpl(mi);
|
return auditImpl(mi, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -298,16 +299,20 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
* @throws Throwable -
|
* @throws Throwable -
|
||||||
* any Throwable that can be thrown by th audtied method.
|
* any Throwable that can be thrown by th audtied method.
|
||||||
*/
|
*/
|
||||||
public Object auditImpl(MethodInvocation mi) throws Throwable
|
public Object auditImpl(MethodInvocation mi, boolean execute) throws Throwable
|
||||||
{
|
{
|
||||||
final AuditState auditInfo = new AuditState(auditConfiguration);
|
final AuditState auditInfo = new AuditState(auditConfiguration);
|
||||||
// RecordOptions recordOptions = auditModel.getAuditRecordOptions(mi);
|
// RecordOptions recordOptions = auditModel.getAuditRecordOptions(mi);
|
||||||
AuditMode auditMode = AuditMode.UNSET;
|
AuditMode auditMode = AuditMode.UNSET;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Object o = null;
|
||||||
auditMode = beforeInvocation(auditMode, auditInfo, mi);
|
auditMode = beforeInvocation(auditMode, auditInfo, mi);
|
||||||
Object o = mi.proceed();
|
if (execute)
|
||||||
auditMode = postInvocation(auditMode, auditInfo, mi, o);
|
{
|
||||||
|
o = mi.proceed();
|
||||||
|
auditMode = postInvocation(auditMode, auditInfo, mi, o);
|
||||||
|
}
|
||||||
if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.SUCCESS))
|
if ((auditMode == AuditMode.ALL) || (auditMode == AuditMode.SUCCESS))
|
||||||
{
|
{
|
||||||
RetryingTransactionCallback<Object> cb = new RetryingTransactionCallback<Object>()
|
RetryingTransactionCallback<Object> cb = new RetryingTransactionCallback<Object>()
|
||||||
@@ -611,6 +616,120 @@ public class AuditComponentImpl implements AuditComponent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see org.alfresco.repo.audit.AuditComponent#beforeMethodCallManualAudit(org.aopalliance.intercept.MethodInvocation)
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void beforeMethodCallManualAudit(Class clazz, Object target, String methodName, Object ... args)
|
||||||
|
{
|
||||||
|
Class[] argTypes = new Class[args.length];
|
||||||
|
for(int i = 0; i < args.length; i++)
|
||||||
|
{
|
||||||
|
argTypes[i] = args[i].getClass();
|
||||||
|
}
|
||||||
|
Method method;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
method = clazz.getMethod(methodName, argTypes);
|
||||||
|
}
|
||||||
|
catch (SecurityException e1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (NoSuchMethodException e1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MethodInvocation methodInvocation = new ReflectiveMethodInvocation(null, target, method, args, null, null) {};
|
||||||
|
if ((auditFlag.get() == null) || (!auditFlag.get().booleanValue()))
|
||||||
|
{
|
||||||
|
if (auditModel instanceof AuditEntry && ((AuditEntry) auditModel).getEnabled() == TrueFalseUnset.TRUE)
|
||||||
|
{
|
||||||
|
boolean auditInternal = (auditModel.getAuditInternalServiceMethods(methodInvocation) == TrueFalseUnset.TRUE);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
String serviceName = publicServiceIdentifier.getPublicServiceName(methodInvocation);
|
||||||
|
|
||||||
|
if (!auditInternal)
|
||||||
|
{
|
||||||
|
auditFlag.set(Boolean.TRUE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Auditing internal service use for - " + serviceName + "." + methodName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method.isAnnotationPresent(Auditable.class))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (serviceName != null)
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Auditing - " + serviceName + "." + methodName);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auditImpl(methodInvocation, false);
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("UnknownService." + methodName);
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
auditImpl(methodInvocation, false);
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (method.isAnnotationPresent(NotAuditable.class))
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Not Audited. " + serviceName + "." + methodName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (logger.isDebugEnabled())
|
||||||
|
{
|
||||||
|
logger.debug("Unannotated service method " + serviceName + "." + methodName);
|
||||||
|
}
|
||||||
|
if (method.getDeclaringClass().isInterface() && method.getDeclaringClass().isAnnotationPresent(PublicService.class))
|
||||||
|
{
|
||||||
|
throw new RuntimeException("Unannotated service method " + serviceName + "." + methodName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (!auditInternal)
|
||||||
|
{
|
||||||
|
auditFlag.set(Boolean.FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple audit entry Currently we ignore filtering here.
|
* A simple audit entry Currently we ignore filtering here.
|
||||||
*/
|
*/
|
||||||
|
@@ -24,11 +24,16 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.security.authentication;
|
package org.alfresco.repo.security.authentication;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.alfresco.repo.audit.AuditComponent;
|
||||||
import org.alfresco.repo.management.subsystems.ActivateableBean;
|
import org.alfresco.repo.management.subsystems.ActivateableBean;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationComponent.UserNameValidationMode;
|
import org.alfresco.repo.security.authentication.AuthenticationComponent.UserNameValidationMode;
|
||||||
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
|
import org.aopalliance.intercept.MethodInvocation;
|
||||||
|
import org.springframework.aop.framework.ReflectiveMethodInvocation;
|
||||||
|
|
||||||
public class AuthenticationServiceImpl extends AbstractAuthenticationService implements ActivateableBean
|
public class AuthenticationServiceImpl extends AbstractAuthenticationService implements ActivateableBean
|
||||||
{
|
{
|
||||||
@@ -36,6 +41,8 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp
|
|||||||
|
|
||||||
TicketComponent ticketComponent;
|
TicketComponent ticketComponent;
|
||||||
|
|
||||||
|
AuditComponent auditComponent;
|
||||||
|
|
||||||
private String domain;
|
private String domain;
|
||||||
|
|
||||||
private boolean allowsUserCreation = true;
|
private boolean allowsUserCreation = true;
|
||||||
@@ -58,7 +65,16 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp
|
|||||||
{
|
{
|
||||||
this.authenticationComponent = authenticationComponent;
|
this.authenticationComponent = authenticationComponent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param auditComponent the auditComponent to set
|
||||||
|
*/
|
||||||
|
public void setAuditComponent(AuditComponent auditComponent)
|
||||||
|
{
|
||||||
|
this.auditComponent = auditComponent;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* (non-Javadoc)
|
* (non-Javadoc)
|
||||||
* @see org.alfresco.repo.management.subsystems.ActivateableBean#isActive()
|
* @see org.alfresco.repo.management.subsystems.ActivateableBean#isActive()
|
||||||
@@ -85,8 +101,7 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp
|
|||||||
throw ae;
|
throw ae;
|
||||||
}
|
}
|
||||||
ticketComponent.clearCurrentTicket();
|
ticketComponent.clearCurrentTicket();
|
||||||
|
getCurrentTicket(null);
|
||||||
ticketComponent.getCurrentTicket(userName, null, true); // to ensure new ticket is created (even if client does not explicitly call getCurrentTicket)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCurrentUserName() throws AuthenticationException
|
public String getCurrentUserName() throws AuthenticationException
|
||||||
@@ -146,24 +161,16 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService imp
|
|||||||
String ticket = ticketComponent.getCurrentTicket(userName, sessionId, false);
|
String ticket = ticketComponent.getCurrentTicket(userName, sessionId, false);
|
||||||
if (ticket == null)
|
if (ticket == null)
|
||||||
{
|
{
|
||||||
try
|
|
||||||
{
|
|
||||||
preAuthenticationCheck(userName);
|
|
||||||
}
|
|
||||||
catch (AuthenticationException e)
|
|
||||||
{
|
|
||||||
clearCurrentSecurityContext();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
// If we get through the authentication check then it's safe to issue a new ticket (e.g. for
|
// If we get through the authentication check then it's safe to issue a new ticket (e.g. for
|
||||||
// SSO/external-based login)
|
// SSO/external-based login)
|
||||||
return ticketComponent.getCurrentTicket(userName, sessionId, true);
|
return getNewTicket(sessionId);
|
||||||
}
|
}
|
||||||
return ticket;
|
return ticket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNewTicket(String sessionId)
|
public String getNewTicket(String sessionId)
|
||||||
{
|
{
|
||||||
|
auditComponent.beforeMethodCallManualAudit(AuthenticationService.class, this, "getNewTicket", "");
|
||||||
String userName = getCurrentUserName();
|
String userName = getCurrentUserName();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user