KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > easybeans > security > permissions > PermissionManager


1 /**
2  * EasyBeans
3  * Copyright (C) 2006 Bull S.A.S.
4  * Contact: easybeans@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 1152 2006-10-11 14:07:37Z benoitf $
23  * --------------------------------------------------------------------------
24  */

25
26 package org.objectweb.easybeans.security.permissions;
27
28 import java.net.URL JavaDoc;
29 import java.security.CodeSource JavaDoc;
30 import java.security.Principal JavaDoc;
31 import java.security.ProtectionDomain JavaDoc;
32 import java.security.cert.Certificate JavaDoc;
33 import java.util.List JavaDoc;
34
35 import javax.security.jacc.EJBMethodPermission JavaDoc;
36 import javax.security.jacc.EJBRoleRefPermission JavaDoc;
37 import javax.security.jacc.PolicyContext JavaDoc;
38 import javax.security.jacc.PolicyContextException JavaDoc;
39
40 import org.objectweb.easybeans.api.EZBPermissionManager;
41 import org.objectweb.easybeans.api.EasyBeansInvocationContext;
42 import org.objectweb.easybeans.api.PermissionManagerException;
43 import org.objectweb.easybeans.api.bean.info.IBeanInfo;
44 import org.objectweb.easybeans.api.bean.info.IEJBJarInfo;
45 import org.objectweb.easybeans.api.bean.info.IMethodSecurityInfo;
46 import org.objectweb.easybeans.api.bean.info.ISecurityInfo;
47 import org.objectweb.easybeans.log.JLog;
48 import org.objectweb.easybeans.log.JLogFactory;
49 import org.objectweb.easybeans.security.propagation.context.SecurityCurrent;
50
51 /**
52  * Permission manager for EJB.
53  * @author Florent Benoit
54  */

55 public class PermissionManager extends AbsPermissionManager implements EZBPermissionManager {
56
57     /**
58      * Logger.
59      */

60     private JLog logger = JLogFactory.getLog(PermissionManager.class);
61
62     /**
63      * CodeSource.
64      */

65     private CodeSource JavaDoc codeSource = null;
66
67     /**
68      * EJB-jar Info.
69      */

70     private IEJBJarInfo ejbJarInfo;
71
72     /**
73      * Default Constructor.
74      * @param contextIdURL context ID used for PolicyContext
75      * @param ejbJarInfo the metadata on all the beans (runtime info)
76      * @throws PermissionManagerException if permissions can't be set
77      */

78     public PermissionManager(final URL JavaDoc contextIdURL, final IEJBJarInfo ejbJarInfo) throws PermissionManagerException {
79         super(contextIdURL);
80         this.ejbJarInfo = ejbJarInfo;
81         this.codeSource = new CodeSource JavaDoc(contextIdURL, (Certificate JavaDoc[]) null);
82
83     }
84
85     /**
86      * 3.1.5 Translating EJB Deployment Descriptors<br>
87      * A reference to a PolicyConfiguration object must be obtained by calling
88      * the getPolicyConfiguration method on the PolicyConfigurationFactory
89      * implementation class of the provider configured into the container. The
90      * policy context identifier used in the call to getPolicyConfiguration must
91      * be a String that satisfies the requirements described in Section 3.1.4,
92      * EJB Policy Context Identifiers, on page 28. The value true must be passed
93      * as the second parameter in the call to getPolicyConfiguration to ensure
94      * that any and all policy statements are removed from the policy context
95      * associated with the returned PolicyConfiguration. The method-permission,
96      * exclude-list, and security-role-ref elements appearing in the deployment
97      * descriptor must be translated into permissions and added to the
98      * PolicyConfiguration object to yield an equivalent translation as that
99      * defined in the following sections and such that every EJB method for
100      * which the container performs pre-dispatch access decisions is implied by
101      * at least one permission resulting from the translation.
102      * @throws PermissionManagerException if permissions can't be set
103      */

104     public void translateMetadata() throws PermissionManagerException {
105         List JavaDoc<IBeanInfo> beansInfo = ejbJarInfo.getBeanInfos();
106         if (beansInfo != null) {
107             for (IBeanInfo beanInfo : beansInfo) {
108                 ISecurityInfo securityInfo = beanInfo.getSecurityInfo();
109                 translateEjbMethodPermission(securityInfo);
110                 translateEjbExcludeList(securityInfo);
111                 translateEjbSecurityRoleRef(beanInfo, securityInfo);
112             }
113         }
114     }
115
116     /**
117      * 3.1.5.1 Translating EJB method-permission Elements<br>
118      * For each method element of each method-permission element, an
119      * EJBMethodPermission object translated from the method element must be
120      * added to the policy statements of the PolicyConfiguration object. The
121      * name of each such EJBMethodPermission object must be the ejb-name from
122      * the corresponding method element, and the actions must be established by
123      * translating the method element into a method specification according to
124      * the methodSpec syntax defined in the documentation of the
125      * EJBMethodPermission class. The actions translation must preserve the
126      * degree of specificity with respect to method-name, method-intf, and
127      * method-params inherent in the method element. If the method-permission
128      * element contains the unchecked element, then the deployment tools must
129      * call the addToUncheckedPolicy method to add the permissions resulting
130      * from the translation to the PolicyConfiguration object. Alternatively, if
131      * the method-permission element contains one or more role-name elements,
132      * then the deployment tools must call the addToRole method to add the
133      * permissions resulting from the translation to the corresponding roles of
134      * the PolicyConfiguration object.
135      * @param securityInfo the security info for a given bean.
136      * @throws PermissionManagerException if permissions can't be set
137      */

138     protected void translateEjbMethodPermission(final ISecurityInfo securityInfo) throws PermissionManagerException {
139         List JavaDoc<IMethodSecurityInfo> methodSecurityInfos = securityInfo.getMethodSecurityInfos();
140         if (methodSecurityInfos != null) {
141             for (IMethodSecurityInfo methodSecurityInfo : methodSecurityInfos) {
142                 if (methodSecurityInfo.isUnchecked()) {
143                     try {
144                         logger.debug("Adding unchecked permission {0}", methodSecurityInfo.getPermission());
145                         getPolicyConfiguration().addToUncheckedPolicy(methodSecurityInfo.getPermission());
146                     } catch (PolicyContextException JavaDoc e) {
147                         throw new PermissionManagerException("Cannot add unchecked policy for method '" + methodSecurityInfo
148                                 + "'.", e);
149                     }
150                 } else {
151                     for (String JavaDoc roleName : methodSecurityInfo.getRoles()) {
152                         try {
153                             logger.debug("Adding permission {0} to role {1}", methodSecurityInfo.getPermission(), roleName);
154                             getPolicyConfiguration().addToRole(roleName, methodSecurityInfo.getPermission());
155                         } catch (PolicyContextException JavaDoc e) {
156                             throw new PermissionManagerException("Cannot add rolebase policy for method '" + methodSecurityInfo
157                                     + "' and for role '" + roleName + "'.", e);
158                         }
159                     }
160                 }
161             }
162         }
163     }
164
165     /**
166      * 3.1.5.2 Translating the EJB exclude-list<br>
167      * An EJBMethodPermission object must be created for each method element
168      * occurring in the exclude-list element of the deployment descriptor. The
169      * name and actions of each EJBMethodPermission must be established as
170      * described in Section 3.1.5.1, Translating EJB method-permission Elements.
171      * The deployment tools must use the addToExcludedPolicy method to add the
172      * EJBMethodPermission objects resulting from the translation of the
173      * exclude-list to the excluded policy statements of the PolicyConfiguration
174      * object.
175      * @param securityInfo the security info for a given bean.
176      * @throws PermissionManagerException if permissions can't be set
177      */

178     protected void translateEjbExcludeList(final ISecurityInfo securityInfo) throws PermissionManagerException {
179         List JavaDoc<IMethodSecurityInfo> methodSecurityInfos = securityInfo.getMethodSecurityInfos();
180         if (methodSecurityInfos != null) {
181             for (IMethodSecurityInfo methodSecurityInfo : methodSecurityInfos) {
182                 if (methodSecurityInfo.isExcluded()) {
183                     try {
184                         logger.debug("Adding excluded permission {0}", methodSecurityInfo.getPermission());
185                         getPolicyConfiguration().addToExcludedPolicy(methodSecurityInfo.getPermission());
186                     } catch (PolicyContextException JavaDoc e) {
187                         throw new PermissionManagerException("Cannot add excluded policy for method '" + methodSecurityInfo
188                                 + "'.", e);
189                     }
190                 }
191             }
192         }
193     }
194
195     /**
196      * 3.1.5.3 Translating EJB security-role-ref Elements<br>
197      * For each security-role-ref element appearing in the deployment
198      * descriptor, a corresponding EJBRoleRefPermission must be created. The
199      * name of each EJBRoleRefPermission must be obtained as described for
200      * EJBMethodPermission objects. The actions used to construct the permission
201      * must be the value of the role-name (that is the reference), appearing in
202      * the security-role-ref. The deployment tools must call the addToRole
203      * method on the PolicyConfiguration object to add a policy statement
204      * corresponding to the EJBRoleRefPermission to the role identified in the
205      * rolelink appearing in the security-role-ref.
206      * @param beanInfo info about the bean.
207      * @param securityInfo the security info for a given bean.
208      * @throws PermissionManagerException if permissions can't be set
209      */

210     public void translateEjbSecurityRoleRef(final IBeanInfo beanInfo, final ISecurityInfo securityInfo)
211             throws PermissionManagerException {
212         List JavaDoc<String JavaDoc> declaredRoles = securityInfo.getDeclaredRoles();
213         if (declaredRoles != null) {
214             for (String JavaDoc role : declaredRoles) {
215                 try {
216                     getPolicyConfiguration().addToRole(role, new EJBRoleRefPermission JavaDoc(beanInfo.getName(), role));
217                 } catch (PolicyContextException JavaDoc e) {
218                     throw new PermissionManagerException("Cannot add to role '" + role + "' an EJBRoleRefPermission.", e);
219                 }
220             }
221         }
222     }
223
224     /**
225      * Checks the security for the given invocation context.
226      * @param invocationContext the context to check.
227      * @param runAsBean if true, the bean is a run-as bean.
228      * @return true if the access has been granted, else false.
229      */

230     public boolean checkSecurity(final EasyBeansInvocationContext invocationContext, final boolean runAsBean) {
231         PolicyContext.setContextID(getContextId());
232
233         // Build Protection Domain with a codesource and array of principal
234
// Get roles.
235
Principal JavaDoc[] principals = SecurityCurrent.getCurrent().getSecurityContext().getCallerRoles(runAsBean);
236         ProtectionDomain JavaDoc protectionDomain = new ProtectionDomain JavaDoc(codeSource, null, null, principals);
237
238         boolean accessOK = getPolicy().implies(protectionDomain, invocationContextToMethodPermission(invocationContext));
239         if (logger.isDebugEnabled()) {
240             logger.debug("Policy.implies result = {0} ", Boolean.valueOf(accessOK));
241         }
242         return accessOK;
243     }
244
245     /**
246      * Gets a EJBMethodPermission from an invocation context.
247      * @param invocationContext the context containing data on the current
248      * invocation.
249      * @return a Method Permission for the current method.
250      */

251     private static EJBMethodPermission JavaDoc invocationContextToMethodPermission(final EasyBeansInvocationContext invocationContext) {
252         // TODO : cache ejbName/methodSignature to avoid creation of a new
253
// EJBMethodPermission each time
254
// See JACC 4.12
255

256         // TODO: Fix Remote/Local method-itf parameter. (set to "" for now)
257
EJBMethodPermission JavaDoc ejbMethodPermission = new EJBMethodPermission JavaDoc(invocationContext.getFactory().getBeanInfo().getName(),
258                 "", invocationContext.getMethod());
259
260         return ejbMethodPermission;
261     }
262
263     /**
264      * Test if the caller has a given role. EJBRoleRefPermission object must be
265      * created with ejbName and actions equal to roleName<br/>
266      * See section 4.3.2 of JACC
267      * @param ejbName The name of the EJB on wich look role
268      * @param roleName The name of the security role. The role must be one of
269      * the security-role-ref that is defined in the deployment
270      * descriptor.
271      * @param inRunAs bean calling this method is running in run-as mode or not ?
272      * @return True if the caller has the specified role.
273      */

274     public boolean isCallerInRole(final String JavaDoc ejbName, final String JavaDoc roleName, final boolean inRunAs) {
275         PolicyContext.setContextID(getContextId());
276         logger.debug("roleName = {0}", roleName);
277
278         // Build Protection Domain with a codesource and array of principals
279
Principal JavaDoc[] principals = SecurityCurrent.getCurrent().getSecurityContext().getCallerRoles(inRunAs);
280         ProtectionDomain JavaDoc protectionDomain = new ProtectionDomain JavaDoc(codeSource, null, null, principals);
281
282         // TODO :add cache mechanism ?
283
// See JACC 4.12
284
EJBRoleRefPermission JavaDoc ejbRoleRefPermission = new EJBRoleRefPermission JavaDoc(ejbName, roleName);
285         boolean isInRole = getPolicy().implies(protectionDomain, ejbRoleRefPermission);
286         return isInRole;
287
288     }
289
290 }
291
Popular Tags