1 22 package org.jboss.aspects.security; 23 24 import javassist.CtConstructor; 25 import javassist.CtField; 26 import javassist.CtMethod; 27 import javassist.NotFoundException; 28 import org.jboss.aop.Advisor; 29 import org.jboss.aop.metadata.ClassMetaDataBinding; 30 import org.jboss.aop.util.PayloadKey; 31 import org.jboss.aop.util.XmlHelper; 32 import org.jboss.security.AnybodyPrincipal; 33 import org.jboss.security.NobodyPrincipal; 34 import org.jboss.security.SimplePrincipal; 35 import org.w3c.dom.Element ; 36 37 import javax.naming.InitialContext ; 38 39 import java.lang.reflect.Constructor ; 40 import java.lang.reflect.Field ; 41 import java.lang.reflect.Method ; 42 import java.util.ArrayList ; 43 import java.util.HashMap ; 44 import java.util.HashSet ; 45 import java.util.Iterator ; 46 import java.util.Set ; 47 48 55 public class SecurityClassMetaDataLoader implements org.jboss.aop.metadata.ClassMetaDataLoader 56 { 57 public org.jboss.aop.metadata.ClassMetaDataBinding importMetaData(Element element, String name, String group, String classExpr) throws Exception 58 { 59 SecurityClassMetaDataBinding data = new SecurityClassMetaDataBinding(this, name, group, classExpr); 60 ArrayList securityRoles = loadSecurityRoles(element); 61 ArrayList methodPermissions = loadMethodPermissions(element); 62 ArrayList methodExcludeList = loadMethodExcludeList(element); 63 HashMap fieldPermissions = loadFieldPermissions(element); 64 ArrayList fieldExcludeList = loadFieldExcludeList(element); 65 ArrayList constructorPermissions = loadConstructorPermissions(element); 66 ArrayList constructorExcludeList = loadConstructorExcludeList(element); 67 String runAs = loadRunAs(element); 68 69 String securityDomain = XmlHelper.getOptionalChildContent(element, "security-domain"); 70 if (securityDomain == null) throw new RuntimeException ("you must define a security-domain"); 71 data.setSecurityDomain(securityDomain); 72 data.setSecurityRoles(securityRoles); 73 data.setMethodPermissions(methodPermissions); 74 data.setMethodExcludeList(methodExcludeList); 75 data.setFieldPermissions(fieldPermissions); 76 data.setFieldExcludeList(fieldExcludeList); 77 data.setConstructorPermissions(constructorPermissions); 78 data.setConstructorExcludeList(constructorExcludeList); 79 data.setRunAs(runAs); 80 return data; 81 } 82 83 public void bind(Advisor advisor, org.jboss.aop.metadata.ClassMetaDataBinding data, Method[] methods, Field[] fields, Constructor[] constructors) throws Exception 84 { 85 SecurityClassMetaDataBinding meta = (SecurityClassMetaDataBinding) data; 86 try 87 { 88 String securityDomain = "java:/jaas/" + meta.getSecurityDomain(); 89 Object domain = new InitialContext ().lookup(securityDomain); 90 advisor.getDefaultMetaData().addMetaData("security", "authentication-manager", domain, PayloadKey.TRANSIENT); 91 advisor.getDefaultMetaData().addMetaData("security", "realm-mapping", domain, PayloadKey.TRANSIENT); 92 } 93 catch (Exception ex) 94 { 95 throw new RuntimeException ("failed to load security domain: " + meta.getSecurityDomain(), ex); 96 } 97 98 for (int i = 0; i < methods.length; i++) 99 { 100 Set permissions = getMethodPermissions(methods[i], meta); 101 if (permissions != null) 102 { 103 advisor.getMethodMetaData().addMethodMetaData(methods[i], "security", "roles", permissions, PayloadKey.TRANSIENT); 104 } 105 } 106 107 for (int i = 0; i < fields.length; i++) 108 { 109 Set permissions = getFieldPermissions(fields[i], meta); 110 if (permissions != null) 111 { 112 advisor.getFieldMetaData().addFieldMetaData(fields[i], "security", "roles", permissions, PayloadKey.TRANSIENT); 113 } 114 } 115 116 for (int i = 0; i < constructors.length; i++) 117 { 118 Set permissions = getConstructorPermissions(constructors[i], meta); 119 if (permissions != null) 120 { 121 advisor.getConstructorMetaData().addConstructorMetaData(constructors[i], "security", "roles", permissions, PayloadKey.TRANSIENT); 122 } 123 } 124 125 if (meta.getRunAs() != null) 126 { 127 advisor.getDefaultMetaData().addMetaData("security", "run-as", new SimplePrincipal(meta.getRunAs()), PayloadKey.TRANSIENT); 128 } 129 } 130 131 public Set getMethodPermissions(Method method, SecurityClassMetaDataBinding meta) 132 { 133 Set result = new HashSet (); 134 Iterator iterator = meta.getMethodExcludeList().iterator(); 137 while (iterator.hasNext()) 138 { 139 SecurityMethodConfig m = (SecurityMethodConfig) iterator.next(); 140 if (m.patternMatches(method)) 141 { 142 147 result.add(NobodyPrincipal.NOBODY_PRINCIPAL); 148 return result; 149 } 150 } 151 152 iterator = meta.getMethodPermissions().iterator(); 154 while (iterator.hasNext()) 155 { 156 SecurityMethodConfig m = (SecurityMethodConfig) iterator.next(); 157 if (m.patternMatches(method)) 158 { 159 if (m.isUnchecked()) 163 { 164 result.clear(); 165 result.add(AnybodyPrincipal.ANYBODY_PRINCIPAL); 166 break; 167 } 168 else 170 { 171 Iterator rolesIterator = m.getRoles().iterator(); 172 while (rolesIterator.hasNext()) 173 { 174 String roleName = (String ) rolesIterator.next(); 175 result.add(new SimplePrincipal(roleName)); 176 } 177 } 178 } 179 } 180 181 if (result.isEmpty()) 184 { 185 result = null; 186 } 187 188 return result; 189 } 190 191 192 public Set getFieldPermissions(Field field, SecurityClassMetaDataBinding meta) 193 { 194 String fieldName = field.getName(); 195 Set result = new HashSet (); 196 Iterator iterator = meta.getFieldExcludeList().iterator(); 199 while (iterator.hasNext()) 200 { 201 String expr = (String ) iterator.next(); 202 if (expr.equals("*") || expr.equals(fieldName)) 203 { 204 209 result.add(NobodyPrincipal.NOBODY_PRINCIPAL); 210 return result; 211 } 212 } 213 214 iterator = meta.getFieldPermissions().keySet().iterator(); 216 while (iterator.hasNext()) 217 { 218 String expr = (String ) iterator.next(); 219 220 if (expr.equals("*") || expr.equals(fieldName)) 221 { 222 Object permission = meta.getFieldPermissions().get(expr); 223 if (permission instanceof Boolean ) 227 { 228 result.clear(); 229 result.add(AnybodyPrincipal.ANYBODY_PRINCIPAL); 230 break; 231 } 232 else 234 { 235 Set roles = (Set ) permission; 236 Iterator rolesIterator = roles.iterator(); 237 while (rolesIterator.hasNext()) 238 { 239 String roleName = (String ) rolesIterator.next(); 240 result.add(new SimplePrincipal(roleName)); 241 } 242 } 243 } 244 } 245 246 if (result.isEmpty()) 249 { 250 result = null; 251 } 252 253 return result; 254 } 255 256 257 protected String loadRunAs(Element element) 258 throws Exception 259 { 260 Element securityIdentityElement = XmlHelper.getOptionalChild(element, 261 "security-identity"); 262 if (securityIdentityElement == null) return null; 263 Element callerIdent = XmlHelper.getOptionalChild(securityIdentityElement, "use-caller-identity"); 264 Element runAs = XmlHelper.getOptionalChild(securityIdentityElement, "run-as"); 265 if (callerIdent == null && runAs == null) 266 throw new RuntimeException ("security-identity: either use-caller-identity or run-as must be specified"); 267 if (callerIdent != null && runAs != null) 268 throw new RuntimeException ("security-identity: only one of use-caller-identity or run-as can be specified"); 269 270 String runAsRoleName = null; 271 if (runAs != null) 272 { 273 runAsRoleName = XmlHelper.getElementContent(XmlHelper.getUniqueChild(runAs, "role-name")); 274 } 275 return runAsRoleName; 276 } 277 278 279 protected ArrayList loadSecurityRoles(Element assemblyDescriptor) throws Exception 280 { 281 ArrayList securityRoles = new ArrayList (); 282 Iterator iterator = XmlHelper.getChildrenByTagName(assemblyDescriptor, "security-role"); 284 while (iterator.hasNext()) 285 { 286 Element securityRole = (Element ) iterator.next(); 287 try 288 { 289 String role = XmlHelper.getUniqueChildContent(securityRole, "role-name"); 290 securityRoles.add(role); 291 } 292 catch (Exception e) 293 { 294 throw new RuntimeException ("Error in metadata " + 295 "for security-role: ", e); 296 } 297 } 298 return securityRoles; 299 } 300 301 protected ArrayList loadMethodPermissions(Element assemblyDescriptor) throws Exception 302 { 303 ArrayList permissionMethods = new ArrayList (); 304 Iterator iterator = XmlHelper.getChildrenByTagName(assemblyDescriptor, 306 "method-permission"); 307 while (iterator.hasNext()) 308 { 309 Element methodPermission = (Element ) iterator.next(); 310 Element unchecked = XmlHelper.getOptionalChild(methodPermission, 312 "unchecked"); 313 314 boolean isUnchecked = false; 315 Set roles = null; 316 if (unchecked != null) 317 { 318 isUnchecked = true; 319 } 320 else 321 { 322 roles = new HashSet (); 324 Iterator rolesIterator = XmlHelper.getChildrenByTagName(methodPermission, "role-name"); 325 while (rolesIterator.hasNext()) 326 { 327 roles.add(XmlHelper.getElementContent((Element ) rolesIterator.next())); 328 } 329 if (roles.size() == 0) 330 throw new RuntimeException ("An unchecked " + 331 "element in security metadata or one or more role-name elements " + 332 "must be specified in method-permission"); 333 } 334 335 Iterator methods = XmlHelper.getChildrenByTagName(methodPermission, 337 "method"); 338 while (methods.hasNext()) 339 { 340 SecurityMethodConfig method = new SecurityMethodConfig(); 342 method.importXml((Element ) methods.next()); 343 if (isUnchecked) 344 { 345 method.setUnchecked(); 346 permissionMethods.add(0, method); 347 } 348 else 349 { 350 method.setRoles(roles); 351 permissionMethods.add(method); 352 } 353 } 354 } 355 return permissionMethods; 356 } 357 358 protected ArrayList loadMethodExcludeList(Element assemblyDescriptor) throws Exception 359 { 360 ArrayList excluded = new ArrayList (); 361 Element excludeList = XmlHelper.getOptionalChild(assemblyDescriptor, 363 "exclude-list"); 364 if (excludeList != null) 365 { 366 Iterator iterator = XmlHelper.getChildrenByTagName(excludeList, "method"); 367 while (iterator.hasNext()) 368 { 369 Element methodInf = (Element ) iterator.next(); 370 SecurityMethodConfig method = new SecurityMethodConfig(); 372 method.importXml(methodInf); 373 method.setExcluded(); 374 excluded.add(method); 375 } 376 } 377 return excluded; 378 } 379 380 protected HashMap loadFieldPermissions(Element assemblyDescriptor) throws Exception 381 { 382 HashMap permissionFields = new HashMap (); 383 Iterator iterator = XmlHelper.getChildrenByTagName(assemblyDescriptor, 385 "field-permission"); 386 while (iterator.hasNext()) 387 { 388 Element fieldPermission = (Element ) iterator.next(); 389 Element unchecked = XmlHelper.getOptionalChild(fieldPermission, 391 "unchecked"); 392 393 boolean isUnchecked = false; 394 Set roles = null; 395 if (unchecked != null) 396 { 397 isUnchecked = true; 398 } 399 else 400 { 401 roles = new HashSet (); 403 Iterator rolesIterator = XmlHelper.getChildrenByTagName(fieldPermission, "role-name"); 404 while (rolesIterator.hasNext()) 405 { 406 roles.add(XmlHelper.getElementContent((Element ) rolesIterator.next())); 407 } 408 if (roles.size() == 0) 409 throw new RuntimeException ("An unchecked " + 410 "element in security metadata or one or more role-name elements " + 411 "must be specified in field-permission"); 412 } 413 414 Iterator fields = XmlHelper.getChildrenByTagName(fieldPermission, 416 "field"); 417 while (fields.hasNext()) 418 { 419 Element field = (Element ) fields.next(); 421 String fieldName = XmlHelper.getElementContent(XmlHelper.getUniqueChild(field, "field-name")); 422 423 if (isUnchecked) 424 { 425 permissionFields.put(fieldName, Boolean.TRUE); } 427 else 428 { 429 430 Object permission = permissionFields.get(fieldName); 431 if (permission != null && permission instanceof Boolean ) { 433 continue; 434 } 435 if (permission != null) 436 { 437 Set curr = (Set ) permission; 438 curr.addAll(roles); 439 } 440 else 441 { 442 permissionFields.put(fieldName, new HashSet (roles)); 443 } 444 } 445 } 446 } 447 return permissionFields; 448 } 449 450 protected ArrayList loadFieldExcludeList(Element assemblyDescriptor) throws Exception 451 { 452 ArrayList excluded = new ArrayList (); 453 Element excludeList = XmlHelper.getOptionalChild(assemblyDescriptor, 455 "exclude-list"); 456 if (excludeList != null) 457 { 458 Iterator iterator = XmlHelper.getChildrenByTagName(excludeList, "field"); 459 while (iterator.hasNext()) 460 { 461 Element fieldInf = (Element ) iterator.next(); 462 String fieldName = XmlHelper.getElementContent(XmlHelper.getUniqueChild(fieldInf, "field-name")); 463 excluded.add(fieldName); 464 } 465 } 466 return excluded; 467 } 468 469 protected ArrayList loadConstructorPermissions(Element assemblyDescriptor) throws Exception 470 { 471 ArrayList permissionConstructors = new ArrayList (); 472 Iterator iterator = XmlHelper.getChildrenByTagName(assemblyDescriptor, 474 "constructor-permission"); 475 while (iterator.hasNext()) 476 { 477 Element constructorPermission = (Element ) iterator.next(); 478 Element unchecked = XmlHelper.getOptionalChild(constructorPermission, 480 "unchecked"); 481 482 boolean isUnchecked = false; 483 Set roles = null; 484 if (unchecked != null) 485 { 486 isUnchecked = true; 487 } 488 else 489 { 490 roles = new HashSet (); 492 Iterator rolesIterator = XmlHelper.getChildrenByTagName(constructorPermission, "role-name"); 493 while (rolesIterator.hasNext()) 494 { 495 roles.add(XmlHelper.getElementContent((Element ) rolesIterator.next())); 496 } 497 if (roles.size() == 0) 498 throw new RuntimeException ("An unchecked " + 499 "element in security metadata or one or more role-name elements " + 500 "must be specified in constructor-permission"); 501 } 502 503 Iterator constructors = XmlHelper.getChildrenByTagName(constructorPermission, 505 "constructor"); 506 while (constructors.hasNext()) 507 { 508 SecurityConstructorConfig constructor = new SecurityConstructorConfig(); 510 constructor.importXml((Element ) constructors.next()); 511 if (isUnchecked) 512 { 513 constructor.setUnchecked(); 514 permissionConstructors.add(0, constructor); 515 } 516 else 517 { 518 constructor.setRoles(roles); 519 permissionConstructors.add(constructor); 520 } 521 } 522 } 523 return permissionConstructors; 524 } 525 526 protected ArrayList loadConstructorExcludeList(Element assemblyDescriptor) throws Exception 527 { 528 ArrayList excluded = new ArrayList (); 529 Element excludeList = XmlHelper.getOptionalChild(assemblyDescriptor, 531 "exclude-list"); 532 if (excludeList != null) 533 { 534 Iterator iterator = XmlHelper.getChildrenByTagName(excludeList, "constructor"); 535 while (iterator.hasNext()) 536 { 537 Element constructorInf = (Element ) iterator.next(); 538 SecurityConstructorConfig constructor = new SecurityConstructorConfig(); 540 constructor.importXml(constructorInf); 541 constructor.setExcluded(); 542 excluded.add(constructor); 543 } 544 } 545 return excluded; 546 } 547 548 public Set getConstructorPermissions(Constructor constructor, SecurityClassMetaDataBinding meta) 549 { 550 Set result = new HashSet (); 551 Iterator iterator = meta.getConstructorExcludeList().iterator(); 554 while (iterator.hasNext()) 555 { 556 SecurityConstructorConfig m = (SecurityConstructorConfig) iterator.next(); 557 if (m.patternMatches(constructor)) 558 { 559 564 result.add(NobodyPrincipal.NOBODY_PRINCIPAL); 565 return result; 566 } 567 } 568 569 iterator = meta.getConstructorPermissions().iterator(); 571 while (iterator.hasNext()) 572 { 573 SecurityConstructorConfig m = (SecurityConstructorConfig) iterator.next(); 574 if (m.patternMatches(constructor)) 575 { 576 if (m.isUnchecked()) 580 { 581 result.clear(); 582 result.add(AnybodyPrincipal.ANYBODY_PRINCIPAL); 583 break; 584 } 585 else 587 { 588 Iterator rolesIterator = m.getRoles().iterator(); 589 while (rolesIterator.hasNext()) 590 { 591 String roleName = (String ) rolesIterator.next(); 592 result.add(new SimplePrincipal(roleName)); 593 } 594 } 595 } 596 } 597 598 if (result.isEmpty()) 601 { 602 result = null; 603 } 604 605 return result; 606 } 607 608 609 620 public void bind(Advisor advisor, ClassMetaDataBinding data, CtMethod[] methods, CtField[] fields, CtConstructor[] constructors) throws Exception 621 { 622 SecurityClassMetaDataBinding meta = (SecurityClassMetaDataBinding) data; 623 for (int i = 0; i < methods.length; i++) 624 { 625 boolean permissions = getMethodPermissions(methods[i], meta); 626 if (permissions) 627 { 628 advisor.getMethodMetaData().addMethodMetaData(methods[i], "security", "roles", Boolean.TRUE, PayloadKey.TRANSIENT); 629 } 630 } 631 632 for (int i = 0; i < fields.length; i++) 633 { 634 boolean permissions = getFieldPermissions(fields[i], meta); 635 if (permissions) 636 { 637 advisor.getFieldMetaData().addFieldMetaData(fields[i].getName(), "security", "roles", Boolean.TRUE, PayloadKey.TRANSIENT); 638 } 639 } 640 641 for (int i = 0; i < constructors.length; i++) 642 { 643 boolean permissions = getConstructorPermissions(constructors[i], meta); 644 if (permissions) 645 { 646 advisor.getConstructorMetaData().addConstructorMetaData(constructors[i].getMethodInfo2().getDescriptor(), "security", "roles", Boolean.TRUE, PayloadKey.TRANSIENT); 648 } 649 } 650 } 651 652 660 public boolean getMethodPermissions(CtMethod method, SecurityClassMetaDataBinding meta) throws Exception 661 { 662 Iterator iterator = meta.getMethodExcludeList().iterator(); 665 while (iterator.hasNext()) 666 { 667 SecurityMethodConfig m = (SecurityMethodConfig) iterator.next(); 668 if (m.patternMatches(method)) 669 { 670 return true; 671 } 672 } 673 674 iterator = meta.getMethodPermissions().iterator(); 676 while (iterator.hasNext()) 677 { 678 SecurityMethodConfig m = (SecurityMethodConfig) iterator.next(); 679 if (m.patternMatches(method)) 680 { 681 return true; 682 } 683 } 684 685 return false; 686 } 687 688 689 public boolean getFieldPermissions(CtField field, SecurityClassMetaDataBinding meta) 690 { 691 String fieldName = field.getName(); 692 Iterator iterator = meta.getFieldExcludeList().iterator(); 695 while (iterator.hasNext()) 696 { 697 String expr = (String ) iterator.next(); 698 if (expr.equals("*") || expr.equals(fieldName)) 699 { 700 return true; 701 } 702 } 703 704 iterator = meta.getFieldPermissions().keySet().iterator(); 706 while (iterator.hasNext()) 707 { 708 String expr = (String ) iterator.next(); 709 710 if (expr.equals("*") || expr.equals(fieldName)) 711 { 712 return true; 713 } 714 } 715 716 return false; 717 } 718 719 720 public boolean getConstructorPermissions(CtConstructor constructor, SecurityClassMetaDataBinding meta) throws NotFoundException 721 { 722 Iterator iterator = meta.getConstructorExcludeList().iterator(); 725 while (iterator.hasNext()) 726 { 727 SecurityConstructorConfig m = (SecurityConstructorConfig) iterator.next(); 728 if (m.patternMatches(constructor)) 729 { 730 return true; 731 } 732 } 733 734 iterator = meta.getConstructorPermissions().iterator(); 736 while (iterator.hasNext()) 737 { 738 SecurityConstructorConfig m = (SecurityConstructorConfig) iterator.next(); 739 if (m.patternMatches(constructor)) 740 { 741 return true; 742 } 743 } 744 745 return false; 746 } 747 748 749 } 750 | Popular Tags |