/* * Copyright 2003-2006 Rick Knowles <winstone-devel at lists sourceforge net> * Distributed under the terms of either: * - the common development and distribution license (CDDL), v1.0; or * - the GNU Lesser General Public License, v2.1 or later */ package winstone.auth; import java.util.HashSet; import java.util.Set; import javax.servlet.http.HttpServletRequest; import org.w3c.dom.Node; import winstone.Logger; import winstone.Mapping; import winstone.WebAppConfiguration; /** * Models a restriction on a particular set of resources in the webapp. * * @author mailto: <a href="rick_knowles@hotmail.com">Rick Knowles</a> * @version $Id: SecurityConstraint.java,v 1.7 2006/08/10 06:38:30 rickknowles Exp $ */ public class SecurityConstraint { final String ELEM_DISPLAY_NAME = "display-name"; final String ELEM_WEB_RESOURCES = "web-resource-collection"; final String ELEM_WEB_RESOURCE_NAME = "web-resource-name"; final String ELEM_URL_PATTERN = "url-pattern"; final String ELEM_HTTP_METHOD = "http-method"; final String ELEM_AUTH_CONSTRAINT = "auth-constraint"; final String ELEM_ROLE_NAME = "role-name"; final String ELEM_USER_DATA_CONSTRAINT = "user-data-constraint"; final String ELEM_TRANSPORT_GUARANTEE = "transport-guarantee"; final String GUARANTEE_NONE = "NONE"; private String displayName; private String methodSets[]; private Mapping urlPatterns[]; private String rolesAllowed[]; private boolean needsSSL; /** * Constructor */ public SecurityConstraint(Node elm, Set rolesAllowed, int counter) { this.needsSSL = false; Set localUrlPatternList = new HashSet(); Set localMethodSetList = new HashSet(); Set localRolesAllowed = new HashSet(); for (int i = 0; i < elm.getChildNodes().getLength(); i++) { Node child = elm.getChildNodes().item(i); if (child.getNodeType() != Node.ELEMENT_NODE) continue; else if (child.getNodeName().equals(ELEM_DISPLAY_NAME)) this.displayName = WebAppConfiguration.getTextFromNode(child); else if (child.getNodeName().equals(ELEM_WEB_RESOURCES)) { String methodSet = null; // Parse the element and extract for (int k = 0; k < child.getChildNodes().getLength(); k++) { Node resourceChild = child.getChildNodes().item(k); if (resourceChild.getNodeType() != Node.ELEMENT_NODE) continue; String resourceChildNodeName = resourceChild.getNodeName(); if (resourceChildNodeName.equals(ELEM_URL_PATTERN)) { localUrlPatternList.add(Mapping.createFromURL( "Security", WebAppConfiguration.getTextFromNode(resourceChild))); } else if (resourceChildNodeName.equals(ELEM_HTTP_METHOD)) { methodSet = (methodSet == null ? "." : methodSet) + WebAppConfiguration.getTextFromNode(resourceChild) + "."; } } localMethodSetList.add(methodSet == null ? ".ALL." : methodSet); } else if (child.getNodeName().equals(ELEM_AUTH_CONSTRAINT)) { // Parse the element and extract for (int k = 0; k < child.getChildNodes().getLength(); k++) { Node roleChild = child.getChildNodes().item(k); if ((roleChild.getNodeType() != Node.ELEMENT_NODE) || !roleChild.getNodeName().equals(ELEM_ROLE_NAME)) continue; String roleName = WebAppConfiguration.getTextFromNode(roleChild); if (roleName.equals("*")) localRolesAllowed.addAll(rolesAllowed); else localRolesAllowed.add(roleName); } } else if (child.getNodeName().equals(ELEM_USER_DATA_CONSTRAINT)) { // Parse the element and extract for (int k = 0; k < child.getChildNodes().getLength(); k++) { Node roleChild = child.getChildNodes().item(k); if ((roleChild.getNodeType() == Node.ELEMENT_NODE) && roleChild.getNodeName().equals(ELEM_TRANSPORT_GUARANTEE)) this.needsSSL = !WebAppConfiguration.getTextFromNode(roleChild) .equalsIgnoreCase(GUARANTEE_NONE); } } } this.urlPatterns = (Mapping[]) localUrlPatternList.toArray(new Mapping[0]); this.methodSets = (String[]) localMethodSetList.toArray(new String[0]); this.rolesAllowed = (String[]) localRolesAllowed.toArray(new String[0]); if (this.displayName == null) this.displayName = BaseAuthenticationHandler.AUTH_RESOURCES.getString( "SecurityConstraint.DefaultName", "" + counter); } /** * Call this to evaluate the security constraint - is this operation allowed ? */ public boolean isAllowed(HttpServletRequest request) { for (int n = 0; n < this.rolesAllowed.length; n++) { if (request.isUserInRole(this.rolesAllowed[n])) { Logger.log(Logger.FULL_DEBUG, BaseAuthenticationHandler.AUTH_RESOURCES, "SecurityConstraint.Passed", new String[] { this.displayName, this.rolesAllowed[n] }); return true; } } Logger.log(Logger.FULL_DEBUG, BaseAuthenticationHandler.AUTH_RESOURCES, "SecurityConstraint.Failed", this.displayName); return false; } /** * Call this to evaluate the security constraint - is this constraint applicable to this url ? */ public boolean isApplicable(String url, String method) { for (int n = 0; n < this.urlPatterns.length; n++) if (this.urlPatterns[n].match(url, null, null) && methodCheck(method, this.methodSets[n])) return true; return false; } private boolean methodCheck(String protocol, String methodSet) { return methodSet.equals(".ALL.") || (methodSet.indexOf("." + protocol.toUpperCase() + ".") != -1); } public boolean needsSSL() { return this.needsSSL; } public String getName() { return this.displayName; } }