]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.security.core/src/org/argeo/security/core/AbstractSystemExecution.java
Move Jackrabbit security model
[lgpl/argeo-commons.git] / org.argeo.security.core / src / org / argeo / security / core / AbstractSystemExecution.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.argeo.security.core;
17
18 import javax.security.auth.login.LoginContext;
19 import javax.security.auth.login.LoginException;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.argeo.ArgeoException;
24 import org.argeo.security.SystemAuthentication;
25 import org.argeo.security.login.BundleContextCallbackHandler;
26 import org.osgi.framework.BundleContext;
27 import org.springframework.security.authentication.AuthenticationManager;
28 import org.springframework.security.authentication.BadCredentialsException;
29 import org.springframework.security.core.Authentication;
30 import org.springframework.security.core.context.SecurityContext;
31 import org.springframework.security.core.context.SecurityContextHolder;
32
33 /** Provides base method for executing code with system authorization. */
34 public abstract class AbstractSystemExecution {
35 static {
36 // Forces Spring Security to use inheritable strategy
37 // FIXME find a better place for forcing spring security mode
38 // doesn't work for the time being
39 // if (System.getProperty(SecurityContextHolder.SYSTEM_PROPERTY) ==
40 // null)
41 // SecurityContextHolder
42 // .setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
43 }
44
45 private final static Log log = LogFactory
46 .getLog(AbstractSystemExecution.class);
47 private AuthenticationManager authenticationManager;
48 private BundleContext bundleContext;
49 private String systemAuthenticationKey;
50 private String loginContextName = "SYSTEM";
51
52 /** Whether the current thread was authenticated by this component. */
53 private ThreadLocal<Boolean> authenticatedBySelf = new ThreadLocal<Boolean>() {
54 protected Boolean initialValue() {
55 return false;
56 }
57 };
58
59 /**
60 * Authenticate the calling thread to the underlying
61 * {@link AuthenticationManager}
62 */
63 protected void authenticateAsSystem() {
64 if (authenticatedBySelf.get())
65 return;
66 SecurityContext securityContext = SecurityContextHolder.getContext();
67 Authentication currentAuth = securityContext.getAuthentication();
68 if (currentAuth != null) {
69 if (!(currentAuth instanceof SystemAuthentication))
70 throw new ArgeoException(
71 "System execution on an already authenticated thread: "
72 + currentAuth + ", THREAD="
73 + Thread.currentThread().getId());
74 return;
75 }
76 // Subject subject = Subject.getSubject(AccessController.getContext());
77 // if (subject != null
78 // && !subject.getPrincipals(Authentication.class).isEmpty())
79 // throw new ArgeoException(
80 // "There is already an authenticated subject: " + subject);
81
82 String key = systemAuthenticationKey != null ? systemAuthenticationKey
83 : System.getProperty(
84 InternalAuthentication.SYSTEM_KEY_PROPERTY,
85 InternalAuthentication.SYSTEM_KEY_DEFAULT);
86 if (key == null)
87 throw new ArgeoException("No system key defined");
88 if (authenticationManager != null) {
89 Authentication auth = authenticationManager
90 .authenticate(new InternalAuthentication(key));
91 securityContext.setAuthentication(auth);
92 } else {
93 try {
94 // TODO test this
95 if (bundleContext == null)
96 throw new ArgeoException("bundleContext must be set");
97 BundleContextCallbackHandler callbackHandler = new BundleContextCallbackHandler(
98 bundleContext);
99 LoginContext loginContext = new LoginContext(loginContextName,
100 callbackHandler);
101 loginContext.login();
102 } catch (LoginException e) {
103 throw new BadCredentialsException("Cannot authenticate");
104 }
105 }
106 authenticatedBySelf.set(true);
107 if (log.isTraceEnabled())
108 log.trace("System authenticated");
109 }
110
111 // /** Removes the authentication from the calling thread. */
112 // protected void deauthenticateAsSystem() {
113 // // remove the authentication
114 // // SecurityContext securityContext = SecurityContextHolder.getContext();
115 // // securityContext.setAuthentication(null);
116 // // authenticatedBySelf.set(false);
117 // if (log.isTraceEnabled()) {
118 // log.trace("System deauthenticated");
119 // // Thread.dumpStack();
120 // }
121 // }
122
123 /**
124 * Whether the current thread was authenticated by this component or a
125 * parent thread.
126 */
127 protected Boolean isAuthenticatedBySelf() {
128 return authenticatedBySelf.get();
129 }
130
131 @Deprecated
132 public void setAuthenticationManager(
133 AuthenticationManager authenticationManager) {
134 // log.warn("This approach is deprecated, inject bundleContext instead");
135 this.authenticationManager = authenticationManager;
136 }
137
138 @Deprecated
139 public void setSystemAuthenticationKey(String systemAuthenticationKey) {
140 this.systemAuthenticationKey = systemAuthenticationKey;
141 }
142
143 public void setBundleContext(BundleContext bundleContext) {
144 this.bundleContext = bundleContext;
145 }
146
147 }