1 22 23 package org.jboss.ejb3.security; 24 25 import java.lang.reflect.Method ; 26 import java.lang.reflect.Modifier ; 27 import java.security.CodeSource ; 28 import java.security.Policy ; 29 import java.security.Principal ; 30 import java.security.ProtectionDomain ; 31 import java.util.Set ; 32 import javax.annotation.security.DenyAll; 33 import javax.annotation.security.PermitAll; 34 import javax.annotation.security.RolesAllowed; 35 import javax.security.auth.Subject ; 36 import javax.security.jacc.EJBMethodPermission ; 37 import javax.security.jacc.PolicyConfiguration ; 38 import javax.security.jacc.PolicyConfigurationFactory ; 39 import javax.security.jacc.PolicyContextException ; 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 52 public class JaccHelper 53 { 54 static Logger log = Logger.getLogger(JaccHelper.class); 55 56 60 public static PolicyConfiguration initialiseJacc(String contextID) throws Exception 61 { 62 log.debug("Initialising JACC Context for deployment: " + contextID); 63 PolicyConfigurationFactory pcFactory = Ejb3PolicyConfigurationFactory.getPolicyConfigurationFactory(); 64 boolean removeExistingContext = true; 65 PolicyConfiguration pc = pcFactory.getPolicyConfiguration(contextID, removeExistingContext); 66 67 75 79 87 return pc; 88 } 89 90 public static void putJaccInService(PolicyConfiguration pc, DeploymentUnit di) throws Exception 91 { 92 93 } 94 public static void putJaccInService(PolicyConfiguration pc, DeploymentInfo di) throws Exception 95 { 96 di.context.put("javax.security.jacc.PolicyConfiguration", pc); 97 98 DeploymentInfo current = di; 100 while (current.parent != null) 101 { 102 current = current.parent; 103 } 104 105 PolicyConfiguration parentPC = (PolicyConfiguration ) 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 contextID) throws Exception 118 { 119 PolicyConfigurationFactory pcFactory = Ejb3PolicyConfigurationFactory.getPolicyConfigurationFactory(); 120 PolicyConfiguration pc = pcFactory.getPolicyConfiguration(contextID, true); 121 pc.delete(); 122 } 123 124 125 public static void configureContainer(String jaccContextId, EJBContainer container) 126 { 127 try 128 { 129 addJaccContextToContainer(jaccContextId, container); 130 PolicyConfigurationFactory pcFactory = Ejb3PolicyConfigurationFactory.getPolicyConfigurationFactory(); 131 PolicyConfiguration pc = pcFactory.getPolicyConfiguration(jaccContextId, false); 132 133 addPermissions(container, pc); 134 } 135 catch (Exception e) 136 { 137 e.printStackTrace(); 138 throw new RuntimeException (e); 139 } 140 } 141 142 private static void addPermissions(EJBContainer container, PolicyConfiguration 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 ("Cannot annotate a bean with both @Unchecked and @MethodPermissions"); 159 } 160 161 String ejbName = container.getEjbName(); 162 163 Method [] methods = container.getBeanClass().getDeclaredMethods(); 166 for (int i = 0; i < methods.length; i++) 167 { 168 Method m = methods[i]; 169 if (!Modifier.isPublic(m.getModifiers())) 170 { 171 continue; 172 } 173 174 EJBMethodPermission permission = new EJBMethodPermission (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 ("You can only use one of @PermitAll, @DenyAll or @RolesAllowed per method"); 190 } 191 192 try 193 { 194 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 pc.addToUncheckedPolicy(permission); 227 log.debug("Adding permission to unchecked policy"); 228 } 229 catch (PolicyContextException e) 230 { 231 throw new RuntimeException (e); } 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 pc, EJBMethodPermission p, RolesAllowed mp) throws PolicyContextException 247 { 248 String [] 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 jaccContextId, EJBContainer container) 257 { 258 SimpleClassMetaDataLoader loader = SimpleClassMetaDataLoader.singleton; 259 String 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 ejbCS, EJBMethodPermission methodPerm) throws SecurityException 270 { 271 try 272 { 273 Policy policy = Policy.getPolicy(); 274 Subject caller = SecurityActions.getContextSubject(); 276 277 Principal [] principals = null; 278 if (caller != null) 279 { 280 Set principalsSet = caller.getPrincipals(); 282 principals = new Principal [principalsSet.size()]; 283 principalsSet.toArray(principals); 284 } 285 286 ProtectionDomain pd = new ProtectionDomain (ejbCS, null, null, principals); 287 if (policy.implies(pd, methodPerm) == false) 288 { 289 String msg = "Denied: " + methodPerm + ", caller=" + caller; 290 SecurityException e = new SecurityException (msg); 291 throw e; 292 } 293 } 294 catch (PolicyContextException e) 295 { 296 throw new RuntimeException (e); 297 } 298 } 299 } 300 | Popular Tags |