2 * Copyright (C) 2007-2012 Argeo GmbH
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package org
.argeo
.security
.core
;
18 import javax
.security
.auth
.login
.LoginContext
;
19 import javax
.security
.auth
.login
.LoginException
;
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
;
33 /** Provides base method for executing code with system authorization. */
34 public abstract class AbstractSystemExecution
{
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) ==
41 // SecurityContextHolder
42 // .setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL);
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";
52 /** Whether the current thread was authenticated by this component. */
53 private ThreadLocal
<Boolean
> authenticatedBySelf
= new ThreadLocal
<Boolean
>() {
54 protected Boolean
initialValue() {
60 * Authenticate the calling thread to the underlying
61 * {@link AuthenticationManager}
63 protected void authenticateAsSystem() {
64 if (authenticatedBySelf
.get())
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());
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);
82 String key
= systemAuthenticationKey
!= null ? systemAuthenticationKey
84 InternalAuthentication
.SYSTEM_KEY_PROPERTY
,
85 InternalAuthentication
.SYSTEM_KEY_DEFAULT
);
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
);
95 if (bundleContext
== null)
96 throw new ArgeoException("bundleContext must be set");
97 BundleContextCallbackHandler callbackHandler
= new BundleContextCallbackHandler(
99 LoginContext loginContext
= new LoginContext(loginContextName
,
101 loginContext
.login();
102 } catch (LoginException e
) {
103 throw new BadCredentialsException("Cannot authenticate");
106 authenticatedBySelf
.set(true);
107 if (log
.isTraceEnabled())
108 log
.trace("System authenticated");
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();
124 * Whether the current thread was authenticated by this component or a
127 protected Boolean
isAuthenticatedBySelf() {
128 return authenticatedBySelf
.get();
132 public void setAuthenticationManager(
133 AuthenticationManager authenticationManager
) {
134 // log.warn("This approach is deprecated, inject bundleContext instead");
135 this.authenticationManager
= authenticationManager
;
139 public void setSystemAuthenticationKey(String systemAuthenticationKey
) {
140 this.systemAuthenticationKey
= systemAuthenticationKey
;
143 public void setBundleContext(BundleContext bundleContext
) {
144 this.bundleContext
= bundleContext
;