]> git.argeo.org Git - lgpl/argeo-commons.git/blob - AbstractSystemExecution.java
b12629ab90ca64313ecb72317fae5408e5dd8296
[lgpl/argeo-commons.git] / AbstractSystemExecution.java
1 package org.argeo.security.core;
2
3 import java.security.AccessController;
4
5 import javax.security.auth.Subject;
6
7 import org.apache.commons.logging.Log;
8 import org.apache.commons.logging.LogFactory;
9 import org.argeo.ArgeoException;
10 import org.springframework.security.Authentication;
11 import org.springframework.security.AuthenticationManager;
12 import org.springframework.security.context.SecurityContext;
13 import org.springframework.security.context.SecurityContextHolder;
14
15 /** Provides base method for executing code with system authorization. */
16 public abstract class AbstractSystemExecution {
17 static {
18 // Forces Spring Security to use inheritable strategy
19 // FIXME find a better place for forcing spring security mode
20 // doesn't work for the time besing
21 // if (System.getProperty(SecurityContextHolder.SYSTEM_PROPERTY) == null)
22 // SecurityContextHolder
23 // .setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
24 }
25
26 private final static Log log = LogFactory
27 .getLog(AbstractSystemExecution.class);
28 private AuthenticationManager authenticationManager;
29 private String systemAuthenticationKey;
30
31 /** Whether the current thread was authenticated by this component. */
32 private InheritableThreadLocal<Boolean> authenticatedBySelf = new InheritableThreadLocal<Boolean>() {
33 protected Boolean initialValue() {
34 return false;
35 }
36 };
37
38 /**
39 * Authenticate the calling thread to the underlying
40 * {@link AuthenticationManager}
41 */
42 protected void authenticateAsSystem() {
43 if (authenticatedBySelf.get())
44 return;
45 SecurityContext securityContext = SecurityContextHolder.getContext();
46 Authentication currentAuth = securityContext.getAuthentication();
47 if (currentAuth != null){
48 throw new ArgeoException(
49 "System execution on an already authenticated thread: "
50 + currentAuth + ", THREAD="
51 + Thread.currentThread().getId());
52 }
53 Subject subject = Subject.getSubject(AccessController.getContext());
54 if (subject != null
55 && !subject.getPrincipals(Authentication.class).isEmpty())
56 throw new ArgeoException(
57 "There is already an authenticated subject: " + subject);
58
59 String key = systemAuthenticationKey != null ? systemAuthenticationKey
60 : System.getProperty(
61 InternalAuthentication.SYSTEM_KEY_PROPERTY,
62 InternalAuthentication.SYSTEM_KEY_DEFAULT);
63 if (key == null)
64 throw new ArgeoException("No system key defined");
65 Authentication auth = authenticationManager
66 .authenticate(new InternalAuthentication(key));
67 securityContext.setAuthentication(auth);
68 authenticatedBySelf.set(true);
69 if (log.isTraceEnabled())
70 log.trace("System authenticated");
71 }
72
73 /** Removes the authentication from the calling thread. */
74 protected void deauthenticateAsSystem() {
75 // remove the authentication
76 SecurityContext securityContext = SecurityContextHolder.getContext();
77 if (securityContext.getAuthentication() != null) {
78 securityContext.setAuthentication(null);
79 authenticatedBySelf.set(false);
80 if (log.isTraceEnabled()) {
81 log.trace("System deauthenticated");
82 // Thread.dumpStack();
83 }
84 }
85 }
86
87 /**
88 * Whether the current thread was authenticated by this component or a
89 * parent thread.
90 */
91 protected Boolean isAuthenticatedBySelf() {
92 return authenticatedBySelf.get();
93 }
94
95 public void setAuthenticationManager(
96 AuthenticationManager authenticationManager) {
97 this.authenticationManager = authenticationManager;
98 }
99
100 public void setSystemAuthenticationKey(String systemAuthenticationKey) {
101 this.systemAuthenticationKey = systemAuthenticationKey;
102 }
103
104 }