KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jonas > web > lib > PermissionManager


1 /**
2  * JOnAS: Java(TM) Open Application Server
3  * Copyright (C) 2004-2005 Bull S.A.
4  * Contact: jonas-team@objectweb.org
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19  * USA
20  *
21  * --------------------------------------------------------------------------
22  * $Id: PermissionManager.java,v 1.10 2005/05/05 16:09:14 benoitf Exp $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.jonas.web.lib;
27
28 import java.net.MalformedURLException JavaDoc;
29 import java.net.URI JavaDoc;
30 import java.net.URISyntaxException JavaDoc;
31 import java.net.URL JavaDoc;
32 import java.security.CodeSource JavaDoc;
33 import java.security.Permission JavaDoc;
34 import java.security.PermissionCollection JavaDoc;
35 import java.security.Principal JavaDoc;
36 import java.security.ProtectionDomain JavaDoc;
37 import java.security.cert.Certificate JavaDoc;
38 import java.util.ArrayList JavaDoc;
39 import java.util.Collection JavaDoc;
40 import java.util.Iterator JavaDoc;
41 import java.util.List JavaDoc;
42 import java.util.Map JavaDoc;
43
44 import javax.security.jacc.PolicyContext JavaDoc;
45 import javax.security.jacc.PolicyContextException JavaDoc;
46 import javax.security.jacc.WebResourcePermission JavaDoc;
47 import javax.security.jacc.WebRoleRefPermission JavaDoc;
48 import javax.security.jacc.WebUserDataPermission JavaDoc;
49 import javax.servlet.http.HttpServletRequest JavaDoc;
50
51 import org.objectweb.jonas.common.Log;
52 import org.objectweb.jonas.security.jacc.JPolicyContextHandlerCurrent;
53 import org.objectweb.jonas.security.jacc.JPolicyContextHandlerData;
54 import org.objectweb.jonas.security.jacc.JPolicyUserRoleMapping;
55
56 import org.objectweb.jonas_lib.deployment.api.SecurityRoleRefDesc;
57 import org.objectweb.jonas_lib.security.AbsPermissionManager;
58 import org.objectweb.jonas_lib.security.PermissionManagerException;
59 import org.objectweb.jonas_web.deployment.api.SecurityConstraintListDesc;
60 import org.objectweb.jonas_web.deployment.api.SecurityRoleDesc;
61 import org.objectweb.jonas_web.deployment.api.ServletDesc;
62 import org.objectweb.jonas_web.deployment.api.WebContainerDeploymentDesc;
63 import org.objectweb.util.monolog.api.BasicLevel;
64 import org.objectweb.util.monolog.api.Logger;
65
66 /**
67  * Defines a PermissionManager class which will manage JACC permissions for a
68  * web-app
69  * @author Florent Benoit
70  */

71 public class PermissionManager extends AbsPermissionManager {
72
73     /**
74      * Logger used
75      */

76     private static Logger logger = null;
77
78     /**
79      * Deployment desc of the module
80      */

81     private WebContainerDeploymentDesc webContainerDeploymentDesc = null;
82
83     /**
84      * Default Constructor
85      * @param webContainerDeploymentDesc EJB deployment Descriptor
86      * @param contextId context ID used for PolicyContext
87      * @throws PermissionManagerException if permissions can't be set
88      */

89     public PermissionManager(final WebContainerDeploymentDesc webContainerDeploymentDesc, final String JavaDoc contextId)
90             throws PermissionManagerException {
91         super(contextId);
92         this.webContainerDeploymentDesc = webContainerDeploymentDesc;
93         logger = Log.getLogger(Log.JONAS_WEB_PREFIX);
94     }
95
96     /**
97      * 3.1.3.Translating Servlet Deployment Descriptors A reference to a
98      * PolicyConfiguration object must be obtained by calling the
99      * getPolicyConfiguration method on the PolicyConfigurationFactory
100      * implementation class of the provider configured into the container. The
101      * policy context identifier used in the call to the getPolicyConfiguration
102      * method must be a String composed as described in Section 3.1.2, Servlet
103      * Policy Context Identifiers, on page 19. The value true must be passed as
104      * the second parameter in the call to getPolicyConfiguration to ensure that
105      * any and all policy statements are removed from the policy context
106      * associated with the returned PolicyConfiguration. The security-constraint
107      * and securityrole-ref elements in the deployment descriptor must be
108      * translated into permissions and added to the PolicyConfiguration object
109      * as defined in the following sections.
110      * @throws PermissionManagerException if permissions can't be set
111      */

112     public void translateServletDeploymentDescriptor() throws PermissionManagerException {
113         translateSecurityConstraintElements();
114         translateServletSecurityRoleRef();
115     }
116
117     /**
118      * 3.1.3.1 Translating security-constraint elements The paragraphs of this
119      * section describe the translation of security-constraints into
120      * WebResourcePermission and WebUserDataPermission objects constructed using
121      * qualified URL pattern names. In the exceptional case, as defined in
122      * Qualified URL Pattern Names, where a pattern is made irrelevant by a
123      * qualifying pattern, the permission instantiations that would result from
124      * the translation of the pattern, as described below, must not be
125      * performed. Otherwise, the translation of URL patterns in security
126      * constraints must yield an equivalent translation to the translation that
127      * would result from following the instructions in the remainder of this
128      * section. [...]
129      * @throws PermissionManagerException if permissions can't be set
130      */

131     protected void translateSecurityConstraintElements() throws PermissionManagerException {
132         if (webContainerDeploymentDesc == null || getPolicyConfiguration() == null) {
133             throw new PermissionManagerException("PolicyConfiguration or webContainerbDeploymentDesc is null");
134         }
135
136         SecurityConstraintListDesc securityConstraintListDesc = webContainerDeploymentDesc
137                 .getSecurityConstraintListDesc();
138         PermissionCollection JavaDoc excludedPermissions = securityConstraintListDesc.getExcludedPermissions();
139         PermissionCollection JavaDoc uncheckedPermissions = securityConstraintListDesc.getUncheckedPermissions();
140         PermissionCollection JavaDoc rolePermissions = null;
141         String JavaDoc roleName = null;
142         Map JavaDoc roleMapPermissions = securityConstraintListDesc.getPermissionsByRole();
143
144         try {
145             getPolicyConfiguration().addToExcludedPolicy(excludedPermissions);
146             getPolicyConfiguration().addToUncheckedPolicy(uncheckedPermissions);
147
148             for (Iterator JavaDoc rolesIt = roleMapPermissions.keySet().iterator(); rolesIt.hasNext();) {
149                 roleName = (String JavaDoc) rolesIt.next();
150                 rolePermissions = (PermissionCollection JavaDoc) roleMapPermissions.get(roleName);
151                 getPolicyConfiguration().addToRole(roleName, rolePermissions);
152             }
153         } catch (PolicyContextException JavaDoc pce) {
154             throw new PermissionManagerException("Can not add add permissions to policy", pce);
155         }
156     }
157
158     /**
159      * 3.1.3.2 Translating Servlet security-role-ref Elements For each
160      * security-role-ref appearing in the deployment descriptor a corresponding
161      * WebRoleRefPermission must be added to the corresponding role. The name of
162      * the WebRoleRefPermission must be the servlet-name in whose context the
163      * security-role-ref is defined. The actions of the WebRoleRefPermission
164      * must be the value of the role-name (that is the reference), appearing in
165      * the security-role-ref. The deployment tools must call the addToRole
166      * method on the PolicyConfiguration object to add the WebRoleRefPermission
167      * object resulting from the translation to the role identified in the
168      * role-link appearing in the security-role-ref. Additional
169      * WebRoleRefPermission objects must be added to the PolicyConfiguration as
170      * follows. For each servlet element in the deployment descriptor a
171      * WebRoleRefPermission must be added to each security-role whose name does
172      * not appear as the role-name in a security-role-ref within the servlet
173      * element. The name of each such WebRoleRefPermission must be the
174      * servlet-name of the corresponding servlet element. The actions (that is,
175      * reference) of each such WebRoleRefPermission must be the corresponding
176      * (non-appearing) role-name. The resulting permissions must be added to the
177      * corresponding roles by calling the addToRole method on the
178      * PolicyConfiguration object.
179      * @throws PermissionManagerException if permissions can't be set
180      */

181     protected void translateServletSecurityRoleRef() throws PermissionManagerException {
182         if (webContainerDeploymentDesc == null || getPolicyConfiguration() == null) {
183             throw new PermissionManagerException("PolicyConfiguration or webContainerbDeploymentDesc is null");
184         }
185
186         Collection JavaDoc servlets = webContainerDeploymentDesc.getServletDescList();
187
188         // List of roles which appear as role-name in a security-role-ref
189
List JavaDoc rolesAppearedInSecurityRoleRef = new ArrayList JavaDoc();
190
191         /*
192          * For each security-role-ref appearing in the deployment descriptor a
193          * corresponding WebRoleRefPermission must be added to the corresponding
194          * role. The name of the WebRoleRefPermission must be the servlet-name
195          * in whose context the security-role-ref is defined. The actions of the
196          * WebRoleRefPermission must be the value of the role-name (that is the
197          * reference), appearing in the security-role-ref
198          */

199         ServletDesc servletDesc = null;
200         String JavaDoc servletName = null;
201         List JavaDoc roleRefs = null;
202         SecurityRoleRefDesc securityRoleRefDesc = null;
203         for (Iterator JavaDoc itServlet = servlets.iterator(); itServlet.hasNext();) {
204             servletDesc = (ServletDesc) itServlet.next();
205             roleRefs = servletDesc.getSecurityRoleRefList();
206             servletName = servletDesc.getServletName();
207             for (Iterator JavaDoc itRoleRef = roleRefs.iterator(); itRoleRef.hasNext();) {
208                 securityRoleRefDesc = (SecurityRoleRefDesc) itRoleRef.next();
209                 /*
210                  * The deployment tools must call the addToRole method on the
211                  * PolicyConfiguration object to add the WebRoleRefPermission
212                  * object resulting from the translation to the role identified
213                  * in the role-link appearing in the security-role-ref.
214                  */

215                 Permission JavaDoc webRoleRefPermission = securityRoleRefDesc.getWebRoleRefPermission();
216
217                 // Role has appear
218
rolesAppearedInSecurityRoleRef.add(securityRoleRefDesc.getRoleName());
219
220                 try {
221                     getPolicyConfiguration().addToRole(securityRoleRefDesc.getRoleLink(), webRoleRefPermission);
222                 } catch (PolicyContextException JavaDoc pce) {
223                     throw new PermissionManagerException("Can not add add permission '" + webRoleRefPermission
224                             + "' to policy", pce);
225                 }
226             }
227         }
228
229         /*
230          * Additional WebRoleRefPermission objects must be added to the
231          * PolicyConfiguration as follows. For each servlet element in the
232          * deployment descriptor a WebRoleRefPermission must be added to each
233          * security-role whose name does not appear as the role-name in a
234          * security-role-ref within the servlet element.
235          */

236         List JavaDoc securityRoles = webContainerDeploymentDesc.getSecurityRoleList();
237         SecurityRoleDesc securityRoleDesc = null;
238         String JavaDoc securityRoleName = null;
239
240         for (Iterator JavaDoc itServlet = servlets.iterator(); itServlet.hasNext();) {
241             servletDesc = (ServletDesc) itServlet.next();
242             servletName = servletDesc.getServletName();
243
244             for (Iterator JavaDoc itSecurityRoles = securityRoles.iterator(); itSecurityRoles.hasNext();) {
245                 securityRoleDesc = (SecurityRoleDesc) itSecurityRoles.next();
246                 securityRoleName = securityRoleDesc.getRoleName();
247                 // if role does not appear as the role-name in a
248
// security-role-ref
249
// need to create permission
250
if (!rolesAppearedInSecurityRoleRef.contains(securityRoleName)) {
251
252                     /*
253                      * The name of each such WebRoleRefPermission must be the
254                      * servlet-name of the corresponding servlet element. The
255                      * actions (that is, reference) of each such
256                      * WebRoleRefPermission must be the corresponding
257                      * (non-appearing) role-name. The resulting permissions must
258                      * be added to the corresponding roles by calling the
259                      * addToRole method on the PolicyConfiguration object.
260                      */

261                     Permission JavaDoc webRoleRefPermission = new WebRoleRefPermission JavaDoc(servletName, securityRoleName);
262                     try {
263                         getPolicyConfiguration().addToRole(securityRoleName, webRoleRefPermission);
264                     } catch (PolicyContextException JavaDoc pce) {
265                         throw new PermissionManagerException("Can not add add permission '" + webRoleRefPermission
266                                 + "' to policy", pce);
267                     }
268                 }
269             }
270         }
271
272         /**
273          * For resolution B19 added for maintenance review, WebRoleRefPermission
274          * must be added with empty strings for every security role
275          */

276         securityRoles = webContainerDeploymentDesc.getSecurityRoleList();
277         for (Iterator JavaDoc itSecurityRoles = securityRoles.iterator(); itSecurityRoles.hasNext();) {
278             securityRoleDesc = (SecurityRoleDesc) itSecurityRoles.next();
279             securityRoleName = securityRoleDesc.getRoleName();
280             /**
281              * Add permission with empty name
282              * B19 resolution
283              */

284             Permission JavaDoc webRoleRefPermission = new WebRoleRefPermission JavaDoc("", securityRoleName);
285             try {
286                 getPolicyConfiguration().addToRole(securityRoleName, webRoleRefPermission);
287             } catch (PolicyContextException JavaDoc pce) {
288                 throw new PermissionManagerException("Can not add add permission '" + webRoleRefPermission
289                         + "' to policy", pce);
290             }
291         }
292     }
293
294     /**
295      * Check the security for a given HttpServletReauest
296      * @param request the http servlet request
297      * @param principalName name of the principal
298      * @param roles array of roles for this permission
299      * @return true if the permission is granted, else false
300      */

301     public boolean checkWebUserDataPermission(HttpServletRequest JavaDoc request, String JavaDoc principalName, String JavaDoc[] roles) {
302
303         try {
304             ProtectionDomain JavaDoc protectionDomain = initPolicyContext(request, principalName, roles);
305
306             //TODO : cache request to avoid creation of a new
307
// WebUserDatapermission each time
308
// See JACC 4.12
309
WebUserDataPermission JavaDoc webUserDataPermission = new WebUserDataPermission JavaDoc(request);
310             boolean accessOK = getPolicy().implies(protectionDomain, webUserDataPermission);
311
312             if (logger.isLoggable(BasicLevel.DEBUG)) {
313                 logger.log(BasicLevel.DEBUG, "Policy.implies result = " + accessOK);
314             }
315             return accessOK;
316
317         } catch (Exception JavaDoc e) {
318             logger.log(BasicLevel.ERROR, "Can't check web user data permission :" + e.getMessage());
319             return false;
320         }
321
322     }
323
324     /**
325      * Check the security for a given HttpServletReauest
326      * @param request the http servlet request
327      * @param principalName name of the principal
328      * @param roles array of roles for this permission
329      * @return true if the permission is granted, else false
330      */

331     public boolean checkWebResourcePermission(HttpServletRequest JavaDoc request, String JavaDoc principalName, String JavaDoc[] roles) {
332         try {
333             ProtectionDomain JavaDoc protectionDomain = initPolicyContext(request, principalName, roles);
334
335             //TODO : cache request to avoid creation of a new
336
// WebResourcePermission each time
337
// See JACC 4.12
338
WebResourcePermission JavaDoc webResourcePermission = new WebResourcePermission JavaDoc(request);
339             boolean accessOK = getPolicy().implies(protectionDomain, webResourcePermission);
340             if (logger.isLoggable(BasicLevel.DEBUG)) {
341                 logger.log(BasicLevel.DEBUG, "Policy.implies result = " + accessOK);
342             }
343             return accessOK;
344
345         } catch (Exception JavaDoc e) {
346             logger.log(BasicLevel.ERROR, "Can't check web resource permission :" + e.getMessage());
347             return false;
348         }
349
350     }
351
352     /**
353      * Check the security for a given HttpServletReauest
354      * @param request the http servlet request
355      * @param servletName Name of the servlet
356      * @param principalName name of the principal
357      * @param roles array of roles for this permission
358      * @param roleName name of the role
359      * @return true if the permission is granted, else false
360      */

361     public boolean checkWebRoleRefPermission(HttpServletRequest JavaDoc request, String JavaDoc servletName, String JavaDoc principalName, String JavaDoc[] roles,
362             String JavaDoc roleName) {
363         try {
364
365             ProtectionDomain JavaDoc protectionDomain = initPolicyContext(request, principalName, roles);
366
367             //TODO : cache request to avoid creation of a new
368
// WebRoleRefPermission each time
369
// See JACC 4.12
370
WebRoleRefPermission JavaDoc webRoleRefPermission = new WebRoleRefPermission JavaDoc(servletName, roleName);
371             boolean accessOK = getPolicy().implies(protectionDomain, webRoleRefPermission);
372             if (logger.isLoggable(BasicLevel.DEBUG)) {
373                 logger.log(BasicLevel.DEBUG, "Policy.implies result = " + accessOK);
374             }
375             return accessOK;
376
377         } catch (Exception JavaDoc e) {
378             logger.log(BasicLevel.ERROR, "Can't check web role ref permission :" + e.getMessage());
379             return false;
380         }
381
382     }
383
384     /**
385      * Init the PolicyContext and return a protectionDomain
386      * @param request the http servlet request
387      * @param principalName name of the principal
388      * @param roles array of roles for this permission
389      * @return the protection domain built with given arguments
390      * @throws URISyntaxException if the URI can't be built
391      * @throws MalformedURLException if the URL of the codesource can't be built
392      */

393     private synchronized ProtectionDomain JavaDoc initPolicyContext(HttpServletRequest JavaDoc request, String JavaDoc principalName, String JavaDoc[] roles)
394             throws URISyntaxException JavaDoc, MalformedURLException JavaDoc {
395
396         // Set the policy context
397
PolicyContext.setContextID(getContextId());
398
399         // Configure ContextHandler
400
JPolicyContextHandlerData jPolicyContextHandlerData = JPolicyContextHandlerCurrent.getCurrent()
401                 .getJPolicyContextHandlerData();
402         if (jPolicyContextHandlerData == null) {
403             logger.log(BasicLevel.ERROR, "The Handler data retrieved is null !");
404             return null;
405         }
406         jPolicyContextHandlerData.setHttpServletRequest(request);
407         PolicyContext.setHandlerData(jPolicyContextHandlerData);
408
409         // Build Protection Domain with a codesource and array of principal
410
URI JavaDoc uri = new URI JavaDoc("file://" + getContextId());
411         CodeSource JavaDoc codesource = new CodeSource JavaDoc(new URL JavaDoc(uri.toString()), (Certificate JavaDoc[]) null);
412
413         // Existing mapping ?
414
String JavaDoc[] overridedRoles = JPolicyUserRoleMapping.getMappingForPrincipal(getContextId(), principalName);
415         if (overridedRoles != null) {
416             roles = overridedRoles;
417         }
418
419         Principal JavaDoc[] principals = null;
420         if (roles != null) {
421             principals = new Principal JavaDoc[roles.length];
422             for (int k = 0; k < roles.length; k++) {
423                 principals[k] = new org.objectweb.jonas.security.auth.JPrincipal(roles[k]);
424             }
425         }
426
427         return new ProtectionDomain JavaDoc(codesource, null, null, principals);
428     }
429
430     /**
431      * Reset Deployment Descriptor
432      */

433     protected void resetDeploymentDesc() {
434         webContainerDeploymentDesc = null;
435     }
436
437 }
438
Popular Tags