/** * Perform access control based on the specified authorization constraint. Return <code>true * </code> if this constraint is satisfied and processing should continue, or <code>false</code> * otherwise. * * @param request Request we are processing * @param response Response we are creating * @param constraints Security constraint we are enforcing * @param context The Context to which client of this class is attached. * @exception IOException if an input/output error occurs */ @Override public boolean hasResourcePermission( Request request, Response response, SecurityConstraint[] constraints, Context context) throws IOException { if (constraints == null || constraints.length == 0) return (true); // Specifically allow access to the form login and form error pages // and the "j_security_check" action LoginConfig config = context.getLoginConfig(); if ((config != null) && (Constants.FORM_METHOD.equals(config.getAuthMethod()))) { String requestURI = request.getRequestPathMB().toString(); String loginPage = config.getLoginPage(); if (loginPage.equals(requestURI)) { if (log.isDebugEnabled()) log.debug(" Allow access to login page " + loginPage); return (true); } String errorPage = config.getErrorPage(); if (errorPage.equals(requestURI)) { if (log.isDebugEnabled()) log.debug(" Allow access to error page " + errorPage); return (true); } if (requestURI.endsWith(Constants.FORM_ACTION)) { if (log.isDebugEnabled()) log.debug(" Allow access to username/password submission"); return (true); } } // Which user principal have we already authenticated? Principal principal = request.getPrincipal(); boolean status = false; boolean denyfromall = false; for (int i = 0; i < constraints.length; i++) { SecurityConstraint constraint = constraints[i]; String roles[]; if (constraint.getAllRoles()) { // * means all roles defined in web.xml roles = request.getContext().findSecurityRoles(); } else { roles = constraint.findAuthRoles(); } if (roles == null) roles = new String[0]; if (log.isDebugEnabled()) log.debug(" Checking roles " + principal); if (roles.length == 0 && !constraint.getAllRoles()) { if (constraint.getAuthConstraint()) { if (log.isDebugEnabled()) log.debug("No roles"); status = false; // No listed roles means no access at all denyfromall = true; break; } if (log.isDebugEnabled()) log.debug("Passing all access"); status = true; } else if (principal == null) { if (log.isDebugEnabled()) log.debug(" No user authenticated, cannot grant access"); } else { for (int j = 0; j < roles.length; j++) { if (hasRole(null, principal, roles[j])) { status = true; if (log.isDebugEnabled()) log.debug("Role found: " + roles[j]); } else if (log.isDebugEnabled()) log.debug("No role found: " + roles[j]); } } } if (!denyfromall && allRolesMode != AllRolesMode.STRICT_MODE && !status && principal != null) { if (log.isDebugEnabled()) { log.debug("Checking for all roles mode: " + allRolesMode); } // Check for an all roles(role-name="*") for (int i = 0; i < constraints.length; i++) { SecurityConstraint constraint = constraints[i]; String roles[]; // If the all roles mode exists, sets if (constraint.getAllRoles()) { if (allRolesMode == AllRolesMode.AUTH_ONLY_MODE) { if (log.isDebugEnabled()) { log.debug("Granting access for role-name=*, auth-only"); } status = true; break; } // For AllRolesMode.STRICT_AUTH_ONLY_MODE there must be zero roles roles = request.getContext().findSecurityRoles(); if (roles.length == 0 && allRolesMode == AllRolesMode.STRICT_AUTH_ONLY_MODE) { if (log.isDebugEnabled()) { log.debug("Granting access for role-name=*, strict auth-only"); } status = true; break; } } } } // Return a "Forbidden" message denying access to this resource if (!status) { response.sendError(HttpServletResponse.SC_FORBIDDEN, sm.getString("realmBase.forbidden")); } return status; }
/** * Return the SecurityConstraints configured to guard the request URI for this request, or <code> * null</code> if there is no such constraint. * * @param request Request we are processing * @param context Context the Request is mapped to */ @Override public SecurityConstraint[] findSecurityConstraints(Request request, Context context) { ArrayList<SecurityConstraint> results = null; // Are there any defined security constraints? SecurityConstraint constraints[] = context.findConstraints(); if ((constraints == null) || (constraints.length == 0)) { if (log.isDebugEnabled()) log.debug(" No applicable constraints defined"); return (null); } // Check each defined security constraint String uri = request.getRequestPathMB().toString(); // Bug47080 - in rare cases this may be null // Mapper treats as '/' do the same to prevent NPE if (uri == null) { uri = "/"; } String method = request.getMethod(); int i; boolean found = false; for (i = 0; i < constraints.length; i++) { SecurityCollection[] collection = constraints[i].findCollections(); // If collection is null, continue to avoid an NPE // See Bugzilla 30624 if (collection == null) { continue; } if (log.isDebugEnabled()) { log.debug( " Checking constraint '" + constraints[i] + "' against " + method + " " + uri + " --> " + constraints[i].included(uri, method)); } for (int j = 0; j < collection.length; j++) { String[] patterns = collection[j].findPatterns(); // If patterns is null, continue to avoid an NPE // See Bugzilla 30624 if (patterns == null) { continue; } for (int k = 0; k < patterns.length; k++) { if (uri.equals(patterns[k])) { found = true; if (collection[j].findMethod(method)) { if (results == null) { results = new ArrayList<SecurityConstraint>(); } results.add(constraints[i]); } } } } } if (found) { return resultsToArray(results); } int longest = -1; for (i = 0; i < constraints.length; i++) { SecurityCollection[] collection = constraints[i].findCollections(); // If collection is null, continue to avoid an NPE // See Bugzilla 30624 if (collection == null) { continue; } if (log.isDebugEnabled()) { log.debug( " Checking constraint '" + constraints[i] + "' against " + method + " " + uri + " --> " + constraints[i].included(uri, method)); } for (int j = 0; j < collection.length; j++) { String[] patterns = collection[j].findPatterns(); // If patterns is null, continue to avoid an NPE // See Bugzilla 30624 if (patterns == null) { continue; } boolean matched = false; int length = -1; for (int k = 0; k < patterns.length; k++) { String pattern = patterns[k]; if (pattern.startsWith("/") && pattern.endsWith("/*") && pattern.length() >= longest) { if (pattern.length() == 2) { matched = true; length = pattern.length(); } else if (pattern.regionMatches(0, uri, 0, pattern.length() - 1) || (pattern.length() - 2 == uri.length() && pattern.regionMatches(0, uri, 0, pattern.length() - 2))) { matched = true; length = pattern.length(); } } } if (matched) { found = true; if (length > longest) { if (results != null) { results.clear(); } longest = length; } if (collection[j].findMethod(method)) { if (results == null) { results = new ArrayList<SecurityConstraint>(); } results.add(constraints[i]); } } } } if (found) { return resultsToArray(results); } for (i = 0; i < constraints.length; i++) { SecurityCollection[] collection = constraints[i].findCollections(); // If collection is null, continue to avoid an NPE // See Bugzilla 30624 if (collection == null) { continue; } if (log.isDebugEnabled()) { log.debug( " Checking constraint '" + constraints[i] + "' against " + method + " " + uri + " --> " + constraints[i].included(uri, method)); } boolean matched = false; int pos = -1; for (int j = 0; j < collection.length; j++) { String[] patterns = collection[j].findPatterns(); // If patterns is null, continue to avoid an NPE // See Bugzilla 30624 if (patterns == null) { continue; } for (int k = 0; k < patterns.length && !matched; k++) { String pattern = patterns[k]; if (pattern.startsWith("*.")) { int slash = uri.lastIndexOf("/"); int dot = uri.lastIndexOf("."); if (slash >= 0 && dot > slash && dot != uri.length() - 1 && uri.length() - dot == pattern.length() - 1) { if (pattern.regionMatches(1, uri, dot, uri.length() - dot)) { matched = true; pos = j; } } } } } if (matched) { found = true; if (collection[pos].findMethod(method)) { if (results == null) { results = new ArrayList<SecurityConstraint>(); } results.add(constraints[i]); } } } if (found) { return resultsToArray(results); } for (i = 0; i < constraints.length; i++) { SecurityCollection[] collection = constraints[i].findCollections(); // If collection is null, continue to avoid an NPE // See Bugzilla 30624 if (collection == null) { continue; } if (log.isDebugEnabled()) { log.debug( " Checking constraint '" + constraints[i] + "' against " + method + " " + uri + " --> " + constraints[i].included(uri, method)); } for (int j = 0; j < collection.length; j++) { String[] patterns = collection[j].findPatterns(); // If patterns is null, continue to avoid an NPE // See Bugzilla 30624 if (patterns == null) { continue; } boolean matched = false; for (int k = 0; k < patterns.length && !matched; k++) { String pattern = patterns[k]; if (pattern.equals("/")) { matched = true; } } if (matched) { if (results == null) { results = new ArrayList<SecurityConstraint>(); } results.add(constraints[i]); } } } if (results == null) { // No applicable security constraint was found if (log.isDebugEnabled()) log.debug(" No applicable constraint located"); } return resultsToArray(results); }