KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jguard > core > authorization > policy > AbstractMultipleAppPolicy


1 /*
2 jGuard is a security framework based on top of jaas (java authentication and authorization security).
3 it is written for web applications, to resolve simply, access control problems.
4 version $Name$
5 http://sourceforge.net/projects/jguard/
6
7 Copyright (C) 2004 Charles GAY
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with this library; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
23
24 jGuard project home page:
25 http://sourceforge.net/projects/jguard/
26
27 */

28 package net.sf.jguard.core.authorization.policy;
29
30 import java.lang.ref.WeakReference JavaDoc;
31 import java.security.Permission JavaDoc;
32 import java.security.PermissionCollection JavaDoc;
33 import java.security.Policy JavaDoc;
34 import java.security.Principal JavaDoc;
35 import java.security.ProtectionDomain JavaDoc;
36 import java.util.Arrays JavaDoc;
37 import java.util.Enumeration JavaDoc;
38 import java.util.HashSet JavaDoc;
39 import java.util.Iterator JavaDoc;
40 import java.util.Map JavaDoc;
41 import java.util.Set JavaDoc;
42 import java.util.WeakHashMap JavaDoc;
43 import java.util.logging.Level JavaDoc;
44 import java.util.logging.Logger JavaDoc;
45
46 import net.sf.jguard.core.authorization.manager.PermissionProvider;
47 import net.sf.jguard.core.authorization.permissions.PermissionUtils;
48 import net.sf.jguard.core.principals.JMXPrincipal;
49
50
51 /**
52  * Jguard Policy implementation:
53  * handle all Authorization decisions.
54  * This implementation handles multiple policies. It is designed for
55  * multiple apps requiring different policies among the same VM. Exemple : webapps.
56  * @author <a HREF="mailto:diabolo512@users.sourceforge.net">Charles Gay</a>
57  * @author <a HREF="mailto:zelfdoen@users.sourceforge.net">Theo Niemeijer</a>
58  * @author <a HREF="mailto:vberetti@users.sourceforge.net">Vincent Beretti</a>
59  *
60  */

61 public abstract class AbstractMultipleAppPolicy extends JGuardPolicy {
62
63    private static Map JavaDoc permissionProviderRepository;
64    private static Logger JavaDoc logger = Logger.getLogger(AbstractMultipleAppPolicy.class.getName());
65
66    /**
67     * constructor.
68     *
69     */

70    public AbstractMultipleAppPolicy(){
71
72        logger.log(Level.INFO,"####### loading jGuardPolicy "+JGuardPolicy.version+" ###########");
73
74        permissionProviderRepository = new WeakHashMap JavaDoc();
75
76        loadDefaultPolicy();
77    }
78
79    /**
80     * constructor used to include the replaced Policy.
81     * @param oldPolicy replaced by jGuardPolicy
82     */

83    public AbstractMultipleAppPolicy(Policy JavaDoc oldPolicy){
84
85        logger.log(Level.INFO,"####### loading AbstractMultipleAppPolicy "+JGuardPolicy.version+" ###########");
86
87        permissionProviderRepository = new WeakHashMap JavaDoc();
88        defaultPolicy = oldPolicy;
89    }
90
91
92
93     /**
94      * refresh all the permissions.
95      * if somes changes are made with the permissionManager implementation,
96      * this method must be called to reflect these changes.
97      * you should use instead <i>public void refresh(Object objectID)</i> JGuardPolicy method
98      * to avoid performance issue (refresh all security configurations for all application policies).
99      * @see AbstractMultipleAppPolicy#refresh(Object objectID)
100      */

101     public void refresh() {
102         Set JavaDoc keys = permissionProviderRepository.keySet();
103         Iterator JavaDoc itKeys = keys.iterator();
104         while(itKeys.hasNext()){
105             Object JavaDoc objectID = itKeys.next();
106             refresh(objectID);
107         }
108         
109     }
110
111     /**
112      * refresh all the permissions.
113      * if somes changes are made with the permissionManager implementation,
114      * this method must be called to reflect these changes.
115      * @see AbstractMultipleAppPolicy#refresh()
116      * @param objectID webapplication's classloader
117      */

118     public void refresh(Object JavaDoc objectID) {
119         //we get the webapp corresponding permission manager
120
// and call its refresh method
121
PermissionProvider pm = getContextPermissionProvider(objectID);
122
123         if (pm != null) {
124             // Refresh the permission configuration
125
pm.refresh();
126        }
127     }
128
129
130     /**
131      * retrieve all user's permissions.
132      * if this protectionDomain is protected by jGuard,
133      * we add the jGuard additional permissions to the permissionCollection
134      * obtained with the defaultPolicy implementation
135      * when the SecurityManager is set.
136      * otherwise, the only PermissionCollection created by jGuard is returned.
137      * @see java.security.Policy#getPermissions(java.security.ProtectionDomain)
138      * @param protectionDomain
139      * @return permissions collection
140      */

141     public PermissionCollection JavaDoc getPermissions(ProtectionDomain JavaDoc protectionDomain) {
142         PermissionCollection JavaDoc pc = null;
143
144         // Get classloader for protection domain
145
ClassLoader JavaDoc cl = protectionDomain.getClassLoader();
146         // Get permission provider associated with classloader
147
PermissionProvider pm = getContextPermissionProvider(cl);
148
149         if(System.getSecurityManager()!=null){
150             pc = defaultPolicy.getPermissions(protectionDomain);
151         }
152
153         //if this protection domain is protected by jGuard
154
if(pm!=null){
155             //retrieve permissions from roles owned by the user which are active
156
//and resolve regexp in permissions
157
PermissionCollection JavaDoc pc2= pm.getPermissionCollection(new HashSet JavaDoc(Arrays.asList(protectionDomain.getPrincipals())),protectionDomain);
158             
159             //the SecurityManager is set,we merge the default permissionCollection and the permissionCollection returned by jGuard
160
if(System.getSecurityManager()!=null){
161                 Enumeration JavaDoc enumeration = pc2.elements();
162                 while(enumeration.hasMoreElements()){
163                     pc.add((Permission JavaDoc)enumeration.nextElement());
164                 }
165             }else{
166                 //there is no Securitymanager set
167
//we return only the permissionCollection obtained by jGuard
168
pc = pc2;
169             }
170         }
171
172         return pc;
173     }
174
175
176
177     /**
178     * Register permission provider. Registers given permission provider instance
179     * with the specified classloader instance.
180     * @param objectID - Object identifier
181     * @param pm - permission provider
182     *
183     */

184    public void registerPermissionProvider(Object JavaDoc objectID, PermissionProvider pm) {
185
186         if (getContextPermissionProvider(objectID) == null) {
187            // Put permission provider in map keyed by classloader
188
setContextPermissionProvider(objectID, pm);
189        }else{
190         logger.log(Level.SEVERE,"registerPermissionProvider() - two webapps have got the same classLoader ....application will stop");
191
192        //key is not unique => two webapps will have the same authorisation mechanism....ERROR
193
throw new RuntimeException JavaDoc(
194            " an exception occurs in the registerPermissionProvider method of the JGuardPolicy \n webApplication stops ");
195        }
196    }
197
198    /**
199     * Unregister permission provider. Removes permission provider associated with
200     * the given classloader instance.
201     *
202     * @param objectID - Object identifier
203     *
204     */

205    public void unregisterPermissionProvider(Object JavaDoc objectID) {
206
207         if (permissionProviderRepository.containsKey(objectID)) {
208
209             // Remove permission provider in map keyed by classloader
210
permissionProviderRepository.remove(objectID);
211         }
212    }
213
214     /**
215      * Get context permission provider. This is a helper method that
216      * uses weakhashmap and weakreferences to ensure that unloaded classes
217      * will become garbage collected.
218      *
219      * @param objectID - Object identifier
220      *
221      * @return permission provider
222      */

223     public PermissionProvider getContextPermissionProvider(Object JavaDoc objectID) {
224
225         // Get permission provider associated with classloader
226
WeakReference JavaDoc ref = (WeakReference JavaDoc) permissionProviderRepository.get(objectID);
227
228         if (ref == null) {
229             return null;
230         }
231
232         // Get permission provider from weak reference
233
PermissionProvider pm = (PermissionProvider) ref.get();
234
235         if (pm == null) {
236
237             return null;
238         }
239
240         return pm;
241     }
242
243     /**
244      * Set context permission provider. This is a helper method that
245      * uses weakhashmap and weakreferences to ensure that unloaded classes
246      * will become garbage collected.
247      *
248      * @param objectID - Identifier Object
249      * @param pm - permission provider
250      */

251     private void setContextPermissionProvider(Object JavaDoc objectID, PermissionProvider pm) {
252
253         // Put classloader and its associated permission provider in map
254
permissionProviderRepository.put(objectID, new WeakReference JavaDoc(pm));
255     }
256
257
258     /**
259      * sees if domain can match permission
260      * @param domain -
261      * @param permission - permission to be checked
262      * @return <code>true</code> if domain checks permission, <code>false</code> otherwise
263      */

264     public boolean implies(ProtectionDomain JavaDoc domain, Permission JavaDoc permission) {
265
266         if(domain.getClassLoader() == null){
267             // domain may be the ProtectionDomain generated
268
// during JMX connection. The JMX generated ProtectionDomain
269
// has null classLoader, null codeSource, empty permissions and
270
// the principals set during JGuardJMXAuthenticator.authenticate().
271
// This domain is created in JMXSubjectDomainCombiner.combine(...)
272
// It could also simply be a protection domain with null classloader
273
// but not very likely.
274
//
275
// The following test searches for a JMXPrincipal to ensure that
276
// this null classloader protectionDomain is indeed created for JMX.
277

278             Principal JavaDoc[] principals = domain.getPrincipals();
279             boolean jmxHandled = false;
280             int i = 0;
281             ProtectionDomain JavaDoc newDomain = null;
282
283             while (i < principals.length && !jmxHandled){
284                 if (principals[i] instanceof JMXPrincipal){
285                     newDomain = new ProtectionDomain JavaDoc(domain.getCodeSource(),
286                             domain.getPermissions(),
287                             (ClassLoader JavaDoc)((JMXPrincipal)principals[i]).getObjectID(),
288                             domain.getPrincipals());
289                     jmxHandled = true;
290                 }
291                 i++;
292             }
293
294             if (newDomain != null){
295                 // domain is the protectionDomain created in JMXSubjectDomainCombiner
296
// a new ProtectionDomain is created based on domain but it adds the
297
// classloader got from the JMXPrincipal. super.implies(newDomain,...);
298
// invokes the method getPermissions(newDomain) and with this new domain,
299
// getPermission is able to get the PermissionProvider of the webapp whose
300
// MBean are monitored by JMX.
301
return super.implies(newDomain, permission);
302             }
303         }
304         return super.implies(domain, permission);
305     }
306
307 }
308
Popular Tags