On 04/04/2013 02:27 AM, Patrick McKeown wrote:
the threads don't have the proper security context
Exactly. So obtain SecurityContextHolder.getContext() from the initial (HTTP request handling) thread; then in your new thread, call
SecurityContextHolder.setContext(securityContext) to be able to access Jenkins model objects.
If using an executor service, the thread might be reused for another runnable, so before this grab the thread’s current context (probably devoid of permissions) and call
SecurityContextHolder.setContext(originalSecurityContext) in a finally block.
For example:
final SecurityContext authorized = SecurityContextHolder.getContext();
service.submit(new Callable<Void>() {
public Void call() throws Exception {
SecurityContext orig = SecurityContextHolder.getContext();
SecurityContextHolder.setContext(authorized);
try {
Jenkins.getInstance().getItem(whatever); // should work
} finally {
SecurityContextHolder.setContext(orig);
}
return null;
}
});
The cleaner way to do this would probably be to create a delegating ExecutorService implementation whose submit and related methods capture the current SecurityContext
and then wrap the task in a block like the above. Then you could simply write:
SomeUtilityClass.wrapExecutorWithSecurity(service).submit(new Callable<Void>() {
public Void call() throws Exception {
Jenkins.getInstance().getItem(whatever); // should work
return null;
}
});
Such a wrapper would be a welcome addition to Jenkins core, I think. Use the jenkins.security package if you want to play with a pull request, or it could be added to
hudson.security.ACL which already hosts the impersonate methods.
--
You received this message because you are subscribed to the Google Groups "Jenkins
Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.