From 25fa471779858995b94910058c2c164df9939e35 Mon Sep 17 00:00:00 2001 From: Luke Taylor Date: Sun, 26 Jun 2005 17:30:36 +0000 Subject: [PATCH] First version of web.xml to acegi translator --- ...WebXmlSecurityToSpringBeansTranslator.java | 108 ++++++++ core/src/main/resources/web-to-spring.xsl | 258 ++++++++++++++++++ ...lSecurityToSpringBeansTranslatorTests.java | 59 ++++ core/src/test/resources/test-web.xml | 54 ++++ 4 files changed, 479 insertions(+) create mode 100644 core/src/main/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslator.java create mode 100644 core/src/main/resources/web-to-spring.xsl create mode 100644 core/src/test/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslatorTests.java create mode 100644 core/src/test/resources/test-web.xml diff --git a/core/src/main/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslator.java b/core/src/main/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslator.java new file mode 100644 index 0000000000..b57b0bf17d --- /dev/null +++ b/core/src/main/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslator.java @@ -0,0 +1,108 @@ +package net.sf.acegisecurity.util; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.DOMImplementation; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.FileSystemResource; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; +import org.springframework.beans.factory.xml.XmlBeanDefinitionReader; +import org.xml.sax.SAXException; + +import javax.xml.transform.stream.StreamSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.Source; +import javax.xml.transform.Result; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.dom.DOMResult; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.ParserConfigurationException; +import java.io.IOException; +import java.io.FileOutputStream; +import java.io.InputStream; + + +/** + * A utility to translate a web.xml file into a set of + * acegi security spring beans. + * + *

+ * This class wraps the XSL transform which actually does + * most of the work. It also tests the result by + * loading it into a Spring bean factory. + *

+ * + * @author Luke Taylor + * @version $Id$ + */ +public class WebXmlSecurityToSpringBeansTranslator { + private String webToSpringXsltFile = "web-to-spring.xsl"; + private String outputFileName = "applicationContext-acegi-security.xml"; + private Transformer transformer, identityTransformer; + private DefaultListableBeanFactory beanFactory; + DocumentBuilderFactory dbf; + + public WebXmlSecurityToSpringBeansTranslator() throws Exception { + ClassPathResource resource = new ClassPathResource(webToSpringXsltFile); + Source xsltSource = new StreamSource(resource.getInputStream()); + dbf = DocumentBuilderFactory.newInstance(); + dbf.setNamespaceAware(true); + TransformerFactory tf = TransformerFactory.newInstance(); + transformer = tf.newTransformer(xsltSource); + identityTransformer = tf.newTransformer(); + identityTransformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "-//SPRING//DTD BEAN//EN"); + identityTransformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "http://www.springframework.org/dtd/spring-beans.dtd"); + } + + public void translate(InputStream in) throws TransformerException, IOException, ParserConfigurationException, SAXException { + DocumentBuilder db = dbf.newDocumentBuilder(); + Document d = db.parse(in); + translate(d); + } + + /** + * Converts the web.xml supplied as a DOM Node + * + * @param webXml the web application xml + */ + public void translate(Node webXml) throws IOException, TransformerException, ParserConfigurationException { + Source xmlSource = new DOMSource(webXml); + DOMResult domResult = new DOMResult(); + + transformer.transform(xmlSource, domResult); + + // Obtain DOM for additional manipulation here. + Node document = domResult.getNode(); + + // Tranform DOM with identity transform to get the output file + Result streamResult = new StreamResult(new FileOutputStream(outputFileName)); + xmlSource = new DOMSource(document); + identityTransformer.transform(xmlSource, streamResult); + beanFactory = new DefaultListableBeanFactory(); + XmlBeanDefinitionReader beanReader = new XmlBeanDefinitionReader(beanFactory); + beanReader.loadBeanDefinitions(new FileSystemResource(outputFileName)); + } + + public String getOutputFileName() { + return outputFileName; + } + + public void setOutputFileName(String outputFileName) { + this.outputFileName = outputFileName; + } + + /** + * Mainly intended for testing + * @return the bean factory built from the created acegi security application context file + * + */ + public BeanFactory getBeanFactory() { + return beanFactory; + } +} diff --git a/core/src/main/resources/web-to-spring.xsl b/core/src/main/resources/web-to-spring.xsl new file mode 100644 index 0000000000..7c55d133e9 --- /dev/null +++ b/core/src/main/resources/web-to-spring.xsl @@ -0,0 +1,258 @@ + + + + + + + + + + + + + + + + + + + ROLE_ + + , + + + + + +/**=httpSessionContextIntegrationFilter + + + ,authenticationProcessingFilter + + + ,basicProcessingFilter + + + Unsupported auth-method in web.xml, must be FORM or BASIC + + +,rememberMeProcessingFilter,anonymousProcessingFilter,securityEnforcementFilter + + + + + + + + + + + + + + + + + ======================== AUTHENTICATION ======================= + + + + + + + + + + + + + + + + + + + + superuser=password, + + + + + + + foobar + anonymousUser,ROLE_ANONYMOUS + + + + foobar + + + + + + + + + + + + springRocks + + + + springRocks + + + + + + + + + + + + + + + + + + Your Realm + + + + + + + + + + + + + + + + + + + + + + + + + + ======================== FILTER CHAIN ======================= + + if you wish to use channel security, add "channelProcessingFilter," in front + of "httpSessionContextIntegrationFilter" in the list below + + + + CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON + PATTERN_TYPE_APACHE_ANT + + + + + + + + + + Processing form login configuration + Remember to switch your login form action from "j_security_check" to "j_acegi_security_check" + + + + + + /j_acegi_security_check + + + + + + false + + + + + + + false + + + + + + + + + + + + + Note the order that entries are placed against the objectDefinitionSource is critical. + The FilterSecurityInterceptor will work from the top of the list down to the FIRST pattern that matches the request URL. + Accordingly, you should place MOST SPECIFIC (ie a/b/c/d.*) expressions first, with LEAST SPECIFIC (ie a/.*) expressions last + + + + + + + CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON + PATTERN_TYPE_APACHE_ANT + + + + + + + + + = + + + + + + + ROLE_ + + + + , + + + + + + + ROLE_ + + , + + + + diff --git a/core/src/test/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslatorTests.java b/core/src/test/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslatorTests.java new file mode 100644 index 0000000000..1c8625c0ac --- /dev/null +++ b/core/src/test/java/org/acegisecurity/util/WebXmlSecurityToSpringBeansTranslatorTests.java @@ -0,0 +1,59 @@ +package net.sf.acegisecurity.util; + +import junit.framework.TestCase; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.beans.factory.BeanFactory; + +import net.sf.acegisecurity.providers.ProviderManager; +import net.sf.acegisecurity.providers.dao.DaoAuthenticationProvider; +import net.sf.acegisecurity.providers.dao.memory.InMemoryDaoImpl; +import net.sf.acegisecurity.UserDetails; +import net.sf.acegisecurity.intercept.web.SecurityEnforcementFilter; + +import net.sf.acegisecurity.intercept.web.FilterSecurityInterceptor; + +/** + * Tests the WebXmlSecurityToSpringBeansTranslator by applying it + * to a test sample web.xml file. + * + * @author Luke Taylor + * @version $Id$ + */ +public class WebXmlSecurityToSpringBeansTranslatorTests extends TestCase { + + public void testFileTranslation() throws Exception { + WebXmlSecurityToSpringBeansTranslator t = new WebXmlSecurityToSpringBeansTranslator(); + + Resource r = new ClassPathResource("test-web.xml"); + t.translate(r.getInputStream()); + + BeanFactory bf = t.getBeanFactory(); + assertNotNull(bf.getBean("filterChainProxy")); + + ProviderManager pm = (ProviderManager) bf.getBean("authenticationManager"); + assertNotNull(pm); + assertEquals(3, pm.getProviders().size()); + + DaoAuthenticationProvider dap = + (DaoAuthenticationProvider) bf.getBean("daoAuthenticationProvider"); + assertNotNull(dap); + + InMemoryDaoImpl dao = (InMemoryDaoImpl) dap.getAuthenticationDao(); + UserDetails user = dao.loadUserByUsername("superuser"); + assertEquals("password",user.getPassword()); + assertEquals(2, user.getAuthorities().length); + assertNotNull(bf.getBean("anonymousProcessingFilter")); + assertNotNull(bf.getBean("anonymousAuthenticationProvider")); + assertNotNull(bf.getBean("httpSessionContextIntegrationFilter")); + assertNotNull(bf.getBean("rememberMeProcessingFilter")); + assertNotNull(bf.getBean("rememberMeAuthenticationProvider")); + + SecurityEnforcementFilter sef = + (SecurityEnforcementFilter) bf.getBean("securityEnforcementFilter"); + assertNotNull(sef); + assertNotNull(sef.getAuthenticationEntryPoint()); + FilterSecurityInterceptor fsi = sef.getFilterSecurityInterceptor(); + + } +} diff --git a/core/src/test/resources/test-web.xml b/core/src/test/resources/test-web.xml new file mode 100644 index 0000000000..0e7f2ffb12 --- /dev/null +++ b/core/src/test/resources/test-web.xml @@ -0,0 +1,54 @@ + + login-xml + + + index.jsp + index.html + + + + + /home.jsp + + + * + + + + + + /admin/* + + + admin + + + + + + /user/* + + + user + admin + + + + + form + + /login.jsp + /login.jsp?login_error=1 + + + + + + user + + + + admin + + + \ No newline at end of file