KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ejb3 > security > JaccHelper


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22
23 package org.jboss.ejb3.security;
24
25 import java.lang.reflect.Method JavaDoc;
26 import java.lang.reflect.Modifier JavaDoc;
27 import java.security.CodeSource JavaDoc;
28 import java.security.Policy JavaDoc;
29 import java.security.Principal JavaDoc;
30 import java.security.ProtectionDomain JavaDoc;
31 import java.util.Set JavaDoc;
32 import javax.annotation.security.DenyAll;
33 import javax.annotation.security.PermitAll;
34 import javax.annotation.security.RolesAllowed;
35 import javax.security.auth.Subject JavaDoc;
36 import javax.security.jacc.EJBMethodPermission JavaDoc;
37 import javax.security.jacc.PolicyConfiguration JavaDoc;
38 import javax.security.jacc.PolicyConfigurationFactory JavaDoc;
39 import javax.security.jacc.PolicyContextException JavaDoc;
40 import org.jboss.annotation.security.SecurityDomain;
41 import org.jboss.aop.metadata.SimpleClassMetaDataBinding;
42 import org.jboss.aop.metadata.SimpleClassMetaDataLoader;
43 import org.jboss.deployment.DeploymentInfo;
44 import org.jboss.ejb3.EJBContainer;
45 import org.jboss.logging.Logger;
46 import org.jboss.deployers.spi.deployer.DeploymentUnit;
47
48 /**
49  * @author <a HREF="mailto:kabir.khan@jboss.org">Kabir Khan</a>
50  * @version $Revision$
51  */

52 public class JaccHelper
53 {
54    static Logger log = Logger.getLogger(JaccHelper.class);
55
56    /**
57     * Creates a new policy configuration on (re)deployment. Context ID used is based on
58     * name of app, so we make sure we clean out any existing policy with that id.
59     */

60    public static PolicyConfiguration JavaDoc initialiseJacc(String JavaDoc contextID) throws Exception JavaDoc
61    {
62       log.debug("Initialising JACC Context for deployment: " + contextID);
63       PolicyConfigurationFactory JavaDoc pcFactory = Ejb3PolicyConfigurationFactory.getPolicyConfigurationFactory();
64       boolean removeExistingContext = true;
65       PolicyConfiguration JavaDoc pc = pcFactory.getPolicyConfiguration(contextID, removeExistingContext);
66
67       /*Set keys = PolicyContext.getHandlerKeys();
68       if (!keys.contains(EnterpriseBeanPolicyContextHandler.EJB_CONTEXT_KEY))
69       {
70          EnterpriseBeanPolicyContextHandler beanHandler = new EnterpriseBeanPolicyContextHandler();
71          PolicyContext.registerHandler(EnterpriseBeanPolicyContextHandler.EJB_CONTEXT_KEY,
72                beanHandler, false);
73       }
74       */

75       //Do I need this?
76
/*BeanMetaDataPolicyContextHandler metadataHandler = new BeanMetaDataPolicyContextHandler();
77       PolicyContext.registerHandler(BeanMetaDataPolicyContextHandler.METADATA_CONTEXT_KEY,
78          metadataHandler, false);*/

79       /*
80       if (!keys.contains(EJBArgsPolicyContextHandler.EJB_ARGS_KEY))
81       {
82          EJBArgsPolicyContextHandler argsHandler = new EJBArgsPolicyContextHandler();
83          PolicyContext.registerHandler(EJBArgsPolicyContextHandler.EJB_ARGS_KEY,
84                argsHandler, false);
85       }
86       */

87       return pc;
88    }
89
90    public static void putJaccInService(PolicyConfiguration JavaDoc pc, DeploymentUnit di) throws Exception JavaDoc
91    {
92
93    }
94    public static void putJaccInService(PolicyConfiguration JavaDoc pc, DeploymentInfo di) throws Exception JavaDoc
95    {
96       di.context.put("javax.security.jacc.PolicyConfiguration", pc);
97
98       // Link this to the parent PC
99
DeploymentInfo current = di;
100       while (current.parent != null)
101       {
102          current = current.parent;
103       }
104
105       PolicyConfiguration JavaDoc parentPC = (PolicyConfiguration JavaDoc)
106               current.context.get("javax.security.jacc.PolicyConfiguration");
107
108       if (parentPC != null && parentPC != pc)
109       {
110          parentPC.linkConfiguration(pc);
111       }
112
113       pc.commit();
114       log.debug("JACC Policy Configuration for deployment has been put in service");
115    }
116
117    public static void unregisterJacc(String JavaDoc contextID) throws Exception JavaDoc
118    {
119       PolicyConfigurationFactory JavaDoc pcFactory = Ejb3PolicyConfigurationFactory.getPolicyConfigurationFactory();
120       PolicyConfiguration JavaDoc pc = pcFactory.getPolicyConfiguration(contextID, true);
121       pc.delete();
122    }
123
124
125    public static void configureContainer(String JavaDoc jaccContextId, EJBContainer container)
126    {
127       try
128       {
129          addJaccContextToContainer(jaccContextId, container);
130          PolicyConfigurationFactory JavaDoc pcFactory = Ejb3PolicyConfigurationFactory.getPolicyConfigurationFactory();
131          PolicyConfiguration JavaDoc pc = pcFactory.getPolicyConfiguration(jaccContextId, false);
132
133          addPermissions(container, pc);
134       }
135       catch (Exception JavaDoc e)
136       {
137          e.printStackTrace();
138          throw new RuntimeException JavaDoc(e);
139       }
140    }
141
142    private static void addPermissions(EJBContainer container, PolicyConfiguration JavaDoc pc)
143    {
144       SecurityDomain sd = (SecurityDomain) container.resolveAnnotation(SecurityDomain.class);
145
146       if (sd == null)
147       {
148          log.debug(container.getEjbName() + " has no @SecurityDomain - skipping JACC configuration");
149          return;
150       }
151       log.debug(container.getEjbName() + " has @SecurityDomain - peforming JACC configuration");
152
153       PermitAll beanUnchecked = (PermitAll) container.resolveAnnotation(PermitAll.class);
154       RolesAllowed beanPermissions = (RolesAllowed) container.resolveAnnotation(RolesAllowed.class);
155
156       if (beanUnchecked != null && beanPermissions != null)
157       {
158          throw new RuntimeException JavaDoc("Cannot annotate a bean with both @Unchecked and @MethodPermissions");
159       }
160
161       String JavaDoc ejbName = container.getEjbName();
162
163       //Am I iterating over the right thing here? Should I be using the stuff from
164
//Advisor.methodInterceptors instead?
165
Method JavaDoc[] methods = container.getBeanClass().getDeclaredMethods();
166       for (int i = 0; i < methods.length; i++)
167       {
168          Method JavaDoc m = methods[i];
169          if (!Modifier.isPublic(m.getModifiers()))
170          {
171             continue;
172          }
173
174          EJBMethodPermission JavaDoc permission = new EJBMethodPermission JavaDoc(ejbName, null, m);
175          log.debug("Creating permission: " + permission);
176
177          PermitAll unchecked = (PermitAll) container.resolveAnnotation(m, PermitAll.class);
178          RolesAllowed permissions = (RolesAllowed) container.resolveAnnotation(m, RolesAllowed.class);
179          DenyAll exclude = (DenyAll) container.resolveAnnotation(m, DenyAll.class);
180
181          int annotationCount = getAnnotationCount(unchecked, permissions, exclude);
182
183          if (annotationCount == 0 && beanPermissions == null && beanUnchecked == null)
184          {
185             continue;
186          }
187          else if (annotationCount > 1)
188          {
189             throw new RuntimeException JavaDoc("You can only use one of @PermitAll, @DenyAll or @RolesAllowed per method");
190          }
191
192          try
193          {
194             //Method level annotations override the bean level annotations
195
if (unchecked != null)
196             {
197                pc.addToUncheckedPolicy(permission);
198                log.debug("Adding permission to unchecked policy");
199                continue;
200             }
201             if (permissions != null)
202             {
203                addToRole(pc, permission, permissions);
204                continue;
205             }
206             if (exclude != null)
207             {
208                pc.addToExcludedPolicy(permission);
209                log.debug("Adding permission to excluded policy");
210                continue;
211             }
212
213             if (beanUnchecked != null)
214             {
215                pc.addToUncheckedPolicy(permission);
216                log.debug("Adding permission to unchecked policy");
217                continue;
218             }
219             if (beanPermissions != null)
220             {
221                addToRole(pc, permission, beanPermissions);
222                continue;
223             }
224
225             //The default is unchecked
226
pc.addToUncheckedPolicy(permission);
227             log.debug("Adding permission to unchecked policy");
228          }
229          catch (PolicyContextException JavaDoc e)
230          {
231             throw new RuntimeException JavaDoc(e); // TODO Auto-generated catch block
232
}
233       }
234    }
235
236    private static int getAnnotationCount(PermitAll u, RolesAllowed mp, DenyAll e)
237    {
238       int annotations = 0;
239       if (u != null) annotations++;
240       if (mp != null) annotations++;
241       if (e != null) annotations++;
242
243       return annotations;
244    }
245
246    private static void addToRole(PolicyConfiguration JavaDoc pc, EJBMethodPermission JavaDoc p, RolesAllowed mp) throws PolicyContextException JavaDoc
247    {
248       String JavaDoc[] roles = mp.value();
249       for (int i = 0; i < roles.length; i++)
250       {
251          pc.addToRole(roles[i], p);
252          log.debug("Adding permission to role: " + roles[i]);
253       }
254    }
255
256    private static void addJaccContextToContainer(String JavaDoc jaccContextId, EJBContainer container)
257    {
258       SimpleClassMetaDataLoader loader = SimpleClassMetaDataLoader.singleton;
259       String JavaDoc name = container.getBeanClassName();
260       SimpleClassMetaDataBinding jaccCtx =
261               new SimpleClassMetaDataBinding(loader, name, JaccAuthorizationInterceptor.JACC, container.getBeanClassName());
262
263       jaccCtx.addDefaultMetaData(JaccAuthorizationInterceptor.JACC,
264                                  JaccAuthorizationInterceptor.CTX, jaccContextId);
265
266       container.addClassMetaData(jaccCtx);
267    }
268
269    public static void checkPermission(CodeSource JavaDoc ejbCS, EJBMethodPermission JavaDoc methodPerm) throws SecurityException JavaDoc
270    {
271       try
272       {
273          Policy JavaDoc policy = Policy.getPolicy();
274          // Get the caller
275
Subject JavaDoc caller = SecurityActions.getContextSubject();
276
277          Principal JavaDoc[] principals = null;
278          if (caller != null)
279          {
280             // Get the caller principals
281
Set JavaDoc principalsSet = caller.getPrincipals();
282             principals = new Principal JavaDoc[principalsSet.size()];
283             principalsSet.toArray(principals);
284          }
285
286          ProtectionDomain JavaDoc pd = new ProtectionDomain JavaDoc(ejbCS, null, null, principals);
287          if (policy.implies(pd, methodPerm) == false)
288          {
289             String JavaDoc msg = "Denied: " + methodPerm + ", caller=" + caller;
290             SecurityException JavaDoc e = new SecurityException JavaDoc(msg);
291             throw e;
292          }
293       }
294       catch (PolicyContextException JavaDoc e)
295       {
296          throw new RuntimeException JavaDoc(e);
297       }
298    }
299 }
300
Popular Tags