cancel
Showing results for 
Search instead for 
Did you mean: 

Authentication within a Job

hubick
Champ in-the-making
Champ in-the-making
Hi,

I have an a org.quartz.Job subclass for creating folders within my repository (v3.3.5).

I have been using only the JCR API up until recently, but now I also wish to populate content rules on the created folders, so I mixed in some native Alfresco API calls to create those.

Despite having wrapped my code in an AuthenticationUtil.RunAsWork interface, I still run into authentication problems when attempting to save rules:


net.sf.acegisecurity.AuthenticationCredentialsNotFoundException: A valid SecureContext was not provided in the RequestContext
        at net.sf.acegisecurity.intercept.AbstractSecurityInterceptor.credentialsNotFound(AbstractSecurityInterceptor.java:477)
        at net.sf.acegisecurity.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:355)
        at net.sf.acegisecurity.intercept.method.aopalliance.MethodSecurityInterceptor.invoke(MethodSecurityInterceptor.java:77)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:43)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.alfresco.repo.audit.AuditComponentImpl.audit(AuditComponentImpl.java:279)
        at org.alfresco.repo.audit.AuditMethodInterceptor.proceed(AuditMethodInterceptor.java:163)
        at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:140)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at $Proxy81.hasAspect(Unknown Source)
        at org.alfresco.repo.rule.RuleServiceImpl.getLinkedToRuleNode(RuleServiceImpl.java:1462)
        at org.alfresco.repo.rule.RuleServiceImpl.isLinkedToRuleNode(RuleServiceImpl.java:1451)
        at org.alfresco.repo.rule.RuleServiceImpl.checkForLinkedRules(RuleServiceImpl.java:919)
        at org.alfresco.repo.rule.RuleServiceImpl.saveRule(RuleServiceImpl.java:722)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:601)
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
        at org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor.invoke(AlwaysProceedMethodInterceptor.java:34)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:43)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.alfresco.repo.audit.AuditComponentImpl.audit(AuditComponentImpl.java:279)
        at org.alfresco.repo.audit.AuditMethodInterceptor.proceedWithAudit(AuditMethodInterceptor.java:228)
        at org.alfresco.repo.audit.AuditMethodInterceptor.proceed(AuditMethodInterceptor.java:195)
        at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:140)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
        at $Proxy113.saveRule(Unknown Source)
        …
        at MyJob$1.doWork(MyJob.java)
        at org.alfresco.repo.security.authentication.AuthenticationUtil.runAs(AuthenticationUtil.java:508)
        at MyJob.execute(MyJob.java)
        at org.quartz.core.JobRunShell.run(JobRunShell.java:202)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:529)


So, I added an explicit authentication call:


serviceRegistry.getAuthenticationService().authenticate(repositoryUserName, repositoryPassword.toCharArray());


And with that, all my folders and rules are then <em>successfully</em> created - regardless of whether my code is wrapped within a RunAsWork implementation.

The problem is, the authenticate call appears to launch a <em>second</em> instance of Alfresco within the same virtual machine!

When the job runs, the logs show a bunch of stuff leading up to a second "Alfresco started" entry.  I confirmed this by doing a `kill -3` to get thread dumps, which list a <em>single</em> 'AlfrescoJbpmJobExecutor' thread before the job runs, and then <em>two</em> such threads after.  Other types of subsequent jobs then appear to be executed twice simultaenously, and all kinds of other problems then ensue.

Can anyone offer any advice as to what I might be doing wrong here?

Much Thanks! Smiley Happy
2 REPLIES 2

afaust
Legendary Innovator
Legendary Innovator
Hello,

why did you use JCR API in a job that runs in Alfresco? Just out of curiosity…

When you invoke Alfresco services from a Quarts job, you not only need to wrap your calls in a proper authentication context via runAs, but also in a proper transaction context (e.g. via RetryingTransactionHelper), which I see is lacking from your thread dump. Or is this contained in the part that you have snipped?

Regards
Axel

hubick
Champ in-the-making
Champ in-the-making
I had assumed 'ApplicationContextHelper.getApplicationContext().getBean(ServiceRegistry.SERVICE_REGISTRY)' would follow the singleton pattern, but it doesn't, and getApplicationContext() was instead causing the duplicate instance of Alfresco to be instantiated.  Injecting the existing ServiceRegistry instance via a &lt;ref bean="ServiceRegistry" /&gt; solved the problem.

And coding projects against a standard interface such as the JCR API's when possible, as opposed to the proprietary Alfresco Foundation API's, attempts to avoid vendor lock-in - both in terms of the implementation runtime and the knowledge required to maintain the resulting code.

Regards.