1 22 package org.jboss.web; 23 24 import java.util.Iterator ; 25 import java.util.HashMap ; 26 import java.util.HashSet ; 27 import java.util.Arrays ; 28 import java.util.Map ; 29 import java.util.Set ; 30 import java.util.ArrayList ; 31 import java.util.Collection ; 32 import javax.security.jacc.PolicyConfiguration ; 33 import javax.security.jacc.PolicyContextException ; 34 import javax.security.jacc.WebResourcePermission ; 35 import javax.security.jacc.WebUserDataPermission ; 36 import javax.security.jacc.WebRoleRefPermission ; 37 38 import org.jboss.metadata.WebMetaData; 39 import org.jboss.metadata.WebSecurityMetaData; 40 import org.jboss.metadata.SecurityRoleRefMetaData; 41 import org.jboss.logging.Logger; 42 43 45 52 public class WebPermissionMapping 53 { 54 static Logger log = Logger.getLogger(WebPermissionMapping.class); 55 56 57 private static final int PREFIX = 1; 58 59 private static final int EXTENSION = 2; 60 61 private static final int DEFAULT = 3; 62 63 private static final int EXACT = 4; 64 65 73 public static void createPermissions(WebMetaData metaData, PolicyConfiguration pc) 74 throws PolicyContextException 75 { 76 HashMap patternMap = qualifyURLPatterns(metaData); 77 log.debug("Qualified url patterns: "+patternMap); 78 79 Iterator constraints = metaData.getSecurityContraints(); 80 while( constraints.hasNext() ) 81 { 82 WebSecurityMetaData wsmd = (WebSecurityMetaData) constraints.next(); 83 String transport = wsmd.getTransportGuarantee(); 84 if( wsmd.isExcluded() || wsmd.isUnchecked() ) 85 { 86 Iterator resources = wsmd.getWebResources().values().iterator(); 88 while( resources.hasNext() ) 89 { 90 WebSecurityMetaData.WebResourceCollection wrc = (WebSecurityMetaData.WebResourceCollection) resources.next(); 91 String [] httpMethods = wrc.getHttpMethods(); 92 String [] urlPatterns = wrc.getUrlPatterns(); 93 for(int n = 0; n < urlPatterns.length; n ++) 94 { 95 String url = urlPatterns[n]; 96 PatternInfo info = (PatternInfo) patternMap.get(url); 97 if( wsmd.isExcluded() ) 99 { 100 info.addExcludedMethods(httpMethods); 101 } 102 } 103 } 104 } 105 else 106 { 107 Iterator resources = wsmd.getWebResources().values().iterator(); 109 while( resources.hasNext() ) 110 { 111 WebSecurityMetaData.WebResourceCollection wrc = (WebSecurityMetaData.WebResourceCollection) resources.next(); 112 String [] httpMethods = wrc.getHttpMethods(); 113 String [] urlPatterns = wrc.getUrlPatterns(); 114 for(int n = 0; n < urlPatterns.length; n ++) 115 { 116 String url = urlPatterns[n]; 117 PatternInfo info = (PatternInfo) patternMap.get(url); 119 Iterator roles = wsmd.getRoles().iterator(); 120 HashSet mappedRoles = new HashSet (); 121 while( roles.hasNext() ) 122 { 123 String role = (String ) roles.next(); 124 if( role.equals("*") ) 125 { 126 Iterator allRoles = metaData.getSecurityRoleNames().iterator(); 128 while( allRoles.hasNext() ) 129 { 130 role = (String ) allRoles.next(); 131 mappedRoles.add(role); 132 } 133 } 134 else 135 { 136 mappedRoles.add(role); 137 } 138 } 139 info.addRoles(mappedRoles, httpMethods); 140 info.addTransport(transport, httpMethods); 142 } 143 } 144 } 145 } 146 147 Iterator iter = patternMap.values().iterator(); 149 while( iter.hasNext() ) 150 { 151 PatternInfo info = (PatternInfo) iter.next(); 152 String qurl = info.getQualifiedPattern(); 153 if( info.isOverriden == true ) 154 { 155 log.debug("Dropping overriden pattern: "+info); 156 continue; 157 } 158 159 String [] httpMethods = info.getExcludedMethods(); 161 if( httpMethods != null ) 162 { 163 WebResourcePermission wrp = new WebResourcePermission (qurl, httpMethods); 165 WebUserDataPermission wudp = new WebUserDataPermission (qurl, 166 httpMethods, null); 167 pc.addToExcludedPolicy(wrp); 168 pc.addToExcludedPolicy(wudp); 169 } 170 171 Iterator roles = info.getRoleMethods(); 173 while( roles.hasNext() ) 174 { 175 Map.Entry roleMethods = (Map.Entry ) roles.next(); 176 String role = (String ) roleMethods.getKey(); 177 HashSet methods = (HashSet ) roleMethods.getValue(); 178 httpMethods = new String [methods.size()]; 179 methods.toArray(httpMethods); 180 WebResourcePermission wrp = new WebResourcePermission (qurl, httpMethods); 181 pc.addToRole(role, wrp); 182 } 183 184 String [] missingHttpMethods = info.getMissingMethods(); 186 if( missingHttpMethods.length > 0 ) 187 { 188 WebResourcePermission wrp = new WebResourcePermission (qurl, missingHttpMethods); 190 pc.addToUncheckedPolicy(wrp); 191 192 } 193 194 Iterator transportContraints = info.getTransportMethods(); 196 while( transportContraints.hasNext() ) 197 { 198 Map.Entry transportMethods = (Map.Entry ) transportContraints.next(); 199 String transport = (String ) transportMethods.getKey(); 200 Set methods = (Set ) transportMethods.getValue(); 201 httpMethods = new String [methods.size()]; 202 methods.toArray(httpMethods); 203 WebUserDataPermission wudp = new WebUserDataPermission (qurl, httpMethods, transport); 204 pc.addToUncheckedPolicy(wudp); 205 } 206 } 207 208 213 Set unreferencedRoles = metaData.getSecurityRoleNames(); 214 Map servletRoleRefs = metaData.getSecurityRoleRefs(); 215 Iterator roleRefsIter = servletRoleRefs.keySet().iterator(); 216 while( roleRefsIter.hasNext() ) 217 { 218 String servletName = (String ) roleRefsIter.next(); 219 ArrayList roleRefs = (ArrayList ) servletRoleRefs.get(servletName); 220 for(int n = 0; n < roleRefs.size(); n ++) 221 { 222 SecurityRoleRefMetaData roleRef = (SecurityRoleRefMetaData) roleRefs.get(n); 223 String roleName = roleRef.getLink(); 224 WebRoleRefPermission wrrp = new WebRoleRefPermission (servletName, roleRef.getName()); 225 pc.addToRole(roleName, wrrp); 226 230 wrrp = new WebRoleRefPermission (servletName, roleName); 231 pc.addToRole(roleRef.getName(), wrrp); 232 unreferencedRoles.remove(roleName); 234 } 235 } 236 237 Set servletNames = metaData.getServletNames(); 239 Iterator names = servletNames.iterator(); 240 while( names.hasNext() ) 241 { 242 String servletName = (String ) names.next(); 243 Iterator roles = unreferencedRoles.iterator(); 244 while( roles.hasNext() ) 245 { 246 String role = (String ) roles.next(); 247 WebRoleRefPermission wrrp = new WebRoleRefPermission (servletName, role); 248 pc.addToRole(role, wrrp); 249 } 250 } 251 255 Iterator roles = unreferencedRoles.iterator(); 256 while( roles.hasNext() ) 257 { 258 String role = (String ) roles.next(); 259 WebRoleRefPermission wrrp = new WebRoleRefPermission ("", role); 260 pc.addToRole(role, wrrp); 261 } 262 } 263 264 269 static int getPatternType(String urlPattern) 270 { 271 int type = EXACT; 272 if( urlPattern.startsWith("*.") ) 273 type = EXTENSION; 274 else if( urlPattern.startsWith("/") && urlPattern.endsWith("/*") ) 275 type = PREFIX; 276 else if( urlPattern.equals("/") ) 277 type = DEFAULT; 278 return type; 279 } 280 281 318 static HashMap qualifyURLPatterns(WebMetaData metaData) 319 { 320 ArrayList prefixList = new ArrayList (); 321 ArrayList extensionList = new ArrayList (); 322 ArrayList exactList = new ArrayList (); 323 HashMap patternMap = new HashMap (); 324 PatternInfo defaultInfo = null; 325 326 Iterator constraints = metaData.getSecurityContraints(); 327 while( constraints.hasNext() ) 328 { 329 WebSecurityMetaData wsmd = (WebSecurityMetaData) constraints.next(); 330 Iterator resources = wsmd.getWebResources().values().iterator(); 331 while( resources.hasNext() ) 332 { 333 WebSecurityMetaData.WebResourceCollection wrc = (WebSecurityMetaData.WebResourceCollection) resources.next(); 334 String [] urlPatterns = wrc.getUrlPatterns(); 335 for(int n = 0; n < urlPatterns.length; n ++) 336 { 337 String url = urlPatterns[n]; 338 int type = getPatternType(url); 339 PatternInfo info = (PatternInfo) patternMap.get(url); 340 if( info == null ) 341 { 342 info = new PatternInfo(url, type); 343 patternMap.put(url, info); 344 switch( type ) 345 { 346 case PREFIX: 347 prefixList.add(info); 348 break; 349 case EXTENSION: 350 extensionList.add(info); 351 break; 352 case EXACT: 353 exactList.add(info); 354 break; 355 case DEFAULT: 356 defaultInfo = info; 357 break; 358 } 359 } 360 } 361 } 362 } 363 364 for(int i = 0; i < prefixList.size(); i ++) 366 { 367 PatternInfo info = (PatternInfo) prefixList.get(i); 368 for(int j = 0; j < prefixList.size(); j ++) 370 { 371 if( i == j ) 372 continue; 373 PatternInfo other = (PatternInfo) prefixList.get(j); 374 if( info.matches(other) ) 375 info.addQualifier(other); 376 } 377 for(int j = 0; j < exactList.size(); j ++) 379 { 380 PatternInfo other = (PatternInfo) exactList.get(j); 381 if( info.matches(other) ) 382 info.addQualifier(other); 383 } 384 } 385 386 for(int i = 0; i < extensionList.size(); i ++) 388 { 389 PatternInfo info = (PatternInfo) extensionList.get(i); 390 for(int j = 0; j < prefixList.size(); j ++) 392 { 393 PatternInfo other = (PatternInfo) prefixList.get(j); 394 { 395 info.addQualifier(other); 397 } 398 } 399 for(int j = 0; j < exactList.size(); j ++) 401 { 402 PatternInfo other = (PatternInfo) exactList.get(j); 403 if( info.isExtensionFor(other) ) 404 info.addQualifier(other); 405 } 406 } 407 408 if( defaultInfo == null ) 410 { 411 defaultInfo = new PatternInfo("/", DEFAULT); 412 patternMap.put("/", defaultInfo); 413 } 414 Iterator iter = patternMap.values().iterator(); 415 while( iter.hasNext() ) 416 { 417 PatternInfo info = (PatternInfo) iter.next(); 418 if( info == defaultInfo ) 419 continue; 420 defaultInfo.addQualifier(info); 421 } 422 423 return patternMap; 424 } 425 426 430 static class PatternInfo 431 { 432 static final HashMap ALL_TRANSPORTS = new HashMap (); 433 static 434 { 435 ALL_TRANSPORTS.put("NONE", WebSecurityMetaData.ALL_HTTP_METHODS); 436 } 437 438 439 String pattern; 440 441 String qpattern; 442 443 ArrayList qualifiers = new ArrayList (); 444 445 int type; 446 447 HashSet excludedMethods; 448 449 HashMap roles; 450 451 HashMap transports; 452 HashSet allMethods = new HashSet (); 454 457 boolean isOverriden; 458 459 463 PatternInfo(String pattern, int type) 464 { 465 this.pattern = pattern; 466 this.type = type; 467 } 468 469 473 void addExcludedMethods(String [] httpMethods) 474 { 475 Collection methods = Arrays.asList(httpMethods); 476 if( methods.size() == 0 ) 477 methods = WebSecurityMetaData.ALL_HTTP_METHODS; 478 if( excludedMethods == null ) 479 excludedMethods = new HashSet (); 480 excludedMethods.addAll(methods); 481 allMethods.addAll(methods); 482 } 483 488 public String [] getExcludedMethods() 489 { 490 String [] httpMethods = null; 491 if( excludedMethods != null ) 492 { 493 httpMethods = new String [excludedMethods.size()]; 494 excludedMethods.toArray(httpMethods); 495 } 496 return httpMethods; 497 } 498 499 504 public void addRoles(HashSet mappedRoles, String [] httpMethods) 505 { 506 Collection methods = Arrays.asList(httpMethods); 507 if( methods.size() == 0 ) 508 methods = WebSecurityMetaData.ALL_HTTP_METHODS; 509 allMethods.addAll(methods); 510 if( roles == null ) 511 roles = new HashMap (); 512 513 Iterator iter = mappedRoles.iterator(); 514 while( iter.hasNext() ) 515 { 516 String role = (String ) iter.next(); 517 HashSet roleMethods = (HashSet ) roles.get(role); 518 if( roleMethods == null ) 519 { 520 roleMethods = new HashSet (); 521 roles.put(role, roleMethods); 522 } 523 roleMethods.addAll(methods); 524 } 525 } 526 531 public Iterator getRoleMethods() 532 { 533 HashMap tmp = roles; 534 if( tmp == null ) 535 tmp = new HashMap (0); 536 Iterator iter = tmp.entrySet().iterator(); 537 return iter; 538 } 539 540 545 void addTransport(String transport, String [] httpMethods) 546 { 547 Collection methods = Arrays.asList(httpMethods); 548 if( methods.size() == 0 ) 549 methods = WebSecurityMetaData.ALL_HTTP_METHODS; 550 if( transports == null ) 551 transports = new HashMap (); 552 553 HashSet transportMethods = (HashSet ) transports.get(transport); 554 if( transportMethods == null ) 555 { 556 transportMethods = new HashSet (); 557 transports.put(transport, transportMethods); 558 } 559 transportMethods.addAll(methods); 560 } 561 566 public Iterator getTransportMethods() 567 { 568 HashMap tmp = transports; 569 if( tmp == null ) 570 tmp = ALL_TRANSPORTS; 571 Iterator iter = tmp.entrySet().iterator(); 572 return iter; 573 } 574 575 581 public String [] getMissingMethods() 582 { 583 String [] httpMethods = {}; 584 if( allMethods.size() == 0 ) 585 { 586 httpMethods = WebSecurityMetaData.ALL_HTTP_METHOD_NAMES; 588 } 589 else 590 { 591 httpMethods = WebSecurityMetaData.getMissingHttpMethods(allMethods); 592 } 593 return httpMethods; 594 } 595 596 603 void addQualifier(PatternInfo info) 604 { 605 if( qualifiers.contains(info) == false ) 606 { 607 if( info.type == PREFIX && info.matches(this) ) 609 isOverriden = true; 610 qualifiers.add(info); 611 } 612 } 613 614 619 public String getQualifiedPattern() 620 { 621 if( qpattern == null ) 622 { 623 StringBuffer tmp = new StringBuffer (pattern); 624 for(int n = 0; n < qualifiers.size(); n ++) 625 { 626 tmp.append(':'); 627 PatternInfo info = (PatternInfo) qualifiers.get(n); 628 tmp.append(info.pattern); 629 } 630 qpattern = tmp.toString(); 631 } 632 return qpattern; 633 } 634 635 public int hashCode() 636 { 637 return pattern.hashCode(); 638 } 639 640 public boolean equals(Object obj) 641 { 642 PatternInfo pi = (PatternInfo) obj; 643 return pattern.equals(pi.pattern); 644 } 645 646 652 public boolean matches(PatternInfo other) 653 { 654 int matchLength = pattern.length()-2; 655 boolean matches = pattern.regionMatches(0, other.pattern, 0, matchLength); 656 return matches; 657 } 658 659 665 public boolean isExtensionFor(PatternInfo other) 666 { 667 int offset = other.pattern.lastIndexOf('.'); 668 int length = pattern.length() - 1; 669 boolean isExtensionFor = false; 670 if( offset > 0 ) 671 { 672 isExtensionFor = pattern.regionMatches(1, other.pattern, offset, length); 673 } 674 return isExtensionFor; 675 } 676 677 public String toString() 678 { 679 StringBuffer tmp = new StringBuffer ("PatternInfo["); 680 tmp.append("pattern="); 681 tmp.append(pattern); 682 tmp.append(",type="); 683 tmp.append(type); 684 tmp.append(",isOverriden="); 685 tmp.append(isOverriden); 686 tmp.append(",qualifiers="); 687 tmp.append(qualifiers); 688 tmp.append("]"); 689 return tmp.toString(); 690 } 691 692 } 693 } 694 | Popular Tags |