1 25 26 package org.objectweb.jonas.security.realm.web.catalina55; 27 28 import java.io.IOException ; 29 import java.security.Principal ; 30 import java.security.cert.X509Certificate ; 31 import java.util.ArrayList ; 32 33 import javax.servlet.http.HttpServletRequest ; 34 import javax.servlet.http.HttpServletResponse ; 35 36 import org.apache.catalina.Context; 37 import org.apache.catalina.connector.Request; 38 import org.apache.catalina.connector.Response; 39 import org.apache.catalina.LifecycleException; 40 import org.apache.catalina.deploy.LoginConfig; 41 import org.apache.catalina.deploy.SecurityConstraint; 42 import org.apache.catalina.realm.Constants; 43 import org.apache.catalina.realm.GenericPrincipal; 44 import org.apache.catalina.realm.RealmBase; 45 import org.apache.catalina.util.StringManager; 46 47 import org.objectweb.jonas.common.Log; 48 import org.objectweb.jonas.security.SecurityService; 49 import org.objectweb.jonas.security.realm.factory.JResource; 50 import org.objectweb.jonas.security.realm.factory.JResourceException; 51 import org.objectweb.jonas.security.realm.principals.User; 52 import org.objectweb.jonas.service.ServiceManager; 53 import org.objectweb.jonas.web.lib.PermissionManager; 54 55 import org.objectweb.security.context.SecurityContext; 56 import org.objectweb.security.context.SecurityCurrent; 57 58 import org.objectweb.util.monolog.api.BasicLevel; 59 import org.objectweb.util.monolog.api.Logger; 60 61 73 public class JACC extends RealmBase implements Cloneable { 74 75 78 private static final String NAME = "JACC_Catalina55"; 79 80 83 private static final String INFO = "org.objectweb.jonas.security.realm.JRealmJACCCatalina50/1.0"; 84 85 88 private static StringManager sm = StringManager.getManager(Constants.Package); 89 90 93 private static Logger logger = null; 94 95 99 private JResource jResource = null; 100 101 104 private String resourceName = null; 105 106 109 private SecurityService securityService = null; 110 111 114 private PermissionManager permissionManager = null; 115 116 122 private ThreadLocal lastRequestThread = new ThreadLocal (); 123 124 127 private Context context = null; 128 129 132 private String realmName = NAME; 133 134 135 142 public String getInfo() { 143 return INFO; 144 } 145 146 151 public String getResourceName() { 152 return resourceName; 153 } 154 155 160 public void setResourceName(String resourceName) { 161 this.resourceName = resourceName; 162 163 } 164 165 170 public void setPermissionManager(PermissionManager permissionManager) { 171 this.permissionManager = permissionManager; 172 173 } 174 175 183 public SecurityConstraint[] findSecurityConstraints(Request request, Context context) { 184 return super.findSecurityConstraints(request, context); 186 } 187 188 201 public boolean hasResourcePermission(Request request, Response response, SecurityConstraint[] constraints, 202 Context context) throws IOException { 203 204 lastRequestThread.set(request); 206 207 209 LoginConfig config = context.getLoginConfig(); 212 if (config != null && Constants.FORM_METHOD.equals(config.getAuthMethod())) { 213 String requestURI = request.getDecodedRequestURI(); 214 String loginPage = context.getPath() + config.getLoginPage(); 215 if (loginPage.equals(requestURI)) { 216 if (logger.isLoggable(BasicLevel.DEBUG)) { 217 logger.log(BasicLevel.DEBUG, realmName + "Allow access to login page " + loginPage); 218 } 219 return true; 220 } 221 222 String errorPage = context.getPath() + config.getErrorPage(); 223 if (errorPage.equals(requestURI)) { 224 if (logger.isLoggable(BasicLevel.DEBUG)) { 225 logger.log(BasicLevel.DEBUG, realmName + "Allow access to error page " + errorPage); 226 } 227 return true; 228 } 229 if (requestURI.endsWith(Constants.FORM_ACTION)) { 230 if (logger.isLoggable(BasicLevel.DEBUG)) { 231 logger.log(BasicLevel.DEBUG, realmName + "Allow access to username/password submission"); 232 } 233 return true; 234 } 235 } 236 237 Principal principal = request.getUserPrincipal(); 239 240 242 String [] roles = null; 243 String principalName = null; 244 if (principal instanceof GenericPrincipal) { 245 roles = ((GenericPrincipal) principal).getRoles(); 246 principalName = principal.getName(); 247 } 248 249 if (permissionManager == null) { 250 logger.log(BasicLevel.ERROR, realmName + "No permission manager is set. It means that you are using this realm without using the JOnAS deployer but only Tomcat."); 251 return false; 252 } 253 254 boolean hasResourcePermission = permissionManager.checkWebResourcePermission(request, principalName, roles); 255 256 if (!hasResourcePermission) { 260 response.sendError(HttpServletResponse.SC_FORBIDDEN, sm 262 .getString("realmBase.forbidden")); 263 } 264 265 return hasResourcePermission; 266 } 267 268 279 public boolean hasRole(Principal principal, String role) { 280 281 if ((principal == null) || (role == null) || !(principal instanceof GenericPrincipal)) { 282 return false; 283 } 284 285 if (logger.isLoggable(BasicLevel.DEBUG)) { 286 logger.log(BasicLevel.DEBUG, realmName + "Principal = " + principal); 287 logger.log(BasicLevel.DEBUG, realmName + "Role = " + role); 288 } 289 290 if (context == null) { 291 logger.log(BasicLevel.ERROR, realmName + "Cannot find a servlet name for isUserInRole() as no context was found"); 292 return false; 293 } 294 295 Request req = (Request ) lastRequestThread.get(); 296 297 if (req == null) { 298 logger.log(BasicLevel.ERROR, realmName + "Cannot find a servlet name for isUserInRole(). No previous request !"); 299 return false; 300 } 301 String servletName = findServletName(req); 302 String [] roles = null; 303 String principalName = null; 304 305 if (principal instanceof GenericPrincipal) { 306 roles = ((GenericPrincipal) principal).getRoles(); 307 principalName = principal.getName(); 308 } 309 310 if (permissionManager == null) { 311 logger.log(BasicLevel.ERROR, realmName + "No permission manager is set. It means that you are using this realm without using the JOnAS deployer but only Tomcat."); 312 return false; 313 } 314 315 boolean hasRole = permissionManager.checkWebRoleRefPermission(req, servletName, principalName, roles, role); 316 return hasRole; 317 } 318 319 327 private String findServletName(Request request) { 328 329 String userPattern = request.getRequestURI().substring(request.getContextPath().length()); 331 332 if (logger.isLoggable(BasicLevel.DEBUG)) { 333 logger.log(BasicLevel.DEBUG, realmName + "User Pattern = " + userPattern); 334 } 335 336 String servletName = ""; 337 String [] patterns = context.findServletMappings(); 338 boolean foundServlet = false; 339 String pattern = ""; 340 int i = 0; 341 342 while ((i < patterns.length) && !foundServlet) { 344 pattern = patterns[i]; 345 if (logger.isLoggable(BasicLevel.DEBUG)) { 346 logger.log(BasicLevel.DEBUG, realmName + "Pattern found = " + pattern); 347 logger.log(BasicLevel.DEBUG, realmName + "Servlet name for pattern = " + context.findServletMapping(pattern)); 348 } 349 350 if (pattern.startsWith("*.") && userPattern.endsWith(pattern.substring(1))) { 352 foundServlet = true; 353 continue; 354 } 355 356 if (pattern.equals(userPattern)) { 359 foundServlet = true; 360 continue; 361 } 362 363 i++; 364 } 365 366 if (foundServlet) { 367 servletName = context.findServletMapping(pattern); 368 if (servletName.equals("jsp")) { 371 servletName = ""; 372 } 373 if (logger.isLoggable(BasicLevel.DEBUG)) { 374 logger.log(BasicLevel.DEBUG, realmName + "Found servlet name = " + servletName); 375 } 376 } 377 return servletName; 378 } 379 380 394 public boolean hasUserDataPermission(Request request, Response response, SecurityConstraint[] constraints) 395 throws IOException { 396 397 lastRequestThread.set(request); 399 400 402 if (request.getRequest().isSecure()) { 404 if (logger.isLoggable(BasicLevel.DEBUG)) { 405 logger.log(BasicLevel.DEBUG, realmName + "User data constraint already satisfied"); 406 } 407 return true; 408 } 409 410 Principal principal = ((HttpServletRequest ) request).getUserPrincipal(); 412 413 415 String [] roles = null; 416 String principalName = null; 417 if (principal instanceof GenericPrincipal) { 418 roles = ((GenericPrincipal) principal).getRoles(); 419 principalName = principal.getName(); 420 } 421 422 for (int i = 0; i < constraints.length; i++) { 424 SecurityConstraint constraint = constraints[i]; 425 String userConstraint = constraint.getUserConstraint(); 428 429 if (userConstraint != null 431 && (userConstraint.equals(Constants.INTEGRAL_TRANSPORT) || userConstraint 432 .equals(Constants.CONFIDENTIAL_TRANSPORT))) { 433 int redirectPort = request.getConnector().getRedirectPort(); 435 436 if (redirectPort <= 0) { 438 if (logger.isLoggable(BasicLevel.DEBUG)) { 439 logger.log(BasicLevel.DEBUG, realmName + "SSL redirect is disabled"); 440 } 441 response.sendError(HttpServletResponse.SC_FORBIDDEN, request.getRequestURI()); 442 return false; 443 } 444 445 StringBuffer file = new StringBuffer (); 447 String protocol = "https"; 448 String host = request.getServerName(); 449 file.append(protocol).append("://"); 451 file.append(host).append(":").append(redirectPort); 453 file.append(request.getRequestURI()); 455 String requestedSessionId = request.getRequestedSessionId(); 456 if ((requestedSessionId != null) && request.isRequestedSessionIdFromURL()) { 457 file.append(";jsessionid="); 458 file.append(requestedSessionId); 459 } 460 String queryString = request.getQueryString(); 461 if (queryString != null) { 462 file.append('?'); 463 file.append(queryString); 464 } 465 466 if (logger.isLoggable(BasicLevel.DEBUG)) { 467 logger.log(BasicLevel.DEBUG, realmName + "Redirecting to " + file.toString()); 468 } 469 response.sendRedirect(file.toString()); 470 471 return false; 472 } 473 } 474 475 if (permissionManager == null) { 477 logger.log(BasicLevel.ERROR, realmName + "No permission manager is set. It means that you are using this realm without using the JOnAS deployer but only Tomcat."); 478 return false; 479 } 480 481 boolean hasUserDataPermission = permissionManager.checkWebUserDataPermission(request, principalName, roles); 483 return hasUserDataPermission; 484 485 } 486 487 496 public Principal authenticate(String username, String credentials) { 497 498 if (username == null) { 500 if (logger.isLoggable(BasicLevel.DEBUG)) { 501 logger.log(BasicLevel.DEBUG, realmName + "No username so no authentication"); 502 } 503 return null; 504 } 505 506 User user = null; 508 try { 509 user = jResource.findUser(username); 510 } catch (Exception jre) { 511 logger.log(BasicLevel.ERROR, realmName + "Can not find the user : " + jre.getMessage()); 513 return null; 514 } 515 516 if (user == null) { 518 if (logger.isLoggable(BasicLevel.DEBUG)) { 519 logger.log(BasicLevel.DEBUG, realmName + "User " + username + " not found."); 520 } 521 return null; 522 } 523 524 boolean validated = jResource.isValidUser(user, credentials); 525 if (!validated) { 526 logger.log(BasicLevel.ERROR, realmName + "The password for the user " + username + " is not valid"); 527 return null; 528 } 529 530 ArrayList combinedRoles = null; 531 try { 532 combinedRoles = jResource.getArrayListCombinedRoles(user); 533 } catch (JResourceException jre) { 534 logger.log(BasicLevel.ERROR, realmName + jre.getMessage(), jre); 535 return null; 536 } 537 538 GenericPrincipal principal = new GenericPrincipal(this, user.getName(), user.getPassword(), combinedRoles); 539 SecurityContext ctx = new SecurityContext(principal.getName(), combinedRoles); 540 SecurityCurrent current = SecurityCurrent.getCurrent(); 541 current.setSecurityContext(ctx); 542 543 return principal; 544 } 545 546 554 public Principal authenticate(X509Certificate [] cert) { 555 String dn = cert[0].getSubjectDN().getName(); 556 return authenticate(dn, "tomcat"); 557 } 558 559 564 protected String getName() { 565 return NAME; 566 } 567 568 574 protected String getPassword(String username) { 575 return null; 576 } 577 578 584 protected Principal getPrincipal(String username) { 585 return null; 586 } 587 588 594 public void setContext(Context context) { 595 this.context = context; 596 StringBuffer sb = new StringBuffer (); 597 sb.append("["); 598 sb.append(NAME); 599 sb.append(":"); 600 sb.append(resourceName); 601 sb.append(":"); 602 if (context != null) { 603 sb.append(context.getName()); 604 } 605 sb.append("] "); 606 this.realmName = sb.toString(); 607 } 608 609 615 public synchronized void start() throws LifecycleException { 616 617 if (logger == null) { 618 logger = Log.getLogger(Log.JONAS_SECURITY_PREFIX); 619 } 620 621 try { 623 securityService = (SecurityService) ServiceManager.getInstance().getSecurityService(); 624 } catch (Exception e) { 625 throw new LifecycleException("can't retrieve Security service"); 627 } 628 629 jResource = securityService.getJResource(resourceName); 631 if (jResource == null) { 632 throw new LifecycleException("Can't retrieve resource '" + resourceName + "' from the security service"); 633 } 634 635 super.start(); 637 638 } 639 640 646 public synchronized void stop() throws LifecycleException { 647 super.stop(); 649 650 jResource = null; 652 } 653 654 659 protected void log(String message) { 660 if (logger.isLoggable(BasicLevel.DEBUG)) { 661 logger.log(BasicLevel.DEBUG, message); 662 } 663 } 664 665 671 public Object clone() throws CloneNotSupportedException { 672 JACC jRealm = new JACC(); 673 jRealm.setResourceName(resourceName); 674 return jRealm; 675 } 676 677 680 public PermissionManager getPermissionManager() { 681 return permissionManager; 682 } 683 684 685 } | Popular Tags |