Author: jlaskowski Date: Wed Dec 15 16:21:38 2004 New Revision: 112258 URL: http://svn.apache.org/viewcvs?view=rev&rev=112258 Log: First attempt to handle "GERONIMO-313 JAAS Login from Tomcat Web Container"
Nothing changed yet from the end user perspective. Contribution of Jeff Genender Added: geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatContext.java geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatJAASRealm.java geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatSecureWebAppContext.java geronimo/trunk/modules/tomcat/src/test/ geronimo/trunk/modules/tomcat/src/test-resources/ geronimo/trunk/modules/tomcat/src/test-resources/data/ geronimo/trunk/modules/tomcat/src/test-resources/data/groups.properties geronimo/trunk/modules/tomcat/src/test-resources/data/login.config geronimo/trunk/modules/tomcat/src/test-resources/data/users.properties geronimo/trunk/modules/tomcat/src/test-resources/deployables/ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/WEB-INF/ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/WEB-INF/geronimo-web.xml geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/WEB-INF/web.xml geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/hello.txt geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/WEB-INF/ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/WEB-INF/geronimo-web.xml geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/WEB-INF/web.xml geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/auth/ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/auth/logon.html geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/auth/logonError.html geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/protected/ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/protected/hello.txt geronimo/trunk/modules/tomcat/src/test/org/ geronimo/trunk/modules/tomcat/src/test/org/apache/ geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/ geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/ geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/AbstractWebModuleTest.java geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/ApplicationTest.java geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/SecurityTest.java Modified: geronimo/trunk/modules/tomcat/maven.xml geronimo/trunk/modules/tomcat/project.properties geronimo/trunk/modules/tomcat/project.xml geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatContainer.java geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatWebAppContext.java Modified: geronimo/trunk/modules/tomcat/maven.xml Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/maven.xml?view=diff&rev=112258&p1=geronimo/trunk/modules/tomcat/maven.xml&r1=112257&p2=geronimo/trunk/modules/tomcat/maven.xml&r2=112258 ============================================================================== --- geronimo/trunk/modules/tomcat/maven.xml (original) +++ geronimo/trunk/modules/tomcat/maven.xml Wed Dec 15 16:21:38 2004 @@ -53,4 +53,25 @@ </preGoal> --> + <preGoal name="test:test"> + <mkdir dir="${maven.build.dir}/endorsed"/> + <mkdir dir="${maven.build.dir}/var"/> + <mkdir dir="${maven.build.dir}/var/catalina"/> + <mkdir dir="${maven.build.dir}/var/catalina/webapps"/> + <mkdir dir="${maven.build.dir}/var/catalina/conf"/> + <copy todir="${maven.build.dir}/var/catalina/conf" file="src/var/web.xml"/> + <copy todir="${maven.build.dir}/var/catalina/webapps"> + <fileset dir="src/test-resources/deployables"> + <include name="war1/**"/> + <include name="war3/**"/> + </fileset> + </copy> + + <j:forEach var="dep" items="${pom.dependencies}"> + <j:if test="${dep.artifactId.equals('xercesImpl') || dep.artifactId.equals('xml-apis')}"> + <copy file="${maven.repo.local}/${dep.groupId}/jars/${dep.artifact}" todir="${maven.build.dir}/endorsed"/> + </j:if> + </j:forEach> + </preGoal> + </project> Modified: geronimo/trunk/modules/tomcat/project.properties Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/project.properties?view=diff&rev=112258&p1=geronimo/trunk/modules/tomcat/project.properties&r1=112257&p2=geronimo/trunk/modules/tomcat/project.properties&r2=112258 ============================================================================== --- geronimo/trunk/modules/tomcat/project.properties (original) +++ geronimo/trunk/modules/tomcat/project.properties Wed Dec 15 16:21:38 2004 @@ -3,4 +3,5 @@ ## maven.repo.remote=http://www.apache.org/~jlaskowski/maven, http://www.ibiblio.org/maven -#maven.repo.remote=http://www.ibiblio.org/maven +maven.junit.jvmargs=-Djava.endorsed.dirs=${maven.build.dir}/endorsed -Djava.security.auth.login.config=src/test-resources/data/login.config +maven.junit.fork=true Modified: geronimo/trunk/modules/tomcat/project.xml Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/project.xml?view=diff&rev=112258&p1=geronimo/trunk/modules/tomcat/project.xml&r1=112257&p2=geronimo/trunk/modules/tomcat/project.xml&r2=112258 ============================================================================== --- geronimo/trunk/modules/tomcat/project.xml (original) +++ geronimo/trunk/modules/tomcat/project.xml Wed Dec 15 16:21:38 2004 @@ -41,7 +41,18 @@ <!-- ============ --> <dependencies> - <!-- temporary solution until appropriate xmlbeans code is ready --> + <!-- temporary solution until appropriate xmlbeans code is ready --> + <dependency> + <groupId>cglib</groupId> + <artifactId>cglib-full</artifactId> + <version>${cglib_version}</version> + <url>http://cglib.sf.net/</url> + </dependency> + <dependency> + <groupId>concurrent</groupId> + <artifactId>concurrent</artifactId> + <version>${concurrent_version}</version> + </dependency> <dependency> <groupId>geronimo</groupId> <artifactId>geronimo-jetty-builder</artifactId> @@ -67,6 +78,11 @@ </dependency> <dependency> <groupId>geronimo</groupId> + <artifactId>geronimo-connector</artifactId> + <version>${pom.currentVersion}</version> + </dependency> + <dependency> + <groupId>geronimo</groupId> <artifactId>geronimo-deployment</artifactId> <version>${pom.currentVersion}</version> </dependency> @@ -82,10 +98,20 @@ </dependency> <dependency> <groupId>geronimo</groupId> + <artifactId>geronimo-security</artifactId> + <version>${pom.currentVersion}</version> + </dependency> + <dependency> + <groupId>geronimo</groupId> <artifactId>geronimo-system</artifactId> <version>${pom.currentVersion}</version> </dependency> <dependency> + <groupId>geronimo</groupId> + <artifactId>geronimo-transaction</artifactId> + <version>${pom.currentVersion}</version> + </dependency> + <dependency> <groupId>geronimo-spec</groupId> <artifactId>geronimo-spec-j2ee</artifactId> <version>${geronimo_spec_j2ee_version}</version> @@ -209,6 +235,11 @@ <groupId>xerces</groupId> <artifactId>xmlParserAPIs</artifactId> <version>${xml_parser_apis_version}</version> + </dependency> + <dependency> + <groupId>xml-apis</groupId> + <artifactId>xml-apis</artifactId> + <version>${xml_apis_version}</version> </dependency> <dependency> <groupId>xmlbeans</groupId> Modified: geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatContainer.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatContainer.java?view=diff&rev=112258&p1=geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatContainer.java&r1=112257&p2=geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatContainer.java&r2=112258 ============================================================================== --- geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatContainer.java (original) +++ geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatContainer.java Wed Dec 15 16:21:38 2004 @@ -1,263 +1,274 @@ -/** - * - * Copyright 2003-2004 The Apache Software Foundation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.geronimo.tomcat; - -import org.apache.catalina.Context; -import org.apache.catalina.Engine; -import org.apache.catalina.Host; -import org.apache.catalina.connector.Connector; -import org.apache.catalina.core.StandardHost; -import org.apache.catalina.startup.Embedded; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.geronimo.gbean.GBeanInfo; -import org.apache.geronimo.gbean.GBeanInfoBuilder; -import org.apache.geronimo.gbean.GBeanLifecycle; - -/** - * Apache Tomcat GBean - * - * @see http://wiki.apache.org/geronimo/Tomcat - * @see http://nagoya.apache.org/jira/browse/GERONIMO-215 - * - * @version $Rev: 46019 $ $Date: 2004-09-14 11:56:06 +0200 (Tue, 14 Sep 2004) $ - */ -public class TomcatContainer implements GBeanLifecycle { - - private static final Log log = LogFactory.getLog(TomcatContainer.class); - - /** - * The default value of CATALINA_HOME variable - */ - private static final String DEFAULT_CATALINA_HOME = "var/catalina"; - - /** - * The default port the HTTP connector listens to - * - * TODO: Move it to another GBean, e.g. HTTPConnector - */ - private static final int DEFAULT_HTTP_CONNECTOR_PORT = 8090; - - /** - * Work directory - */ - private static final String WORK_DIR = "work"; - - /** - * Reference to the org.apache.catalina.Embedded embedded. - */ - private Embedded embedded; - - /** - * Tomcat Host that will contain deployed contexts (webapps) - */ - private Host host; - - /** - * Tomcat Engine that will contain the host - */ - private Engine engine; - - /** - * Tomcat Connector that will process requests - * - * TODO: Make it a GBean - */ - private Connector connector; - - /** - * Tomcat default Context - * - * TODO: Make it a gbean - */ - private Context defaultContext; - - /** - * The port Tomcat's HTTP Connector listens to - * - * TODO: Make it a part of the Listener GBean - */ - private int port; - - // Required as it's referenced by deployed webapps - public TomcatContainer(){ - setCatalinaHome(DEFAULT_CATALINA_HOME); - setPort(DEFAULT_HTTP_CONNECTOR_PORT); - } - - /** - * GBean constructor (invoked dynamically when the gbean is declared in a - * plan) - */ - public TomcatContainer(String catalinaHome, int port) { - setCatalinaHome(catalinaHome); - setPort(port); - } - - public void doFail() { - try { - doStop(); - } catch (Exception ignored) { - } - } - - /** - * Instantiate and start up Tomcat's Embedded class - * - * See org.apache.catalina.startup.Embedded for details (TODO: provide the - * link to the javadoc) - */ - public void doStart() throws Exception { - log.debug("doStart()"); - - // The comments are from the javadoc of the Embedded class - - // 1. Instantiate a new instance of this class. - if (embedded == null) { - embedded = new Embedded(); - } - - // Assemble FileLogger as a gbean - /* - * FileLogger fileLog = new FileLogger(); fileLog.setDirectory("."); - * fileLog.setPrefix("vsjMbedTC5"); fileLog.setSuffix(".log"); - * fileLog.setTimestamp(true); - */ - - // 2. Set the relevant properties of this object itself. In particular, - // you will want to establish the default Logger to be used, as well as - // the default Realm if you are using container-managed security. - embedded.setUseNaming(false); - - // 3. Call createEngine() to create an Engine object, and then call its - // property setters as desired. - engine = embedded.createEngine(); - engine.setName("tomcat.engine"); - engine.setDefaultHost("localhost"); - - // 4. Call createHost() to create at least one virtual Host associated - // with the newly created Engine, and then call its property setters as - // desired. After you customize this Host, add it to the corresponding - // Engine with engine.addChild(host). - host = embedded.createHost("localhost", ""); - // TODO: Make it the gbean's attribute or tomcatwebappcontext's one - ((StandardHost) host).setWorkDir(WORK_DIR); - - engine.addChild(host); - - // 5. Call createContext() to create at least one Context associated - // with each newly created Host, and then call its property setters as - // desired. You SHOULD create a Context with a pathname equal to a - // zero-length string, which will be used to process all requests not - // mapped to some other Context. After you customize this Context, add - // it to the corresponding Host with host.addChild(context). - // TODO: Make a default webapp configurable - another gbean? - defaultContext = embedded.createContext("", ""); - defaultContext.setParentClassLoader(this.getClass().getClassLoader()); - host.addChild(defaultContext); - - // 6. Call addEngine() to attach this Engine to the set of defined - // Engines for this object. - embedded.addEngine(engine); - - // 7. Call createConnector() to create at least one TCP/IP connector, - // and then call its property setters as desired. - - // It doesn't work - there's no HTTP connector created - // connector = embedded.createConnector((String) null, 8080, "http"); - - // Create an HTTP/1.1 connector manually - connector = new Connector("HTTP/1.1"); - connector.setPort(this.getPort()); - - // 8. Call addConnector() to attach this Connector to the set of defined - // Connectors for this object. The added Connector will use the most - // recently added Engine to process its received requests. - embedded.addConnector(connector); - - // 9. Call start() to initiate normal operations of all the attached - // components. - embedded.start(); - } - - public void doStop() throws Exception { - if (embedded != null) { - embedded.stop(); - embedded = null; - } - } - - /** - * Creates and adds the context to the running host - * - * It simply delegates the call to Tomcat's Embedded and Host classes - * - * @param ctx - * the context to be added - * - * @see org.apache.catalina.startup.Embedded - * @see org.apache.catalina.Host - */ - public void addContext(Context ctx) { - // TODO: Rethink what we're doing here - // The param - ctx - extends StandardContext, but at the same time we - // don't leverage it. - // TomcatContainer creates it again - so in fact there're two classes - // for the same thing. - // The question comes up what do we get from having the - // TomcatWebAppContext class extend Tomcat's StandardContext? - Context anotherCtxObj = embedded.createContext(ctx.getPath(), ctx.getDocBase()); - anotherCtxObj.setParentClassLoader(this.getClass().getClassLoader()); - host.addChild(anotherCtxObj); - } - - public void removeContext(Context ctx) { - embedded.removeContext(ctx); - } - - public void setCatalinaHome(String catalinaHome) { - System.setProperty("catalina.home", catalinaHome); - } - - public int getPort() { - return port; - } - - public void setPort(int port) { - this.port = port; - } - - public static final GBeanInfo GBEAN_INFO; - - static { - GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("Tomcat Web Container", TomcatContainer.class); - - infoFactory.setConstructor(new String[] { "catalinaHome", "port" }); - - infoFactory.addAttribute("catalinaHome", String.class, true); - infoFactory.addAttribute("port", int.class, true); - - infoFactory.addOperation("addContext", new Class[] { Context.class }); - infoFactory.addOperation("removeContext", new Class[] { Context.class }); - - GBEAN_INFO = infoFactory.getBeanInfo(); - } - - public static GBeanInfo getGBeanInfo() { - return GBEAN_INFO; - } +/** + * + * Copyright 2003-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.tomcat; + +import org.apache.catalina.Context; +import org.apache.catalina.Engine; +import org.apache.catalina.Host; +import org.apache.catalina.connector.Connector; +import org.apache.catalina.core.StandardHost; +import org.apache.catalina.startup.Embedded; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.gbean.GBeanLifecycle; + +/** + * Apache Tomcat GBean + * + * @see http://wiki.apache.org/geronimo/Tomcat + * @see http://nagoya.apache.org/jira/browse/GERONIMO-215 + * + * @version $Rev: 46019 $ $Date: 2004-09-14 11:56:06 +0200 (Tue, 14 Sep 2004) $ + */ +public class TomcatContainer implements GBeanLifecycle { + + private static final Log log = LogFactory.getLog(TomcatContainer.class); + + /** + * The default value of CATALINA_HOME variable + */ + private static final String DEFAULT_CATALINA_HOME = "var/catalina"; + + /** + * The default port the HTTP connector listens to + * + * TODO: Move it to another GBean, e.g. HTTPConnector + */ + private static final int DEFAULT_HTTP_CONNECTOR_PORT = 8090; + + /** + * Work directory + */ + private static final String WORK_DIR = "work"; + + /** + * Reference to the org.apache.catalina.Embedded embedded. + */ + private Embedded embedded; + + /** + * Tomcat Host that will contain deployed contexts (webapps) + */ + private Host host; + + /** + * Tomcat Engine that will contain the host + */ + private Engine engine; + + /** + * Tomcat Connector that will process requests + * + * TODO: Make it a GBean + */ + private Connector connector; + + /** + * Tomcat default Context + * + * TODO: Make it a gbean + */ + private Context defaultContext; + + /** + * The port Tomcat's HTTP Connector listens to + * + * TODO: Make it a part of the Listener GBean + */ + private int port; + + // Required as it's referenced by deployed webapps + public TomcatContainer() { + setCatalinaHome(DEFAULT_CATALINA_HOME); + setPort(DEFAULT_HTTP_CONNECTOR_PORT); + } + + /** + * GBean constructor (invoked dynamically when the gbean is declared in a + * plan) + */ + public TomcatContainer(String catalinaHome, int port) { + setCatalinaHome(catalinaHome); + setPort(port); + } + + public void doFail() { + try { + doStop(); + } catch (Exception ignored) { + } + } + + /** + * Instantiate and start up Tomcat's Embedded class + * + * See org.apache.catalina.startup.Embedded for details (TODO: provide the + * link to the javadoc) + */ + public void doStart() throws Exception { + log.debug("doStart()"); + + // The comments are from the javadoc of the Embedded class + + // 1. Instantiate a new instance of this class. + if (embedded == null) { + embedded = new Embedded(); + } + + // Assemble FileLogger as a gbean + /* + * FileLogger fileLog = new FileLogger(); fileLog.setDirectory("."); + * fileLog.setPrefix("vsjMbedTC5"); fileLog.setSuffix(".log"); + * fileLog.setTimestamp(true); + */ + + // 2. Set the relevant properties of this object itself. In particular, + // you will want to establish the default Logger to be used, as well as + // the default Realm if you are using container-managed security. + embedded.setUseNaming(false); + + // 3. Call createEngine() to create an Engine object, and then call its + // property setters as desired. + engine = embedded.createEngine(); + engine.setName("tomcat.engine"); + engine.setDefaultHost("localhost"); + + // Set a default realm for Geronimo, or Tomcat will use JAASRealm + // TomcatJAASRealm realm = new TomcatJAASRealm(); + // realm.setUserClassNames("org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal"); + // realm.setRoleClassNames("org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal"); + // engine.setRealm(realm); + + // 4. Call createHost() to create at least one virtual Host associated + // with the newly created Engine, and then call its property setters as + // desired. After you customize this Host, add it to the corresponding + // Engine with engine.addChild(host). + host = embedded.createHost("localhost", ""); + // TODO: Make it the gbean's attribute or tomcatwebappcontext's one + ((StandardHost) host).setWorkDir(WORK_DIR); + + engine.addChild(host); + + // 5. Call createContext() to create at least one Context associated + // with each newly created Host, and then call its property setters as + // desired. You SHOULD create a Context with a pathname equal to a + // zero-length string, which will be used to process all requests not + // mapped to some other Context. After you customize this Context, add + // it to the corresponding Host with host.addChild(context). + // TODO: Make a default webapp configurable - another gbean? + defaultContext = embedded.createContext("", ""); + defaultContext.setParentClassLoader(this.getClass().getClassLoader()); + host.addChild(defaultContext); + + // 6. Call addEngine() to attach this Engine to the set of defined + // Engines for this object. + embedded.addEngine(engine); + + // 7. Call createConnector() to create at least one TCP/IP connector, + // and then call its property setters as desired. + + // It doesn't work - there's no HTTP connector created + // connector = embedded.createConnector((String) null, 8080, "http"); + + // Create an HTTP/1.1 connector manually + connector = new Connector("HTTP/1.1"); + connector.setPort(this.getPort()); + + // 8. Call addConnector() to attach this Connector to the set of defined + // Connectors for this object. The added Connector will use the most + // recently added Engine to process its received requests. + embedded.addConnector(connector); + + // 9. Call start() to initiate normal operations of all the attached + // components. + embedded.start(); + } + + public void doStop() throws Exception { + if (embedded != null) { + embedded.stop(); + embedded = null; + } + } + + /** + * Creates and adds the context to the running host + * + * It simply delegates the call to Tomcat's Embedded and Host classes + * + * @param ctx + * the context to be added + * + * @see org.apache.catalina.startup.Embedded + * @see org.apache.catalina.Host + */ + public void addContext(TomcatContext ctx) { + Context anotherCtxObj = embedded.createContext(ctx.getPath(), ctx.getDocBase()); + anotherCtxObj.setParentClassLoader(this.getClass().getClassLoader()); + + // Set the context for thew Tomcat implementation + ctx.setContext(anotherCtxObj); + + // Have the context to set its properties + ctx.setContextProperties(); + + host.addChild(anotherCtxObj); + } + + public void removeContext(TomcatContext ctx) { + Context context = ctx.getContext(); + + if (context != null) + embedded.removeContext(context); + + ctx.setContext(null); + } + + public void setCatalinaHome(String catalinaHome) { + System.setProperty("catalina.home", catalinaHome); + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; + } + + public static final GBeanInfo GBEAN_INFO; + + static { + GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("Tomcat Web Container", TomcatContainer.class); + + infoFactory.setConstructor(new String[] { "catalinaHome", "port" }); + + infoFactory.addAttribute("catalinaHome", String.class, true); + infoFactory.addAttribute("port", int.class, true); + + infoFactory.addOperation("addContext", new Class[] { TomcatContext.class }); + infoFactory.addOperation("removeContext", new Class[] { TomcatContext.class }); + + GBEAN_INFO = infoFactory.getBeanInfo(); + } + + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } } Added: geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatContext.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatContext.java?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatContext.java Wed Dec 15 16:21:38 2004 @@ -0,0 +1,34 @@ +/** + * + * Copyright 2003-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.tomcat; + +import org.apache.catalina.Context; + +/** + * @version $Rev: 106522 $ $Date: 2004-11-25 01:28:57 +0100 (Thu, 25 Nov 2004) $ + */ +public interface TomcatContext { + public void setContextProperties(); + + public String getPath(); + + public void setContext(Context ctx); + + public Context getContext(); + + public String getDocBase(); +} Added: geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatJAASRealm.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatJAASRealm.java?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatJAASRealm.java Wed Dec 15 16:21:38 2004 @@ -0,0 +1,157 @@ +/** + * + * Copyright 2003-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.tomcat; + +import java.security.Principal; + +import javax.security.auth.Subject; +import javax.security.auth.login.AccountExpiredException; +import javax.security.auth.login.CredentialExpiredException; +import javax.security.auth.login.FailedLoginException; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +import org.apache.catalina.realm.JAASCallbackHandler; +import org.apache.catalina.realm.JAASRealm; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.geronimo.security.ContextManager; + +/** + * @version $Rev: 106522 $ $Date: 2004-11-25 01:28:57 +0100 (Thu, 25 Nov 2004) $ + */ +public class TomcatJAASRealm extends JAASRealm { + private static Log log = LogFactory.getLog(TomcatJAASRealm.class); + + /** + * Descriptive information about this <code>Realm</code> implementation. + */ + protected static final String info = "org.apache.geronimo.tomcat.TomcatJAASRealm/1.0"; + + /** + * Descriptive information about this <code>Realm</code> implementation. + */ + protected static final String name = "TomcatJAASRealm"; + + /** + * Return the <code>Principal</code> associated with the specified + * username and credentials, if there is one; otherwise return + * <code>null</code>. + * + * If there are any errors with the JDBC connection, executing the query or + * anything we return null (don't authenticate). This event is also logged, + * and the connection will be closed so that a subsequent request will + * automatically re-open it. + * + * @param username + * Username of the <code>Principal</code> to look up + * @param credentials + * Password or other credentials to use in authenticating this + * username + */ + public Principal authenticate(String username, String credentials) { + + // Establish a LoginContext to use for authentication + try { + LoginContext loginContext = null; + if (appName == null) + appName = "Tomcat"; + + if (log.isDebugEnabled()) + log.debug(sm.getString("jaasRealm.beginLogin", username, appName)); + + // What if the LoginModule is in the container class loader ? + ClassLoader ocl = null; + + if (isUseContextClassLoader()) { + ocl = Thread.currentThread().getContextClassLoader(); + Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader()); + } + + try { + loginContext = new LoginContext(appName, new JAASCallbackHandler(this, username, credentials)); + } catch (Throwable e) { + log.error(sm.getString("jaasRealm.unexpectedError"), e); + return (null); + } finally { + if (isUseContextClassLoader()) { + Thread.currentThread().setContextClassLoader(ocl); + } + } + + if (log.isDebugEnabled()) + log.debug("Login context created " + username); + + // Negotiate a login via this LoginContext + Subject subject = null; + try { + loginContext.login(); + Subject tempSubject = loginContext.getSubject(); + if (tempSubject == null) { + if (log.isDebugEnabled()) + log.debug(sm.getString("jaasRealm.failedLogin", username)); + return (null); + } + + subject = ContextManager.getServerSideSubject(tempSubject); + if (subject == null) { + if (log.isDebugEnabled()) + log.debug(sm.getString("jaasRealm.failedLogin", username)); + return (null); + } + + } catch (AccountExpiredException e) { + if (log.isDebugEnabled()) + log.debug(sm.getString("jaasRealm.accountExpired", username)); + return (null); + } catch (CredentialExpiredException e) { + if (log.isDebugEnabled()) + log.debug(sm.getString("jaasRealm.credentialExpired", username)); + return (null); + } catch (FailedLoginException e) { + if (log.isDebugEnabled()) + log.debug(sm.getString("jaasRealm.failedLogin", username)); + return (null); + } catch (LoginException e) { + log.warn(sm.getString("jaasRealm.loginException", username), e); + return (null); + } catch (Throwable e) { + log.error(sm.getString("jaasRealm.unexpectedError"), e); + return (null); + } + + if (log.isDebugEnabled()) + log.debug(sm.getString("jaasRealm.loginContextCreated", username)); + + // Return the appropriate Principal for this authenticated Subject + Principal principal = createPrincipal(username, subject); + if (principal == null) { + log.debug(sm.getString("jaasRealm.authenticateFailure", username)); + return (null); + } + if (log.isDebugEnabled()) { + log.debug(sm.getString("jaasRealm.authenticateSuccess", username)); + } + + return (principal); + } catch (Throwable t) { + log.error("error ", t); + return null; + } + } + +} Added: geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatSecureWebAppContext.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatSecureWebAppContext.java?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatSecureWebAppContext.java Wed Dec 15 16:21:38 2004 @@ -0,0 +1,155 @@ +/** + * + * Copyright 2003-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.tomcat; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; + +import org.apache.catalina.Realm; +import org.apache.catalina.deploy.LoginConfig; +import org.apache.catalina.deploy.SecurityConstraint; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.geronimo.gbean.GBeanInfo; +import org.apache.geronimo.gbean.GBeanInfoBuilder; +import org.apache.geronimo.gbean.GBeanLifecycle; +import org.apache.geronimo.gbean.WaitingException; + +/** + * Wrapper for a WebApplicationContext that sets up its J2EE environment. + * + * @version $Rev: 56022 $ $Date: 2004-10-30 07:16:18 +0200 (Sat, 30 Oct 2004) $ + */ +public class TomcatSecureWebAppContext extends TomcatWebAppContext implements GBeanLifecycle { + + private static Log log = LogFactory.getLog(org.apache.geronimo.tomcat.TomcatSecureWebAppContext.class); + + private LoginConfig loginConfig = null; + + private String authMethod = null; + + private String realmName = null; + + private String loginPage = null; + + private String errorPage = null; + + private Realm tomcatRealm = null; + + private SecurityConstraint[] securityConstraints = null; + + private String[] securityRoles = null; + + public TomcatSecureWebAppContext(URI webAppRoot, URI[] webClassPath, URL configurationBaseUrl, String authMethod, + String realmName, String loginPage, String errorPage, Realm tomcatRealm, + SecurityConstraint[] securityConstraints, String[] securityRoles, TomcatContainer container) + throws MalformedURLException { + + super(webAppRoot, webClassPath, configurationBaseUrl, container); + + assert authMethod != null; + assert realmName != null; + assert loginPage != null; + assert errorPage != null; + assert tomcatRealm != null; + assert securityConstraints != null; + assert securityRoles != null; + + this.authMethod = authMethod; + this.realmName = realmName; + this.loginPage = loginPage; + this.errorPage = errorPage; + this.tomcatRealm = tomcatRealm; + this.securityConstraints = securityConstraints; + this.securityRoles = securityRoles; + + loginConfig = new LoginConfig(); + loginConfig.setAuthMethod(authMethod); + loginConfig.setRealmName(realmName); + loginConfig.setLoginPage(loginPage); + loginConfig.setErrorPage(errorPage); + + } + + public void setContextProperties() { + super.setContextProperties(); + context.setRealm(tomcatRealm); + context.setLoginConfig(loginConfig); + + // Add the security constraints + for (int i = 0; i < securityConstraints.length; i++) { + SecurityConstraint sc = securityConstraints[i]; + context.addConstraint(sc); + } + + // Add the security roles + for (int i = 0; i < securityRoles.length; i++) { + context.addSecurityRole(securityRoles[i]); + } + } + + public void doStart() throws WaitingException, Exception { + + super.doStart(); + log.info("TomcatSecureWebAppContext started"); + } + + public void doStop() throws Exception { + super.doStop(); + log.info("TomcatSecureWebAppContext stopped"); + } + + public void doFail() { + super.doFail(); + log.info("TomcatSecureWebAppContext failed"); + } + + public static final GBeanInfo GBEAN_INFO; + + static { + GBeanInfoBuilder infoFactory = new GBeanInfoBuilder("Tomcat Secure WebApplication Context", + org.apache.geronimo.tomcat.TomcatSecureWebAppContext.class); + + infoFactory.addAttribute("webAppRoot", URI.class, true); + infoFactory.addAttribute("webClassPath", URI[].class, true); + infoFactory.addAttribute("configurationBaseUrl", URL.class, true); + + infoFactory.addAttribute("path", String.class, true); + + infoFactory.addAttribute("authMethod", String.class, true); + infoFactory.addAttribute("realmName", String.class, true); + infoFactory.addAttribute("loginPage", String.class, true); + infoFactory.addAttribute("errorPage", String.class, true); + + infoFactory.addAttribute("tomcatRealm", Realm.class, true); + infoFactory.addAttribute("securityConstraints", SecurityConstraint[].class, true); + infoFactory.addAttribute("securityRoles", String[].class, true); + + infoFactory.addReference("Container", TomcatContainer.class); + + infoFactory.setConstructor(new String[] { "webAppRoot", "webClassPath", "configurationBaseUrl", "authMethod", + "realmName", "loginPage", "errorPage", "tomcatRealm", "securityConstraints", "securityRoles", + "Container" }); + + GBEAN_INFO = infoFactory.getBeanInfo(); + } + + public static GBeanInfo getGBeanInfo() { + return GBEAN_INFO; + } +} Modified: geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatWebAppContext.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatWebAppContext.java?view=diff&rev=112258&p1=geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatWebAppContext.java&r1=112257&p2=geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatWebAppContext.java&r2=112258 ============================================================================== --- geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatWebAppContext.java (original) +++ geronimo/trunk/modules/tomcat/src/java/org/apache/geronimo/tomcat/TomcatWebAppContext.java Wed Dec 15 16:21:38 2004 @@ -21,8 +21,7 @@ import java.net.URI; import java.net.URL; -import org.apache.catalina.LifecycleException; -import org.apache.catalina.core.StandardContext; +import org.apache.catalina.Context; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.geronimo.gbean.GBeanInfo; @@ -35,14 +34,20 @@ * * @version $Rev: 56022 $ $Date: 2004-10-30 07:16:18 +0200 (Sat, 30 Oct 2004) $ */ -public class TomcatWebAppContext extends StandardContext implements GBeanLifecycle { +public class TomcatWebAppContext implements GBeanLifecycle, TomcatContext { private static Log log = LogFactory.getLog(TomcatWebAppContext.class); - private final TomcatContainer container; + protected final TomcatContainer container; + + protected Context context = null; private final URI webAppRoot; + private String path = null; + + private String docBase = null; + public TomcatWebAppContext(URI webAppRoot, URI[] webClassPath, URL configurationBaseUrl, TomcatContainer container) throws MalformedURLException { @@ -57,6 +62,35 @@ this.setDocBase(this.webAppRoot.getPath()); } + public String getDocBase() { + return docBase; + } + + public void setDocBase(String docBase) { + this.docBase = docBase; + } + + public void setContextProperties() { + context.setDocBase(webAppRoot.getPath()); + context.setPath(path); + } + + public Context getContext() { + return context; + } + + public void setContext(Context context) { + this.context = context; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + public void doStart() throws WaitingException, Exception { // See the note of TomcatContainer::addContext @@ -68,18 +102,12 @@ } public void doStop() throws Exception { - super.stop(); container.removeContext(this); log.info("TomcatWebAppContext stopped"); } public void doFail() { - try { - super.stop(); - } catch (LifecycleException e) { - } - container.removeContext(this); log.info("TomcatWebAppContext failed"); } @@ -97,7 +125,7 @@ infoFactory.addReference("Container", TomcatContainer.class); - infoFactory.setConstructor(new String[] { "webAppRoot", "webClassPath", "configurationBaseUrl", "Container", }); + infoFactory.setConstructor(new String[] { "webAppRoot", "webClassPath", "configurationBaseUrl", "Container" }); GBEAN_INFO = infoFactory.getBeanInfo(); } Added: geronimo/trunk/modules/tomcat/src/test-resources/data/groups.properties Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test-resources/data/groups.properties?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test-resources/data/groups.properties Wed Dec 15 16:21:38 2004 @@ -0,0 +1,23 @@ +## +## +## Copyright 2004 The Apache Software Foundation +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +manager=izumi +it=alan +pet=george,gracie,metro +dog=george,gracie +cat=metro +auto-administrator=izumi Added: geronimo/trunk/modules/tomcat/src/test-resources/data/login.config Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test-resources/data/login.config?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test-resources/data/login.config Wed Dec 15 16:21:38 2004 @@ -0,0 +1,5 @@ +securetest { + org.apache.geronimo.security.jaas.JaasLoginCoordinator required + realm="demo-properties-realm" + kernel="test.kernel"; +}; Added: geronimo/trunk/modules/tomcat/src/test-resources/data/users.properties Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test-resources/data/users.properties?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test-resources/data/users.properties Wed Dec 15 16:21:38 2004 @@ -0,0 +1,22 @@ +## +## +## Copyright 2004 The Apache Software Foundation +## +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +izumi=violin +alan=starcraft +george=bone +gracie=biscuit +metro=mouse \ No newline at end of file Added: geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/WEB-INF/geronimo-web.xml Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/WEB-INF/geronimo-web.xml?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/WEB-INF/geronimo-web.xml Wed Dec 15 16:21:38 2004 @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright 2004 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<tomcat:web-app + xmlns:tomcat="http://geronimo.apache.org/xml/ns/web/tomcat" + configId="org/apache/geronimo/tomcat/Test" + > + <tomcat:context-root>/test</tomcat:context-root> + <tomcat:context-priority-classloader>false</tomcat:context-priority-classloader> + <!-- + <jetty:security> + <sec:default-principal realm-name="foo"> + <sec:principal class="org.apache.geronimo.security.DefaultPrincipal" + name="bar"/> + </sec:default-principal> + </jetty:security> + --> +</tomcat:web-app> Added: geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/WEB-INF/web.xml Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/WEB-INF/web.xml?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/WEB-INF/web.xml Wed Dec 15 16:21:38 2004 @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright 2004 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> + +<web-app> + <description>Test Web Deployment</description> + <resource-env-ref> + <resource-env-ref-name>fake-resource-env-ref</resource-env-ref-name> + <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type> + </resource-env-ref> + <resource-ref> + <res-ref-name>fake-resource-ref</res-ref-name> + <res-type>javax.sql.DataSource</res-type> + <res-auth>Container</res-auth> + <res-sharing-scope>Shareable</res-sharing-scope> + </resource-ref> + <ejb-ref> + <ejb-ref-name>fake-ejb-ref</ejb-ref-name> + <ejb-ref-type>Entity</ejb-ref-type> + <home>some.package.FakeHome</home> + <remote>some.package.Fake</remote> + </ejb-ref> + <ejb-ref> + <ejb-ref-name>another-ejb-ref</ejb-ref-name> + <ejb-ref-type>Entity</ejb-ref-type> + <home>some.package.FakeHome</home> + <remote>some.package.Fake</remote> + </ejb-ref> + <ejb-local-ref> + <ejb-ref-name>fake-ejb-local-ref</ejb-ref-name> + <ejb-ref-type>Entity</ejb-ref-type> + <local-home>some.package.FakeLocalHome</local-home> + <local>some.package.FakeLocal</local> + </ejb-local-ref> + <ejb-local-ref> + <ejb-ref-name>another-ejb-local-ref</ejb-ref-name> + <ejb-ref-type>Entity</ejb-ref-type> + <local-home>some.package.FakeLocalHome</local-home> + <local>some.package.FakeLocal</local> + </ejb-local-ref> +<!-- <service-ref>--> +<!-- <service-ref-name>fake-service-ref</service-ref-name>--> +<!-- <service-interface>some.package.FakeService</service-interface>--> +<!-- </service-ref>--> +</web-app> \ No newline at end of file Added: geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/hello.txt Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/hello.txt?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war1/hello.txt Wed Dec 15 16:21:38 2004 @@ -0,0 +1 @@ +Hello World Added: geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/WEB-INF/geronimo-web.xml Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/WEB-INF/geronimo-web.xml?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/WEB-INF/geronimo-web.xml Wed Dec 15 16:21:38 2004 @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright 2004 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<web-app + xmlns="http://geronimo.apache.org/xml/ns/web/jetty" + xmlns:sec="http://geronimo.apache.org/xml/ns/security" + configId="org/apache/geronimo/test"> + + <context-root>/test</context-root> + <context-priority-classloader>false</context-priority-classloader> + <sec:security> + <sec:default-principal realm-name="demo-properties-realm"> + <sec:principal class="org.apache.geronimo.security.realm.providers.PropertiesFileUserPrincipal" name="metro"/> + </sec:default-principal> + </sec:security> +</web-app> Added: geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/WEB-INF/web.xml Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/WEB-INF/web.xml?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/WEB-INF/web.xml Wed Dec 15 16:21:38 2004 @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright 2004 The Apache Software Foundation + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> + +<web-app> + <description>Test Web Deployment</description> + <resource-env-ref> + <resource-env-ref-name>fake-resource-env-ref</resource-env-ref-name> + <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type> + </resource-env-ref> + <resource-ref> + <res-ref-name>fake-resource-ref</res-ref-name> + <res-type>javax.sql.DataSource</res-type> + <res-auth>Container</res-auth> + <res-sharing-scope>Shareable</res-sharing-scope> + </resource-ref> + + <security-constraint> + <web-resource-collection> + <web-resource-name>Admin Role</web-resource-name> + <url-pattern>/protected/*</url-pattern> + </web-resource-collection> + <auth-constraint> + <role-name>content-administrator</role-name> + <role-name>auto-administrator</role-name> --> + </auth-constraint> + </security-constraint> + + <security-constraint> + <web-resource-collection> + <web-resource-name>NO ACCESS</web-resource-name> + <url-pattern>/auth/logon.html</url-pattern> + </web-resource-collection> + <auth-constraint/> + </security-constraint> + + <login-config> + <auth-method>FORM</auth-method> + <realm-name>Test JAAS Realm</realm-name> + <form-login-config> + <form-login-page>/auth/logon.html?param=test</form-login-page> + <form-error-page>/auth/logonError.html?param=test</form-error-page> + </form-login-config> + </login-config> + + <!-- SECURITY ROLES --> + + <security-role> + <role-name>content-administrator</role-name> + </security-role> + + <security-role> + <role-name>auto-administrator</role-name> + </security-role> + + <ejb-ref> + <ejb-ref-name>fake-ejb-ref</ejb-ref-name> + <ejb-ref-type>Entity</ejb-ref-type> + <home>some.package.FakeHome</home> + <remote>some.package.Fake</remote> + </ejb-ref> + <ejb-ref> + <ejb-ref-name>another-ejb-ref</ejb-ref-name> + <ejb-ref-type>Entity</ejb-ref-type> + <home>some.package.FakeHome</home> + <remote>some.package.Fake</remote> + </ejb-ref> + <ejb-local-ref> + <ejb-ref-name>fake-ejb-local-ref</ejb-ref-name> + <ejb-ref-type>Entity</ejb-ref-type> + <local-home>some.package.FakeLocalHome</local-home> + <local>some.package.FakeLocal</local> + </ejb-local-ref> + <ejb-local-ref> + <ejb-ref-name>another-ejb-local-ref</ejb-ref-name> + <ejb-ref-type>Entity</ejb-ref-type> + <local-home>some.package.FakeLocalHome</local-home> + <local>some.package.FakeLocal</local> + </ejb-local-ref> + +</web-app> \ No newline at end of file Added: geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/auth/logon.html Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/auth/logon.html?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/auth/logon.html Wed Dec 15 16:21:38 2004 @@ -0,0 +1,21 @@ +<!-- Login Page --> +<HTML> +<H1>FORM Authentication demo</H1> +<form method="POST" action="j_security_check"> +<table border="0" cellspacing="2" cellpadding="1"> +<tr> + <td>Username:</td> + <td><input size="12" value="" name="j_username" maxlength="25" type="text"></td> +</tr> +<tr> + <td>Password:</td> + <td><input size="12" value="" name="j_password" maxlength="25" type="password"></td> +</tr> +<tr> + <td colspan="2" align="center"> + <input name="submit" type="submit" value="Login"> + </td> +</tr> +</table> +</form> +</HTML> Added: geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/auth/logonError.html Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/auth/logonError.html?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/auth/logonError.html Wed Dec 15 16:21:38 2004 @@ -0,0 +1,6 @@ +<!-- Not Authorized --> +<HTML> +<H1>Authentication ERROR</H1> +Username, password or role incorrect. + +</HTML> \ No newline at end of file Added: geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/protected/hello.txt Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/protected/hello.txt?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test-resources/deployables/war3/protected/hello.txt Wed Dec 15 16:21:38 2004 @@ -0,0 +1 @@ +Hello World Added: geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/AbstractWebModuleTest.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/AbstractWebModuleTest.java?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/AbstractWebModuleTest.java Wed Dec 15 16:21:38 2004 @@ -0,0 +1,270 @@ +/** + * + * Copyright 2003-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.tomcat; + +import java.io.File; +import java.net.URI; +import java.util.Collections; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +import javax.management.ObjectName; + +import junit.framework.TestCase; + +import org.apache.catalina.deploy.SecurityConstraint; +import org.apache.geronimo.connector.outbound.connectiontracking.ConnectionTrackingCoordinator; +import org.apache.geronimo.gbean.GBeanData; +import org.apache.geronimo.j2ee.j2eeobjectnames.J2eeContext; +import org.apache.geronimo.j2ee.j2eeobjectnames.J2eeContextImpl; +import org.apache.geronimo.j2ee.j2eeobjectnames.NameFactory; +import org.apache.geronimo.kernel.Kernel; +import org.apache.geronimo.kernel.management.State; +import org.apache.geronimo.security.SecurityServiceImpl; +import org.apache.geronimo.security.jaas.JaasLoginService; +import org.apache.geronimo.security.jaas.LoginModuleGBean; +import org.apache.geronimo.security.realm.GenericSecurityRealm; +import org.apache.geronimo.system.serverinfo.ServerInfo; +import org.apache.geronimo.transaction.context.TransactionContextManager; +import org.apache.geronimo.transaction.manager.TransactionManagerImpl; + +/** + * @version $Rev: 111239 $ $Date: 2004-12-08 02:29:11 -0700 (Wed, 08 Dec 2004) $ + */ +public class AbstractWebModuleTest extends TestCase { + protected Kernel kernel; + + private GBeanData container; + + private ObjectName containerName; + + private ObjectName connectorName; + + private GBeanData connector; + + private ObjectName webModuleName; + + private ObjectName tmName; + + private ObjectName ctcName; + + private GBeanData tm; + + private GBeanData ctc; + + private ObjectName tcmName; + + private GBeanData tcm; + + private ClassLoader cl; + + private J2eeContext moduleContext = new J2eeContextImpl("tomcat.test", "test", "null", "tomcatTest", null, null); + + private GBeanData securityServiceGBean; + + protected ObjectName securityServiceName; + + private ObjectName loginServiceName; + + private GBeanData loginServiceGBean; + + protected GBeanData propertiesLMGBean; + + protected ObjectName propertiesLMName; + + private ObjectName propertiesRealmName; + + private GBeanData propertiesRealmGBean; + + private ObjectName serverInfoName; + + private GBeanData serverInfoGBean; + + public void testDummy() throws Exception { + } + + protected void setUpInsecureAppContext() throws Exception { + + GBeanData app = new GBeanData(webModuleName, TomcatWebAppContext.GBEAN_INFO); + // GBeanData app = new GBeanData(webModuleName, + // TomcatWebAppContext.GBEAN_INFO); + app.setAttribute("webAppRoot", new File("target/var/catalina/webapps/war1/").toURI()); + // app.setAttribute("componentContext", null); + // OnlineUserTransaction userTransaction = new OnlineUserTransaction(); + // app.setAttribute("userTransaction", userTransaction); + // we have no classes or libs. + app.setAttribute("webClassPath", new URI[] {}); + // app.setAttribute("contextPriorityClassLoader", Boolean.FALSE); + app.setAttribute("configurationBaseUrl", new File("target/var/catalina/webapps/war1/WEB-INF/web.xml").toURL()); + // app.setReferencePattern("TransactionContextManager", tcmName); + // app.setReferencePattern("TrackedConnectionAssociator", ctcName); + app.setReferencePattern("Container", containerName); + + // app.setAttribute("contextPath", "/test"); + app.setAttribute("path", "/test"); + + start(app); + } + + // protected void setUpSecureAppContext(Security securityConfig, Set + // uncheckedPermissions, Set excludedPermissions, Map rolePermissions, Set + // securityRoles, Map legacySecurityConstraintMap) throws Exception { + protected ObjectName setUpSecureAppContext(SecurityConstraint[] securityConstraints, String[] securityRoles) + throws Exception { + GBeanData app = new GBeanData(webModuleName, TomcatSecureWebAppContext.GBEAN_INFO); + app.setAttribute("webAppRoot", new File("target/var/catalina/webapps/war3/").toURI()); + app.setAttribute("webClassPath", new URI[] {}); + app.setAttribute("configurationBaseUrl", new File("target/var/catalina/webapps/war3/WEB-INF/web.xml").toURL()); + app.setAttribute("path", "/securetest"); + app.setAttribute("authMethod", "FORM"); + app.setAttribute("realmName", "Test JAAS Realm"); + app.setAttribute("loginPage", "/auth/logon.html?param=test"); + app.setAttribute("errorPage", "/auth/logonError.html?param=test"); + + app.setAttribute("securityConstraints", securityConstraints); + app.setAttribute("securityRoles", securityRoles); + + TomcatJAASRealm realm = new TomcatJAASRealm(); + realm.setUserClassNames("org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal"); + realm.setRoleClassNames("org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal"); + app.setAttribute("tomcatRealm", realm); + + app.setReferencePattern("Container", containerName); + start(app); + + return webModuleName; + } + + protected void setUpSecurity() throws Exception { + securityServiceName = new ObjectName("geronimo.security:type=SecurityService"); + securityServiceGBean = new GBeanData(securityServiceName, SecurityServiceImpl.GBEAN_INFO); + securityServiceGBean.setReferencePatterns("Realms", Collections.singleton(new ObjectName( + "geronimo.security:type=SecurityRealm,*"))); + securityServiceGBean.setReferencePatterns("Mappers", Collections.singleton(new ObjectName( + "geronimo.security:type=SecurityRealm,*"))); + securityServiceGBean.setAttribute("policyConfigurationFactory", + "org.apache.geronimo.security.jacc.GeronimoPolicyConfigurationFactory"); + + loginServiceName = new ObjectName("geronimo.security:type=JaasLoginService"); + loginServiceGBean = new GBeanData(loginServiceName, JaasLoginService.GBEAN_INFO); + loginServiceGBean.setReferencePatterns("Realms", Collections.singleton(new ObjectName( + "geronimo.security:type=SecurityRealm,*"))); + // loginServiceGBean.setAttribute("reclaimPeriod", new Long(1000 * + // 1000)); + loginServiceGBean.setAttribute("algorithm", "HmacSHA1"); + loginServiceGBean.setAttribute("password", "secret"); + + serverInfoName = new ObjectName("geronimo.system:role=ServerInfo"); + serverInfoGBean = new GBeanData(serverInfoName, ServerInfo.GBEAN_INFO); + serverInfoGBean.setAttribute("baseDirectory", "."); + + propertiesLMName = new ObjectName("geronimo.security:type=LoginModule,name=demo-properties-login"); + propertiesLMGBean = new GBeanData(propertiesLMName, LoginModuleGBean.GBEAN_INFO); + propertiesLMGBean.setAttribute("loginModuleClass", + "org.apache.geronimo.security.realm.providers.PropertiesFileLoginModule"); + propertiesLMGBean.setAttribute("serverSide", Boolean.TRUE); + Properties options = new Properties(); + options.setProperty("usersURI", "src/test-resources/data/users.properties"); + options.setProperty("groupsURI", "src/test-resources/data/groups.properties"); + propertiesLMGBean.setAttribute("options", options); + propertiesLMGBean.setAttribute("loginDomainName", "demo-properties-realm"); + + propertiesRealmName = new ObjectName("geronimo.security:type=SecurityRealm,realm=demo-properties-realm"); + propertiesRealmGBean = new GBeanData(propertiesRealmName, GenericSecurityRealm.GBEAN_INFO); + propertiesRealmGBean.setReferencePatterns("ServerInfo", Collections.singleton(serverInfoName)); + propertiesRealmGBean.setAttribute("realmName", "demo-properties-realm"); + Properties config = new Properties(); + config.setProperty("LoginModule.1.REQUIRED", propertiesLMName.getCanonicalName()); + propertiesRealmGBean.setAttribute("loginModuleConfiguration", config); + // propertiesRealmGBean.setAttribute("autoMapPrincipalClasses", + // "org.apache.geronimo.security.realm.providers.PropertiesFileGroupPrincipal"); + propertiesRealmGBean.setAttribute("defaultPrincipal", + "metro=org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal"); + + start(securityServiceGBean); + start(loginServiceGBean); + start(serverInfoGBean); + start(propertiesLMGBean); + start(propertiesRealmGBean); + + } + + protected void tearDownSecurity() throws Exception { + stop(propertiesRealmName); + stop(propertiesLMName); + stop(serverInfoName); + stop(loginServiceName); + stop(securityServiceName); + } + + private void start(GBeanData gbeanData) throws Exception { + kernel.loadGBean(gbeanData, cl); + kernel.startGBean(gbeanData.getName()); + if (((Integer) kernel.getAttribute(gbeanData.getName(), "state")).intValue() != State.RUNNING_INDEX) { + fail("gbean not started: " + gbeanData.getName()); + } + } + + protected void stop(ObjectName name) throws Exception { + kernel.stopGBean(name); + kernel.unloadGBean(name); + } + + protected void setUp() throws Exception { + cl = this.getClass().getClassLoader(); + containerName = NameFactory.getWebComponentName(null, null, null, null, "tomcatContainer", "WebResource", + moduleContext); + webModuleName = NameFactory.getWebComponentName(null, null, null, null, NameFactory.WEB_MODULE, "WebResource", + moduleContext); + + tmName = NameFactory + .getComponentName(null, null, "TransactionManager", NameFactory.JTA_RESOURCE, moduleContext); + tcmName = NameFactory.getComponentName(null, null, "TransactionContextManager", NameFactory.JTA_RESOURCE, + moduleContext); + ctcName = new ObjectName("geronimo.test:role=ConnectionTrackingCoordinator"); + + kernel = new Kernel("test.kernel"); + kernel.boot(); + + // Need to override the constructor for unit tests + container = new GBeanData(containerName, TomcatContainer.GBEAN_INFO); + container.setAttribute("catalinaHome", "target/var/catalina"); + container.setAttribute("port", new Integer(8080)); + + start(container); + + tm = new GBeanData(tmName, TransactionManagerImpl.GBEAN_INFO); + Set patterns = new HashSet(); + patterns.add(ObjectName.getInstance("geronimo.server:j2eeType=JCAManagedConnectionFactory,*")); + tm.setAttribute("defaultTransactionTimeoutSeconds", new Integer(10)); + tm.setReferencePatterns("ResourceManagers", patterns); + start(tm); + tcm = new GBeanData(tcmName, TransactionContextManager.GBEAN_INFO); + tcm.setReferencePattern("TransactionManager", tmName); + start(tcm); + ctc = new GBeanData(ctcName, ConnectionTrackingCoordinator.GBEAN_INFO); + start(ctc); + } + + protected void tearDown() throws Exception { + stop(ctcName); + stop(tmName); + stop(containerName); + kernel.shutdown(); + } +} Added: geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/ApplicationTest.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/ApplicationTest.java?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/ApplicationTest.java Wed Dec 15 16:21:38 2004 @@ -0,0 +1,40 @@ +/** + * + * Copyright 2003-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.tomcat; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +/** + * @version $Rev: 111239 $ $Date: 2004-12-08 02:29:11 -0700 (Wed, 08 Dec 2004) $ + */ +public class ApplicationTest extends AbstractWebModuleTest { + + public void testApplication() throws Exception { + setUpInsecureAppContext(); + + HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/test/hello.txt") + .openConnection(); + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + assertEquals("Hello World", reader.readLine()); + connection.disconnect(); + } + +} Added: geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/SecurityTest.java Url: http://svn.apache.org/viewcvs/geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/SecurityTest.java?view=auto&rev=112258 ============================================================================== --- (empty file) +++ geronimo/trunk/modules/tomcat/src/test/org/apache/geronimo/tomcat/SecurityTest.java Wed Dec 15 16:21:38 2004 @@ -0,0 +1,566 @@ +/** + * + * Copyright 2003-2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.geronimo.tomcat; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; + +import javax.management.ObjectName; + +import org.apache.catalina.deploy.SecurityCollection; +import org.apache.catalina.deploy.SecurityConstraint; + + +/** + * Tests the JAAS security for Tomcat + * + * @version $Rev: 111239 $ $Date: 2004-12-08 02:29:11 -0700 (Wed, 08 Dec 2004) $ + */ +public class SecurityTest extends AbstractWebModuleTest { + + ObjectName appName = null; + /** + * Test the explicit map feature. Only Alan should be able to log in. + * + * @throws Exception thrown if an error in the test occurs + */ + /* + public void xtestExplicitMapping() throws Exception { + Security securityConfig = new Security(); + securityConfig.setUseContextHandler(false); + + DefaultPrincipal defaultPrincipal = new DefaultPrincipal(); + defaultPrincipal.setRealmName("demo-properties-realm"); + Principal principal = new Principal(); + principal.setClassName("org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal"); + principal.setPrincipalName("izumi"); + defaultPrincipal.setPrincipal(principal); + + securityConfig.setDefaultPrincipal(defaultPrincipal); + + Role role = new Role(); + role.setRoleName("content-administrator"); + principal = new Principal(); + principal.setClassName("org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal"); + principal.setPrincipalName("it"); + Realm realm = new Realm(); + realm.setRealmName("demo-properties-realm"); + realm.getPrincipals().add(principal); + role.getRealms().put(realm.getRealmName(), realm); + + securityConfig.getRoleMappings().put(role.getRoleName(), role); + + Set uncheckedPermissions = new HashSet(); + Set excludedPermissions = new HashSet(); + Map rolePermissions = new HashMap(); + Set securityRoles = new HashSet(); + Map legacySecurityConstraintMap = new HashMap(); + + startWebApp(securityConfig, uncheckedPermissions, excludedPermissions, rolePermissions, securityRoles, legacySecurityConstraintMap); + + HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/test/protected/hello.txt").openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + String cookie = connection.getHeaderField("Set-Cookie"); + cookie = cookie.substring(0, cookie.lastIndexOf(';')); + String location = connection.getHeaderField("Location"); + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + + location = location.substring(0, location.lastIndexOf('/')) + "/j_security_check?j_username=alan&j_password=starcraft"; + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + connection = (HttpURLConnection) new URL("http://localhost:8080/test/protected/hello.txt").openConnection(); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + assertEquals("Hello World", reader.readLine()); + connection.disconnect(); + + connection = (HttpURLConnection) new URL("http://localhost:8080/test/protected/hello.txt").openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + cookie = connection.getHeaderField("Set-Cookie"); + cookie = cookie.substring(0, cookie.lastIndexOf(';')); + location = connection.getHeaderField("Location"); + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + + location = location.substring(0, location.lastIndexOf('/')) + "/j_security_check?j_username=izumi&j_password=violin"; + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + try { + connection = (HttpURLConnection) new URL("http://localhost:8080/test/protected/hello.txt").openConnection(); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + fail("Should throw an IOException for HTTP 403 response"); + } catch (IOException e) { + } + + assertEquals(HttpURLConnection.HTTP_FORBIDDEN, connection.getResponseCode()); + connection.disconnect(); + + stopWebApp(); + } + */ + + /** + * Test the auto map feature. Only Izumi should be able to log in. + * + * @throws Exception thrown if an error in the test occurs + */ + /* + public void xtestAutoMapping() throws Exception { + Security securityConfig = new Security(); + securityConfig.setUseContextHandler(false); + + AutoMapAssistant assistant = new AutoMapAssistant(); + assistant.setSecurityRealm("demo-properties-realm"); + securityConfig.setAssistant(assistant); + + securityConfig.getRoleNames().add("content-administrator"); + securityConfig.getRoleNames().add("auto-administrator"); + + SecurityService securityService = (SecurityService) kernel.getProxyManager().createProxy(securityServiceName, SecurityService.class); + try { + securityConfig.autoGenerate(securityService); + } finally { + kernel.getProxyManager().destroyProxy(securityService); + } + + String actions = "GET,POST,PUT,DELETE,HEAD,OPTIONS,TRACE"; + Set uncheckedPermissions = new HashSet(); + uncheckedPermissions.add(new WebUserDataPermission("/protected/*", actions)); + uncheckedPermissions.add(new WebResourcePermission("/:/protected/*:/auth/logon.html", actions)); + uncheckedPermissions.add(new WebUserDataPermission("/:/protected/*:/auth/logon.html", actions)); + Set excludedPermissions = new HashSet(); + excludedPermissions.add(new WebResourcePermission("/auth/login.html", actions)); + excludedPermissions.add(new WebUserDataPermission("/auth/login.html", actions)); + Map rolePermissions = new HashMap(); + WebResourcePermission permission = new WebResourcePermission("/protected/*", actions); + Set permissionSet = new HashSet(); + permissionSet.add(permission); + rolePermissions.put("content-administrator", permissionSet); + rolePermissions.put("auto-administrator", permissionSet); + Set securityRoles = new HashSet(); + securityRoles.add("content-administrator"); + securityRoles.add("auto-administrator"); + + Map legacySecurityConstraintMap = new HashMap(); + + startWebApp(securityConfig, uncheckedPermissions, excludedPermissions, rolePermissions, securityRoles, legacySecurityConstraintMap); + + HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/test/protected/hello.txt").openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + String cookie = connection.getHeaderField("Set-Cookie"); + cookie = cookie.substring(0, cookie.lastIndexOf(';')); + String location = connection.getHeaderField("Location"); + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + + location = location.substring(0, location.lastIndexOf('/')) + "/j_security_check?j_username=izumi&j_password=violin"; + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + connection = (HttpURLConnection) new URL("http://localhost:8080/test/protected/hello.txt").openConnection(); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + assertEquals("Hello World", reader.readLine()); + connection.disconnect(); + + + connection = (HttpURLConnection) new URL("http://localhost:8080/test/protected/hello.txt").openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + cookie = connection.getHeaderField("Set-Cookie"); + cookie = cookie.substring(0, cookie.lastIndexOf(';')); + location = connection.getHeaderField("Location"); + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + + location = location.substring(0, location.lastIndexOf('/')) + "/j_security_check?j_username=alan&j_password=starcraft"; + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + try { + connection = (HttpURLConnection) new URL("http://localhost:8080/test/protected/hello.txt").openConnection(); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + fail("Should throw an IOException for HTTP 403 response"); + } catch (IOException e) { + } + + assertEquals(HttpURLConnection.HTTP_FORBIDDEN, connection.getResponseCode()); + connection.disconnect(); + stopWebApp(); + } + */ + /** + * Mixed the auto map and the standard explicit map. Both Alan and Izumi + * should be able to login. + * + * @throws Exception thrown if an error in the test occurs + */ + /* + public void xtestMixedMapping() throws Exception { + + Security securityConfig = new Security(); + securityConfig.setUseContextHandler(false); + + AutoMapAssistant assistant = new AutoMapAssistant(); + assistant.setSecurityRealm("demo-properties-realm"); + securityConfig.setAssistant(assistant); + + securityConfig.getRoleNames().add("content-administrator"); + securityConfig.getRoleNames().add("auto-administrator"); + + SecurityService securityService = (SecurityService) kernel.getProxyManager().createProxy(securityServiceName, SecurityService.class); + try { + securityConfig.autoGenerate(securityService); + } finally { + kernel.getProxyManager().destroyProxy(securityService); + } + + DefaultPrincipal defaultPrincipal = new DefaultPrincipal(); + defaultPrincipal.setRealmName("demo-properties-realm"); + Principal principal = new Principal(); + principal.setClassName("org.apache.geronimo.security.realm.providers.GeronimoUserPrincipal"); + principal.setPrincipalName("izumi"); + defaultPrincipal.setPrincipal(principal); + + securityConfig.setDefaultPrincipal(defaultPrincipal); + + Role role = new Role(); + role.setRoleName("content-administrator"); + principal = new Principal(); + principal.setClassName("org.apache.geronimo.security.realm.providers.GeronimoGroupPrincipal"); + principal.setPrincipalName("it"); + Realm realm = new Realm(); + realm.setRealmName("demo-properties-realm"); + realm.getPrincipals().add(principal); + role.getRealms().put(realm.getRealmName(), realm); + + securityConfig.append(role); + + Set uncheckedPermissions = new HashSet(); + Set excludedPermissions = new HashSet(); + Map rolePermissions = new HashMap(); + Set securityRoles = new HashSet(); + Map legacySecurityConstraintMap = new HashMap(); + + startWebApp(securityConfig, uncheckedPermissions, excludedPermissions, rolePermissions, securityRoles, legacySecurityConstraintMap); + + HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/test/protected/hello.txt").openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + String cookie = connection.getHeaderField("Set-Cookie"); + cookie = cookie.substring(0, cookie.lastIndexOf(';')); + String location = connection.getHeaderField("Location"); + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + + location = location.substring(0, location.lastIndexOf('/')) + "/j_security_check?j_username=izumi&j_password=violin"; + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + connection = (HttpURLConnection) new URL("http://localhost:8080/test/protected/hello.txt").openConnection(); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + assertEquals("Hello World", reader.readLine()); + connection.disconnect(); + + + connection = (HttpURLConnection) new URL("http://localhost:8080/test/protected/hello.txt").openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + cookie = connection.getHeaderField("Set-Cookie"); + cookie = cookie.substring(0, cookie.lastIndexOf(';')); + location = connection.getHeaderField("Location"); + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + + location = location.substring(0, location.lastIndexOf('/')) + "/j_security_check?j_username=alan&j_password=starcraft"; + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + connection = (HttpURLConnection) new URL("http://localhost:8080/test/protected/hello.txt").openConnection(); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + assertEquals("Hello World", reader.readLine()); + connection.disconnect(); + + stopWebApp(); + } + */ + public void testNotAuthorized() throws Exception { + SecurityConstraint[] constraints = new SecurityConstraint[2]; + + SecurityConstraint sc = new SecurityConstraint(); + sc.setAuthConstraint(true); + sc.addAuthRole("content-administrator"); + sc.addAuthRole("auto-administrator"); + SecurityCollection coll = new SecurityCollection("Admin Role"); + coll.addPattern("/protected/*"); + sc.addCollection(coll); + constraints[0] = sc; + + sc = new SecurityConstraint(); + sc.setAuthConstraint(false); + coll = new SecurityCollection("NO ACCESS"); + coll.addPattern("/auth/logon.html"); + sc.addCollection(coll); + constraints[1] = sc; + + String[] securityRoles = new String[2]; + securityRoles[0] = "content-administrator"; + securityRoles[1] = "auto-administrator"; + + startWebApp(constraints, securityRoles); + + //Begin the test + HttpURLConnection connection = (HttpURLConnection) + new URL("http://localhost:8080/securetest/protected/hello.txt").openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + //Be sure we have been given the login page + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + assertEquals("<!-- Login Page -->", reader.readLine()); + reader.close(); + String cookie = connection.getHeaderField("Set-Cookie"); + cookie = cookie.substring(0, cookie.lastIndexOf(';')); + String location = "http://localhost:8080/securetest/protected/j_security_check?j_username=alan&j_password=starcraft"; + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + location = connection.getHeaderField("Location"); + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(true); + assertEquals(HttpURLConnection.HTTP_FORBIDDEN, connection.getResponseCode()); + connection.disconnect(); + + stopWebApp(); + } + + public void testBadAuthentication() throws Exception { + + SecurityConstraint[] constraints = new SecurityConstraint[2]; + + SecurityConstraint sc = new SecurityConstraint(); + sc.setAuthConstraint(true); + sc.addAuthRole("content-administrator"); + sc.addAuthRole("auto-administrator"); + SecurityCollection coll = new SecurityCollection("Admin Role"); + coll.addPattern("/protected/*"); + sc.addCollection(coll); + constraints[0] = sc; + + sc = new SecurityConstraint(); + sc.setAuthConstraint(false); + coll = new SecurityCollection("NO ACCESS"); + coll.addPattern("/auth/logon.html"); + sc.addCollection(coll); + constraints[1] = sc; + + String[] securityRoles = new String[2]; + securityRoles[0] = "content-administrator"; + securityRoles[1] = "auto-administrator"; + + startWebApp(constraints, securityRoles); + + //Begin the test + HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/securetest/protected/hello.txt").openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + + //Be sure we have been given the login page + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + assertEquals("<!-- Login Page -->", reader.readLine()); + reader.close(); + + String cookie = connection.getHeaderField("Set-Cookie"); + cookie = cookie.substring(0, cookie.lastIndexOf(';')); + String location = "http://localhost:8080/securetest/protected/j_security_check?j_username=alan&j_password=basspassword"; + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(true); + + //Be sure we have been given the login error page + reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + + location = connection.getHeaderField("Location"); + assertEquals("<!-- Not Authorized -->", reader.readLine()); + reader.close(); + + connection.disconnect(); + + stopWebApp(); + + } + + public void testAutoMapping + () throws Exception { + + SecurityConstraint[] constraints = new SecurityConstraint[2]; + + SecurityConstraint sc = new SecurityConstraint(); + sc.setAuthConstraint(true); + sc.addAuthRole("content-administrator"); + sc.addAuthRole("auto-administrator"); + SecurityCollection coll = new SecurityCollection("Admin Role"); + coll.addPattern("/protected/*"); + sc.addCollection(coll); + constraints[0] = sc; + + sc = new SecurityConstraint(); + sc.setAuthConstraint(false); + coll = new SecurityCollection("NO ACCESS"); + coll.addPattern("/auth/logon.html"); + sc.addCollection(coll); + constraints[1] = sc; + + String[] securityRoles = new String[2]; + securityRoles[0] = "content-administrator"; + securityRoles[1] = "auto-administrator"; + + startWebApp(constraints, securityRoles); + + //Begin the test + HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/securetest/protected/hello.txt").openConnection(); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + + //Be sure we have been given the login page + BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + assertEquals("<!-- Login Page -->", reader.readLine()); + reader.close(); + + String cookie = connection.getHeaderField("Set-Cookie"); + cookie = cookie.substring(0, cookie.lastIndexOf(';')); + String location = connection.getHeaderField("Location"); + + location = "http://localhost:8080/securetest/protected/j_security_check?j_username=izumi&j_password=violin"; + + connection = (HttpURLConnection) new URL(location).openConnection(); + connection.setRequestMethod("POST"); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + assertEquals(HttpURLConnection.HTTP_MOVED_TEMP, connection.getResponseCode()); + + connection = (HttpURLConnection) new URL("http://localhost:8080/securetest/protected/hello.txt").openConnection(); + connection.setRequestProperty("Cookie", cookie); + connection.setInstanceFollowRedirects(false); + reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); + + assertEquals(HttpURLConnection.HTTP_OK, connection.getResponseCode()); + assertEquals("Hello World", reader.readLine()); + connection.disconnect(); + + stopWebApp(); + + } + + protected void startWebApp + (SecurityConstraint[] securityConstraints, String[] securityRoles) throws Exception { + appName = setUpSecureAppContext(securityConstraints, securityRoles); + } + + protected void stopWebApp + () throws Exception { + stop(appName); + } + + protected void setUp + () throws Exception { + super.setUp(); + setUpSecurity(); + } + + protected void tearDown + () throws Exception { + tearDownSecurity(); + super.tearDown(); + } + +}