package org.argeo.security;
+import java.util.concurrent.Callable;
import java.util.concurrent.Executor;
+import java.util.concurrent.Future;
/**
* Allows to execute code authenticated as a system user (that is not a real
*/
public interface SystemExecutionService extends Executor {
/**
- * Executes this Runnable within a system authenticated context.
+ * Executes this {@link Runnable} within a system authenticated context.
* Implementations should make sure that this method is properly secured via
* Java permissions since it could access to everything without credentials.
*/
public void execute(Runnable runnable);
+
+ /**
+ * Executes this {@link Callable} within a system authenticated context.
+ * Implementations should make sure that this method is properly secured via
+ * Java permissions since it could access to everything without credentials.
+ */
+ public <T> Future<T> submit(Callable<T> task);
}
package org.argeo.security.core;
import java.security.AccessController;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
import javax.security.auth.Subject;
private String systemAuthenticationKey;
public void execute(Runnable runnable) {
- wrapWithSystemAuthentication(runnable).run();
+ try {
+ wrapWithSystemAuthentication(Executors.callable(runnable)).call();
+ } catch (Exception e) {
+ throw new ArgeoException(
+ "Exception when running system authenticated task", e);
+ }
}
- protected Runnable wrapWithSystemAuthentication(final Runnable runnable) {
- return new Runnable() {
+ public <T> Future<T> submit(Callable<T> task) {
+ FutureTask<T> future = new FutureTask<T>(
+ wrapWithSystemAuthentication(task));
+ future.run();
+ return future;
+ }
+
+ protected <T> Callable<T> wrapWithSystemAuthentication(
+ final Callable<T> runnable) {
+ return new Callable<T>() {
- public void run() {
+ public T call() throws Exception {
SecurityContext securityContext = SecurityContextHolder
.getContext();
Authentication currentAuth = securityContext
systemAuthenticationKey));
securityContext.setAuthentication(auth);
try {
- runnable.run();
+ return runnable.call();
} finally {
// remove the authentication
securityContext.setAuthentication(null);