Ver código fonte

Changes to exception handling, and some additional validation of web.xml content.

Luke Taylor 20 anos atrás
pai
commit
28e8c93beb

+ 29 - 11
samples/acegifier/src/java/acegifier/WebXmlConverter.java

@@ -5,17 +5,16 @@ import org.springframework.util.Assert;
 import org.dom4j.Document;
 import org.dom4j.DocumentHelper;
 import org.dom4j.DocumentException;
+import org.dom4j.Node;
 import org.dom4j.io.SAXReader;
 import org.dom4j.io.DocumentSource;
 import org.dom4j.io.DocumentResult;
 
-import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.*;
 import javax.xml.transform.stream.StreamSource;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.List;
 
 /**
  * A utility to translate a web.xml file into a set of acegi security spring beans.
@@ -47,7 +46,7 @@ public class WebXmlConverter {
     /** The results of the conversion */
     private Document newWebXml, acegiBeansXml;
 
-    public WebXmlConverter() throws Exception {
+    public WebXmlConverter() throws IOException, TransformerConfigurationException {
         TransformerFactory tf = TransformerFactory.newInstance();
 
         acegiSecurityTransformer = tf.newTransformer(createTransformerSource(WEB_TO_SPRING_XSL_FILE));
@@ -81,17 +80,37 @@ public class WebXmlConverter {
 
     /** Set the input as an xml string */
     public void setInput(String xml) throws DocumentException {
-        Document document = DocumentHelper.parseText(xml);
-        xmlSource = new DocumentSource(document);
+        setInput(DocumentHelper.parseText(xml));
     }
 
-    /** set the input as an InputStream */
-    public void setInput(InputStream xmlIn) throws Exception {
+    /** Set the input as a stream */
+    public void setInput(InputStream in) throws DocumentException {
         SAXReader reader = new SAXReader();
-        Document document = reader.read(xmlIn);
+        setInput(reader.read(in));
+    }
+
+    /** set the input as a dom4j document */
+    public void setInput(Document document) throws DocumentException {
+        validateWebXml(document);
         xmlSource = new DocumentSource(document);
     }
 
+    /** Checks the web.xml to make sure it contains correct data */
+    private void validateWebXml(Document document) throws DocumentException {
+        Node authMethodNode =
+                document.selectSingleNode("/web-app/login-config/auth-method");
+        if(authMethodNode == null)
+            throw new DocumentException("login-config and auth-method must be present");
+        String authMethod =  authMethodNode.getStringValue().toUpperCase();
+        if(!authMethod.equals("BASIC") && !authMethod.equals("FORM")) {
+            throw new DocumentException("unsupported auth-method: " + authMethod);
+        }
+        List roles = document.selectNodes("/web-app/security-role");
+        if(roles.isEmpty()) {
+            throw new DocumentException("Each role used must be defined in a security-role element");
+        }
+    }
+
     public String getAcegiOutputFileName() {
         return acegiOutputFileName;
     }
@@ -112,5 +131,4 @@ public class WebXmlConverter {
     public Document getAcegiBeans() {
         return acegiBeansXml;
     }
-
 }

+ 10 - 9
samples/acegifier/src/java/acegifier/web/AcegifierController.java

@@ -8,14 +8,15 @@ import org.springframework.beans.factory.support.DefaultListableBeanFactory;
 import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
 import org.springframework.beans.BeansException;
 import net.sf.acegisecurity.util.InMemoryResource;
-import org.xml.sax.SAXParseException;
+
 import org.dom4j.Document;
+import org.dom4j.DocumentException;
 import org.dom4j.io.XMLWriter;
 import org.dom4j.io.OutputFormat;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.ByteArrayInputStream;
+import javax.xml.transform.TransformerException;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.HashMap;
@@ -41,20 +42,20 @@ public class AcegifierController extends SimpleFormController {
                 throws Exception {
 
         AcegifierForm conversion = (AcegifierForm)command;
-        ByteArrayInputStream in = new ByteArrayInputStream(conversion.getWebXml().getBytes());
-        WebXmlConverter converter = null;
+        WebXmlConverter converter = new WebXmlConverter();
         int nBeans = 0;
         Document newWebXml = null, acegiBeans = null;
 
         try {
-            converter = new WebXmlConverter();
-            converter.setInput(in);
+            converter.setInput(conversion.getWebXml());
             converter.doConversion();
             newWebXml = converter.getNewWebXml();
             acegiBeans = converter.getAcegiBeans();
             nBeans = validateAcegiBeans(conversion, acegiBeans, errors);
-        } catch (SAXParseException spe) {
-            errors.rejectValue("webXml","parseFailure","Your Web XML Document failed to parse: " + spe.getMessage());
+        } catch (DocumentException de) {
+            errors.rejectValue("webXml","webXmlDocError","There was a problem with your web.xml: " + de.getMessage());
+        } catch (TransformerException te) {
+            errors.rejectValue("webXml","transFailure","There was an error during the XSL transformation: " + te.getMessage());
         }
 
         if(errors.hasErrors()) {
@@ -85,7 +86,7 @@ public class AcegifierController extends SimpleFormController {
      * Validates the acegi beans, based on the input form data, and returns the number
      * of spring beans defined in the document.
      */
-    private int validateAcegiBeans(AcegifierForm conversion, Document beans, Errors errors) throws IOException {
+    private int validateAcegiBeans(AcegifierForm conversion, Document beans, Errors errors) {
         DefaultListableBeanFactory bf = createBeanFactory(beans);
 
         //TODO: actually do some proper validation!

+ 1 - 0
samples/acegifier/src/test/acegifier/WebXmlConverterTests.java

@@ -64,6 +64,7 @@ public class WebXmlConverterTests extends TestCase {
         assertNotNull(sef);
         assertNotNull(sef.getAuthenticationEntryPoint());
         FilterSecurityInterceptor fsi = sef.getFilterSecurityInterceptor();
+        System.out.println(prettyPrint(converter.getNewWebXml()));
         System.out.println(prettyPrint(converter.getAcegiBeans()));
 
     }

+ 0 - 18
samples/acegifier/src/test/test-web.xml

@@ -88,24 +88,6 @@
     </auth-constraint>
   </security-constraint>
 
-  <security-constraint>
-    <web-resource-collection>
-      <url-pattern>/acegilogin.jsp*</url-pattern>
-    </web-resource-collection>
-    <auth-constraint>
-      <role-name>*</role-name>
-    </auth-constraint>
-  </security-constraint>
-
-  <security-constraint>
-    <web-resource-collection>
-      <url-pattern>/*</url-pattern>
-    </web-resource-collection>
-    <auth-constraint>
-      <role-name>user</role-name>
-    </auth-constraint>
-  </security-constraint>
-
   <login-config>
     <auth-method>form</auth-method>
     <form-login-config>

+ 1 - 0
samples/acegifier/src/webapp/WEB-INF/classes/web-to-spring.xsl

@@ -248,6 +248,7 @@
           <xsl:text>&#xA;        CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON</xsl:text>
           <xsl:text>&#xA;        PATTERN_TYPE_APACHE_ANT</xsl:text>
           <xsl:apply-templates select="security-constraint"/>
+          <xsl:text>&#xA;        /*=ROLE_ANONYMOUS</xsl:text> <!-- by default allow anonymous access to top level urls --> 
           <xsl:text>&#xA;      </xsl:text>
         </value>
       </property>