📄 webcontainerauthorizer.java
字号:
*/ public boolean isConstrained( String url, Role role ) throws JDOMException { Element root = m_webxml.getRootElement(); XPath xpath; String selector; // Get all constraints that have our URL pattern // (Note the crazy j: prefix to denote the 2.4 j2ee schema) selector = "//j:web-app/j:security-constraint[j:web-resource-collection/j:url-pattern=\"" + url + "\"]"; xpath = XPath.newInstance( selector ); xpath.addNamespace( "j", J2EE_SCHEMA_24_NAMESPACE ); List<?> constraints = xpath.selectNodes( root ); // Get all constraints that match our Role pattern selector = "//j:web-app/j:security-constraint[j:auth-constraint/j:role-name=\"" + role.getName() + "\"]"; xpath = XPath.newInstance( selector ); xpath.addNamespace( "j", J2EE_SCHEMA_24_NAMESPACE ); List<?> roles = xpath.selectNodes( root ); // If we can't find either one, we must not be constrained if ( constraints.size() == 0 ) { return false; } // Shortcut: if the role is ALL, we are constrained if ( role.equals( Role.ALL ) ) { return true; } // If no roles, we must not be constrained if ( roles.size() == 0 ) { return false; } // If a constraint is contained in both lists, we must be constrained for ( Iterator<?> c = constraints.iterator(); c.hasNext(); ) { Element constraint = (Element)c.next(); for ( Iterator<?> r = roles.iterator(); r.hasNext(); ) { Element roleConstraint = (Element)r.next(); if ( constraint.equals( roleConstraint ) ) { return true; } } } return false; } /** * Returns <code>true</code> if the web container is configured to protect * certain JSPWiki resources by requiring authentication. Specifically, this * method parses JSPWiki's web application descriptor (<code>web.xml</code>) * and identifies whether the string representation of * {@link com.ecyrd.jspwiki.auth.authorize.Role#AUTHENTICATED} is required * to access <code>/Delete.jsp</code> and <code>LoginRedirect.jsp</code>. * If the administrator has uncommented the large * <code><security-constraint></code> section of <code>web.xml</code>, * this will be true. This is admittedly an indirect way to go about it, but * it should be an accurate test for default installations, and also in 99% * of customized installs. * @return <code>true</code> if the container protects resources, * <code>false</code> otherwise */ public boolean isContainerAuthorized() { return m_containerAuthorized; } /** * Returns an array of role Principals this Authorizer knows about. * This method will return an array of Role objects corresponding to * the logical roles enumerated in the <code>web.xml</code>. * This method actually returns a defensive copy of an internally stored * array. * @return an array of Principals representing the roles */ public Principal[] getRoles() { return m_containerRoles.clone(); } /** * Protected method that extracts the roles from JSPWiki's web application * deployment descriptor. Each Role is constructed by using the String * representation of the Role, for example * <code>new Role("Administrator")</code>. * @param webxml the web application deployment descriptor * @return an array of Role objects * @throws JDOMException if elements cannot be parsed correctly */ protected Role[] getRoles( Document webxml ) throws JDOMException { Set<Role> roles = new HashSet<Role>(); Element root = webxml.getRootElement(); // Get roles referred to by constraints String selector = "//j:web-app/j:security-constraint/j:auth-constraint/j:role-name"; XPath xpath = XPath.newInstance( selector ); xpath.addNamespace( "j", J2EE_SCHEMA_24_NAMESPACE ); List<?> nodes = xpath.selectNodes( root ); for( Iterator<?> it = nodes.iterator(); it.hasNext(); ) { String role = ( (Element) it.next() ).getTextTrim(); roles.add( new Role( role ) ); } // Get all defined roles selector = "//j:web-app/j:security-role/j:role-name"; xpath = XPath.newInstance( selector ); xpath.addNamespace( "j", J2EE_SCHEMA_24_NAMESPACE ); nodes = xpath.selectNodes( root ); for( Iterator<?> it = nodes.iterator(); it.hasNext(); ) { String role = ( (Element) it.next() ).getTextTrim(); roles.add( new Role( role ) ); } return roles.toArray( new Role[roles.size()] ); } /** * Returns an {@link org.jdom.Document} representing JSPWiki's web * application deployment descriptor. The document is obtained by calling * the servlet context's <code>getResource()</code> method and requesting * <code>/WEB-INF/web.xml</code>. For non-servlet applications, this * method calls this class' * {@link ClassLoader#getResource(java.lang.String)} and requesting * <code>WEB-INF/web.xml</code>. * @return the descriptor * @throws IOException if the deployment descriptor cannot be found or opened * @throws JDOMException if the deployment descriptor cannot be parsed correctly */ protected Document getWebXml() throws JDOMException, IOException { URL url; SAXBuilder builder = new SAXBuilder(); builder.setValidation( false ); builder.setEntityResolver( new LocalEntityResolver() ); Document doc = null; if ( m_engine.getServletContext() == null ) { ClassLoader cl = WebContainerAuthorizer.class.getClassLoader(); url = cl.getResource( "WEB-INF/web.xml" ); if( url != null ) log.info( "Examining " + url.toExternalForm() ); } else { url = m_engine.getServletContext().getResource( "/WEB-INF/web.xml" ); if( url != null ) log.info( "Examining " + url.toExternalForm() ); } if( url == null ) throw new IOException("Unable to find web.xml for processing."); log.debug( "Processing web.xml at " + url.toExternalForm() ); doc = builder.build( url ); return doc; } /** * <p>XML entity resolver that redirects resolution requests by JDOM, JAXP and * other XML parsers to locally-cached copies of the resources. Local * resources are stored in the <code>WEB-INF/dtd</code> directory.</p> * <p>For example, Sun Microsystem's DTD for the webapp 2.3 specification is normally * kept at <code>http://java.sun.com/dtd/web-app_2_3.dtd</code>. The * local copy is stored at <code>WEB-INF/dtd/web-app_2_3.dtd</code>.</p> * @author Andrew Jaquith */ public class LocalEntityResolver implements EntityResolver { /** * Returns an XML input source for a requested external resource by * reading the resource instead from local storage. The local resource path * is <code>WEB-INF/dtd</code>, plus the file name of the requested * resource, minus the non-filename path information. * @param publicId the public ID, such as * <code>-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN</code> * @param systemId the system ID, such as * <code>http://java.sun.com/dtd/web-app_2_3.dtd</code> * @return the InputSource containing the resolved resource * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String, * java.lang.String) * @throws SAXException if the resource cannot be resolved locally * @throws IOException if the resource cannot be opened */ public InputSource resolveEntity( String publicId, String systemId ) throws SAXException, IOException { String file = systemId.substring( systemId.lastIndexOf( '/' ) + 1 ); URL url; if ( m_engine.getServletContext() == null ) { ClassLoader cl = WebContainerAuthorizer.class.getClassLoader(); url = cl.getResource( "WEB-INF/dtd/" + file ); } else { url = m_engine.getServletContext().getResource( "/WEB-INF/dtd/" + file ); } if( url != null ) { InputSource is = new InputSource( url.openStream() ); log.debug( "Resolved systemID=" + systemId + " using local file " + url ); return is; } // // Let's fall back to default behaviour of the container, and let's // also let the user know what is going on. This caught me by surprise // while running JSPWiki on an unconnected laptop... // // The DTD needs to be resolved and read because it contains things like // entity definitions... // log.info("Please note: There are no local DTD references in /WEB-INF/dtd/"+file+"; falling back to default behaviour."+ " This may mean that the XML parser will attempt to connect to the internet to find the DTD."+ " If you are running JSPWiki locally in an unconnected network, you might want to put the DTD files in place to avoid nasty UnknownHostExceptions."); // Fall back to default behaviour return null; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -