package org.argeo.security.core;
+import java.security.AccessController;
+
+import javax.security.auth.Subject;
+
+import org.argeo.ArgeoException;
import org.argeo.security.SystemExecutionService;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
import org.springframework.security.context.SecurityContext;
import org.springframework.security.context.SecurityContextHolder;
-public class KeyBasedSystemExecutionService implements SystemExecutionService {
+public class KeyBasedSystemExecutionService implements SystemExecutionService,
+ TaskExecutor {
private AuthenticationManager authenticationManager;
private String systemAuthenticationKey;
- public void executeAsSystem(Runnable runnable) {
+ public void execute(Runnable runnable) {
wrapWithSystemAuthentication(runnable).run();
}
public void run() {
SecurityContext securityContext = SecurityContextHolder
.getContext();
+ Authentication currentAuth = securityContext
+ .getAuthentication();
+ if (currentAuth != null)
+ throw new ArgeoException(
+ "System execution on an already authenticated thread: "
+ + currentAuth + ", THREAD="
+ + Thread.currentThread().getId());
+
+ Subject subject = Subject.getSubject(AccessController
+ .getContext());
+ if (subject != null
+ && !subject.getPrincipals(Authentication.class)
+ .isEmpty())
+ throw new ArgeoException(
+ "There is already an authenticated subject: "
+ + subject);
+
Authentication auth = authenticationManager
.authenticate(new InternalAuthentication(
systemAuthenticationKey));
securityContext.setAuthentication(auth);
-
- runnable.run();
+ try {
+ runnable.run();
+ } finally {
+ // remove the authentication
+ securityContext.setAuthentication(null);
+ }
}
};
}