adc 2004/06/27 13:37:38
Modified: modules/jetty/src/java/org/apache/geronimo/jetty
JAASJettyPrincipal.java JAASJettyRealm.java
JettyServer.java JettyXMLConfiguration.java
modules/jetty/src/java/org/apache/geronimo/jetty/deployment
JettyModuleBuilder.java
modules/jetty/src/test/org/apache/geronimo/jetty
ApplicationTest.java
Added: modules/jetty/src/java/org/apache/geronimo/jetty
JettyServletHolder.java JettyWebAppContext.java
JettyWebAppHandler.java JettyWebAppJACCContext.java
modules/jetty/src/test/org/apache/geronimo/jetty
SecurityTest.java
Removed: modules/jetty/src/java/org/apache/geronimo/jetty
JettyWebApplicationContext.java
Log:
Added JACC to Jetty.
Revision Changes Path
1.2 +11 -1
incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyPrincipal.java
Index: JAASJettyPrincipal.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyPrincipal.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JAASJettyPrincipal.java 30 May 2004 19:09:57 -0000 1.1
+++ JAASJettyPrincipal.java 27 Jun 2004 20:37:38 -0000 1.2
@@ -18,6 +18,7 @@
import javax.security.auth.Subject;
import java.security.Principal;
+import java.util.Stack;
/**
@@ -26,6 +27,7 @@
public class JAASJettyPrincipal implements Principal {
private String name;
private Subject subject;
+ private Stack stack = new Stack();
public JAASJettyPrincipal(String name) {
this.name = name;
@@ -41,5 +43,13 @@
void setSubject(Subject subject) {
this.subject = subject;
+ }
+
+ void push(Subject roleDesignate) {
+ stack.push(roleDesignate);
+ }
+
+ Subject pop() {
+ return (Subject) stack.pop();
}
}
1.5 +48 -26
incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyRealm.java
Index: JAASJettyRealm.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyRealm.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- JAASJettyRealm.java 5 Jun 2004 07:53:21 -0000 1.4
+++ JAASJettyRealm.java 27 Jun 2004 20:37:38 -0000 1.5
@@ -16,21 +16,29 @@
*/
package org.apache.geronimo.jetty;
-import java.security.Principal;
-import java.util.HashMap;
+import javax.security.auth.Subject;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
+import javax.security.jacc.WebRoleRefPermission;
+import java.security.AccessControlContext;
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Stack;
+import org.mortbay.http.HttpRequest;
+import org.mortbay.http.UserRealm;
+import org.mortbay.jaas.callback.DefaultCallbackHandler;
+import org.mortbay.util.LogSupport;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanInfoFactory;
import org.apache.geronimo.gbean.GBeanLifecycle;
import org.apache.geronimo.gbean.WaitingException;
-import org.mortbay.http.HttpRequest;
-import org.mortbay.http.UserRealm;
-import org.mortbay.jaas.callback.DefaultCallbackHandler;
-import org.mortbay.util.LogSupport;
+import org.apache.geronimo.security.ContextManager;
/**
@@ -40,10 +48,10 @@
private static Log log = LogFactory.getLog(JAASJettyRealm.class);
- protected final JettyContainer container;
- protected String realmName;
- protected String loginModuleName;
- protected HashMap userMap = new HashMap();
+ private final JettyContainer container;
+ private String realmName;
+ private String loginModuleName;
+ private HashMap userMap = new HashMap();
public JAASJettyRealm(JettyContainer container) {
this.container = container;
@@ -65,9 +73,8 @@
return (Principal) userMap.get(username);
}
- public Principal authenticate(String username,
- Object credentials,
- HttpRequest request) {
+ public Principal authenticate(String username, Object credentials,
HttpRequest request) {
+
try {
JAASJettyPrincipal userPrincipal = (JAASJettyPrincipal)
userMap.get(username);
@@ -85,10 +92,13 @@
//set up the login context
LoginContext loginContext = new LoginContext(loginModuleName,
- callbackHandler);
+ callbackHandler);
loginContext.login();
+ ContextManager.registerSubject(loginContext.getSubject());
+ ContextManager.setCurrentCaller(loginContext.getSubject());
+
//login success
userPrincipal = new JAASJettyPrincipal(username);
userPrincipal.setSubject(loginContext.getSubject());
@@ -102,33 +112,45 @@
}
}
+ public void logout(Principal user) {
+ JAASJettyPrincipal principal = (JAASJettyPrincipal) user;
+
+ userMap.remove(principal.getName());
+ ContextManager.unregisterSubject(principal.getSubject());
+ }
+
public boolean reauthenticate(Principal user) {
// TODO This is not correct if auth can expire! We need to
+
+
ContextManager.setCurrentCaller(((JAASJettyPrincipal)user).getSubject());
+
// get the user out of the cache
return (userMap.get(user.getName()) != null);
}
- public boolean isUserInRole(Principal user, String role) {
- //TODO
- return true;
+ public void disassociate(Principal user) {
+ // do nothing
}
- public void disassociate(Principal user) {
- //TODO
+ public boolean isUserInRole(Principal user, String role) {
+ AccessControlContext acc = ContextManager.getCurrentContext();
+ try {
+ acc.checkPermission(new
WebRoleRefPermission(JettyServletHolder.getJettyServletHolder().getName(),
role));
+ } catch (AccessControlException e) {
+ return false;
+ }
+ return true;
}
public Principal pushRole(Principal user, String role) {
- //TODO
+ ((JAASJettyPrincipal)user).push(ContextManager.getCurrentCaller());
+
ContextManager.setCurrentCaller(JettyServer.getCurrentWebAppContext().getRoleDesignate(role));
return user;
}
public Principal popRole(Principal user) {
- //TODO
+ ContextManager.setCurrentCaller(((JAASJettyPrincipal)user).pop());
return user;
- }
-
- public void logout(Principal user) {
- log.warn(LogSupport.NOT_IMPLEMENTED);
}
public void doStart() throws WaitingException, Exception {
1.2 +18 -1
incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServer.java
Index: JettyServer.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServer.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JettyServer.java 30 May 2004 19:09:57 -0000 1.1
+++ JettyServer.java 27 Jun 2004 20:37:38 -0000 1.2
@@ -24,6 +24,8 @@
import org.mortbay.http.UserRealm;
import org.mortbay.jetty.Server;
+import org.apache.geronimo.security.ContextManager;
+
/**
* @version $Revision$ $Date$
@@ -31,6 +33,7 @@
public class JettyServer extends Server {
private Map realmDelegates = new HashMap();
+ private final static ThreadLocal currentWebAppContext = new
ThreadLocal();
public UserRealm addRealm(UserRealm realm) {
RealmDelegate delegate = (RealmDelegate)
realmDelegates.get(realm.getName());
@@ -55,6 +58,20 @@
public void removeRealm(UserRealm realm) {
realmDelegates.remove(realm.getName());
+ }
+
+ public static void setCurrentWebAppContext(JettyWebAppJACCContext
context) {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) sm.checkPermission(ContextManager.SET_CONTEXT);
+
+ currentWebAppContext.set(context);
+ }
+
+ public static JettyWebAppJACCContext getCurrentWebAppContext() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) sm.checkPermission(ContextManager.GET_CONTEXT);
+
+ return (JettyWebAppJACCContext) currentWebAppContext.get();
}
private class RealmDelegate implements UserRealm {
1.2 +85 -31
incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/JettyXMLConfiguration.java
Index: JettyXMLConfiguration.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/JettyXMLConfiguration.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- JettyXMLConfiguration.java 30 May 2004 19:09:57 -0000 1.1
+++ JettyXMLConfiguration.java 27 Jun 2004 20:37:38 -0000 1.2
@@ -16,16 +16,19 @@
*/
package org.apache.geronimo.jetty;
+import javax.security.auth.Subject;
import javax.security.jacc.PolicyConfiguration;
import javax.security.jacc.PolicyContextException;
import javax.security.jacc.WebResourcePermission;
+import javax.security.jacc.WebRoleRefPermission;
import javax.security.jacc.WebUserDataPermission;
import javax.servlet.UnavailableException;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
+import java.io.IOException;
+import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.Map;
import java.util.Set;
import org.mortbay.jetty.servlet.XMLConfiguration;
@@ -33,7 +36,6 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.geronimo.jetty.JettyWebApplicationContext;
import org.apache.geronimo.security.GeronimoSecurityException;
import org.apache.geronimo.security.RealmPrincipal;
import org.apache.geronimo.security.deploy.Principal;
@@ -41,26 +43,31 @@
import org.apache.geronimo.security.deploy.Role;
import org.apache.geronimo.security.deploy.Security;
import org.apache.geronimo.security.jacc.RoleMappingConfiguration;
+import org.apache.geronimo.security.util.ConfigurationUtil;
import org.apache.geronimo.security.util.URLPattern;
/**
+ * JettyXMLConfiguration reads the web-app configuration and translates them
+ * into corresponding JACC policy permissions.
+ *
* @version $Revision$ $Date$
*/
public class JettyXMLConfiguration extends XMLConfiguration {
private static Log log = LogFactory.getLog(JettyXMLConfiguration.class);
- private HashSet securityRoles = new HashSet();
- private HashMap uncheckedPatterns = new HashMap();
- private HashMap excludedPatterns = new HashMap();
- private HashMap rolesPatterns = new HashMap();
- private HashSet allSet = new HashSet();
- private HashMap allMap = new HashMap();
- private HashSet allRoles = new HashSet();
+ private Set securityRoles = new HashSet();
+ private Map uncheckedPatterns = new HashMap();
+ private Map excludedPatterns = new HashMap();
+ private Map rolesPatterns = new HashMap();
+ private Set allSet = new HashSet();
+ private Map allMap = new HashMap();
+ private Set allRoles = new HashSet();
+ private Map roleRefs = new HashMap();
- public JettyXMLConfiguration(JettyWebApplicationContext context) {
+ public JettyXMLConfiguration(JettyWebAppContext context) {
super(context);
}
@@ -73,10 +80,39 @@
}
}
+ protected void initServlet(XmlParser.Node node)
+ throws ClassNotFoundException, UnavailableException,
IOException, MalformedURLException {
+
+ super.initServlet(node);
+
+ String name = node.getString("servlet-name", false, true);
+ if (name == null) name = node.getString("servlet-class", false,
true);
+
+ Iterator sRefsIter = node.iterator("security-role-ref");
+ while (sRefsIter.hasNext()) {
+ XmlParser.Node securityRef = (XmlParser.Node) sRefsIter.next();
+ String roleName = securityRef.getString("role-name", false,
true);
+ String roleLink = securityRef.getString("role-link", false,
true);
+
+ if (roleName != null && roleName.length() > 0 && roleLink !=
null && roleLink.length() > 0) {
+ if (log.isDebugEnabled()) log.debug("link role " + roleName
+ " to " + roleLink + " for " + this);
+
+ Set refs = (Set) roleRefs.get(roleLink);
+ if (refs == null) {
+ refs = new HashSet();
+ roleRefs.put(roleLink, refs);
+ }
+ refs.add(new WebRoleRefPermission(name, roleName));
+ } else {
+ log.warn("Ignored invalid security-role-ref element: " +
"servlet-name=" + name + ", " + securityRef);
+ }
+ }
+ }
+
/**
* Translate the web deployment descriptors into equivalent security
* permissions. These permissions are placed into the appropriate
- * <code>PolicyConfiguration</code> object as defined in the JAAC spec.
+ * <code>PolicyConfiguration</code> object as defined in the JACC spec.
*
* @param node the deployment descriptor from which to obtain the
* security constraints that are to be translated.
@@ -91,7 +127,7 @@
XmlParser.Node auths = node.get("auth-constraint");
- HashMap currentPatterns;
+ Map currentPatterns;
if (auths == null) {
currentPatterns = uncheckedPatterns;
} else if (auths.size() == 0) {
@@ -157,9 +193,19 @@
}
protected void initSecurityRole(XmlParser.Node node) {
+ super.initSecurityRole(node);
+
securityRoles.add(node.get("role-name").toString(false, true));
}
+ /**
+ * This method dumps the intermediate security information into the JACC
+ * PolicyConfiguration.
+ *
+ * @param configuration the JACC PolicyConfiguration
+ * @param security the augmented security information from the
geronimo-web.xml file
+ * @throws GeronimoSecurityException
+ */
public void configure(PolicyConfiguration configuration, Security
security) throws GeronimoSecurityException {
try {
@@ -257,12 +303,16 @@
configuration.addToUncheckedPolicy(new
WebUserDataPermission(name, actions));
}
+ JettyWebAppJACCContext context = (JettyWebAppJACCContext)
getWebApplicationContext();
RoleMappingConfiguration roleMapper = (RoleMappingConfiguration)
configuration;
- Iterator rollMappings = security.getRollMappings().iterator();
+ Iterator rollMappings = security.getRoleMappings().iterator();
while (rollMappings.hasNext()) {
Role role = (Role) rollMappings.next();
+ String roleName = role.getRoleName();
+
+ if (!securityRoles.contains(roleName)) throw new
GeronimoSecurityException("Role does not exist in this configuration");
- if (!securityRoles.contains(role.getRoleName())) throw new
GeronimoSecurityException("Role does not exist in this configuration");
+ Subject roleDesignate = new Subject();
Iterator realms = role.getRealms().iterator();
while (realms.hasNext()) {
@@ -273,27 +323,31 @@
while (principals.hasNext()) {
Principal principal = (Principal) principals.next();
- Class clazz =
Class.forName(principal.getClassName());
- Constructor constructor =
clazz.getDeclaredConstructor(new Class[]{String.class});
- java.security.Principal p =
(java.security.Principal) constructor.newInstance(new
Object[]{principal.getPrincipalName()});
- principalSet.add(new
RealmPrincipal(realm.getRealmName(), p));
+ RealmPrincipal realmPrincipal =
ConfigurationUtil.generateRealmPrincipal(principal, realm.getRealmName());
+
+ if (realmPrincipal == null) throw new
GeronimoSecurityException("Unable to create realm principal");
+
+ principalSet.add(realmPrincipal);
+ if (principal.isDesignatedRunAs())
roleDesignate.getPrincipals().add(realmPrincipal);
}
- roleMapper.addRoleMapping(role.getRoleName(),
principalSet);
+ roleMapper.addRoleMapping(roleName, principalSet);
+ }
+
+ if (roleDesignate.getPrincipals().size() > 0)
context.setRoleDesignate(roleName, roleDesignate);
+ }
+
+ Iterator keys = roleRefs.keySet().iterator();
+ while (keys.hasNext()) {
+ String roleLink = (String) keys.next();
+ iter = ((Set) roleRefs.get(roleLink)).iterator();
+
+ while (iter.hasNext()) {
+ configuration.addToRole(roleLink, (WebRoleRefPermission)
iter.next());
}
}
} catch (ClassCastException cce) {
throw new GeronimoSecurityException("Policy configuration object
does not implement RoleMappingConfiguration", cce.getCause());
} catch (PolicyContextException e) {
- throw new GeronimoSecurityException(e);
- } catch (IllegalAccessException e) {
- throw new GeronimoSecurityException(e);
- } catch (NoSuchMethodException e) {
- throw new GeronimoSecurityException(e);
- } catch (InvocationTargetException e) {
- throw new GeronimoSecurityException(e);
- } catch (InstantiationException e) {
- throw new GeronimoSecurityException(e);
- } catch (ClassNotFoundException e) {
throw new GeronimoSecurityException(e);
}
}
1.1
incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServletHolder.java
Index: JettyServletHolder.java
===================================================================
/**
*
* 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.
*/
package org.apache.geronimo.jetty;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.UnavailableException;
import java.io.IOException;
import org.mortbay.jetty.servlet.ServletHandler;
import org.mortbay.jetty.servlet.ServletHolder;
/**
* This ServletHolder's sole purpose is to provide the thread's current
* ServletHolder for realms that are interested in the current servlet, e.g.
* current servlet name.
* @see
org.apache.geronimo.jetty.JAASJettyRealm#isUserInRole(java.security.Principal,
java.lang.String)
* @version $Revision: 1.1 $ $Date: 2004/06/27 20:37:38 $
*/
public class JettyServletHolder extends ServletHolder {
private static final ThreadLocal currentServletHolder = new ThreadLocal();
public JettyServletHolder() {
super();
}
public JettyServletHolder(ServletHandler handler, String name, String
className) {
super(handler, name, className);
}
public JettyServletHolder(ServletHandler handler, String name, String
className, String forcedPath) {
super(handler,name, className, forcedPath);
}
/**
* Service a request with this servlet. Set the ThreadLocal to hold the
* current JettyServletHolder.
* @param request
* @param response
* @throws ServletException
* @throws UnavailableException
* @throws IOException
*/
public void handle(ServletRequest request, ServletResponse response)
throws ServletException, UnavailableException, IOException {
currentServletHolder.set(this);
super.handle(request, response);
}
/**
* Provide the thread's current JettyServletHolder
* @return the thread's current JettyServletHolder
* @see
org.apache.geronimo.jetty.JAASJettyRealm#isUserInRole(java.security.Principal,
java.lang.String)
*/
static JettyServletHolder getJettyServletHolder() {
return (JettyServletHolder) currentServletHolder.get();
}
}
1.1
incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/JettyWebAppContext.java
Index: JettyWebAppContext.java
===================================================================
/**
*
* 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.jetty;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.Set;
import javax.resource.ResourceException;
import javax.transaction.TransactionManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanInfoFactory;
import org.apache.geronimo.gbean.GBeanLifecycle;
import org.apache.geronimo.gbean.WaitingException;
import org.apache.geronimo.kernel.config.ConfigurationParent;
import org.apache.geronimo.naming.java.ReadOnlyContext;
import org.apache.geronimo.naming.java.RootContext;
import org.apache.geronimo.transaction.DefaultInstanceContext;
import org.apache.geronimo.transaction.InstanceContext;
import org.apache.geronimo.transaction.TrackedConnectionAssociator;
import org.apache.geronimo.transaction.TransactionContext;
import org.apache.geronimo.transaction.UnspecifiedTransactionContext;
import org.apache.geronimo.transaction.UserTransactionImpl;
import org.mortbay.http.HttpException;
import org.mortbay.http.HttpRequest;
import org.mortbay.http.HttpResponse;
import org.mortbay.jetty.servlet.WebApplicationContext;
/**
* Wrapper for a WebApplicationContext that sets up its J2EE environment.
*
* @version $Revision: 1.1 $ $Date: 2004/06/27 20:37:38 $
*/
public class JettyWebAppContext extends WebApplicationContext implements
GBeanLifecycle {
private static Log log = LogFactory.getLog(JettyWebAppContext.class);
private final ConfigurationParent config;
private final URI uri;
private final JettyContainer container;
private final ReadOnlyContext componentContext;
private final TransactionManager txManager;
private final TrackedConnectionAssociator associator;
private final UserTransactionImpl userTransaction;
private final ClassLoader classLoader;
// @todo get these from DD
private final Set unshareableResources;
private final Set applicationManagedSecurityResources;
private boolean contextPriorityClassLoader = false;
public JettyWebAppContext() {
this(null, null, null, null, null, null, null, null, null, null);
}
public JettyWebAppContext(ConfigurationParent config,
URI uri,
JettyContainer container,
ReadOnlyContext compContext,
Set unshareableResources,
Set applicationManagedSecurityResources,
TransactionManager txManager,
TrackedConnectionAssociator associator,
UserTransactionImpl userTransaction,
ClassLoader classLoader) {
super();
this.config = config;
this.uri = uri;
this.container = container;
this.componentContext = compContext;
this.unshareableResources = unshareableResources;
this.applicationManagedSecurityResources =
applicationManagedSecurityResources;
this.txManager = txManager;
this.associator = associator;
this.userTransaction = userTransaction;
this.classLoader = classLoader;
setConfiguration(new JettyXMLConfiguration(this));
}
/**
* getContextPriorityClassLoader.
*
* @return True if this context should give web application class in
preference over the containers
* classes, as per the servlet specification recommendations.
*/
public boolean getContextPriorityClassLoader() {
return contextPriorityClassLoader;
}
/**
* setContextPriorityClassLoader.
*
* @param b True if this context should give web application class in
preference over the containers
* classes, as per the servlet specification recommendations.
*/
public void setContextPriorityClassLoader(boolean b) {
contextPriorityClassLoader = b;
}
/**
* init the classloader. Uses the value of contextPriorityClassLoader to
* determine if the context needs to create its own classloader.
*/
protected void initClassLoader(boolean forceContextLoader)
throws MalformedURLException, IOException {
setClassLoaderJava2Compliant(!contextPriorityClassLoader);
if (!contextPriorityClassLoader) {
// TODO - once geronimo is correctly setting up the classpath,
this should be uncommented.
// At the moment, the g classloader does not appear to know about
the WEB-INF classes and lib.
// setClassLoader(Thread.currentThread().getContextClassLoader());
}
super.initClassLoader(forceContextLoader);
if (log.isDebugEnabled()) {
log.debug("classloader for " + getContextPath() + ": " +
getClassLoader());
}
}
public void handle(String pathInContext,
String pathParams,
HttpRequest httpRequest,
HttpResponse httpResponse)
throws HttpException, IOException {
// save previous state
ReadOnlyContext oldComponentContext =
RootContext.getComponentContext();
InstanceContext oldInstanceContext = null;
try {
// set up java:comp JNDI Context
RootContext.setComponentContext(componentContext);
// Turn on the UserTransaction
userTransaction.setOnline(true);
if (TransactionContext.getContext() == null) {
TransactionContext.setContext(new
UnspecifiedTransactionContext());
}
try {
oldInstanceContext = associator.enter(new
DefaultInstanceContext(unshareableResources,
applicationManagedSecurityResources));
} catch (ResourceException e) {
throw new RuntimeException(e);
}
super.handle(pathInContext, pathParams, httpRequest,
httpResponse);
} finally {
try {
associator.exit(oldInstanceContext);
} catch (ResourceException e) {
throw new RuntimeException(e);
} finally {
userTransaction.setOnline(false);
RootContext.setComponentContext(oldComponentContext);
}
}
}
public void doStart() throws WaitingException, Exception {
userTransaction.setUp(txManager, associator);
if (uri.isAbsolute()) {
setWAR(uri.toString());
} else {
setWAR(new URL(config.getBaseURL(), uri.toString()).toString());
}
if (userTransaction != null) {
userTransaction.setOnline(true);
}
container.addContext(this);
ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(classLoader);
super.start();
} finally {
Thread.currentThread().setContextClassLoader(oldCL);
}
log.info("JettyWebAppContext started");
}
public void doStop() throws WaitingException, Exception {
while (true) {
try {
super.stop();
break;
} catch (InterruptedException e) {
continue;
}
}
container.removeContext(this);
if (userTransaction != null) {
userTransaction.setOnline(false);
}
log.info("JettyWebAppContext stopped");
}
public void doFail() {
try {
super.stop();
} catch (InterruptedException e) {
}
container.removeContext(this);
log.info("JettyWebAppContext failed");
}
public static final GBeanInfo GBEAN_INFO;
static {
GBeanInfoFactory infoFactory = new GBeanInfoFactory("Jetty
WebApplication Context", JettyWebAppContext.class);
infoFactory.addAttribute("URI", URI.class, true);
infoFactory.addAttribute("ContextPath", String.class, true);
infoFactory.addAttribute("ContextPriorityClassLoader", Boolean.TYPE,
true);
infoFactory.addAttribute("ComponentContext", ReadOnlyContext.class,
true);
infoFactory.addAttribute("UnshareableResources", Set.class, true);
infoFactory.addAttribute("ApplicationManagedSecurityResources",
Set.class, true);
infoFactory.addAttribute("UserTransaction",
UserTransactionImpl.class, true);
infoFactory.addAttribute("classLoader", ClassLoader.class, false);
infoFactory.addReference("Configuration", ConfigurationParent.class);
infoFactory.addReference("JettyContainer", JettyContainer.class);
infoFactory.addReference("TransactionManager",
TransactionManager.class);
infoFactory.addReference("TrackedConnectionAssociator",
TrackedConnectionAssociator.class);
infoFactory.setConstructor(new String[]{
"Configuration",
"URI",
"JettyContainer",
"ComponentContext",
"UnshareableResources",
"ApplicationManagedSecurityResources",
"TransactionManager",
"TrackedConnectionAssociator",
"UserTransaction",
"classLoader"});
GBEAN_INFO = infoFactory.getBeanInfo();
}
public static GBeanInfo getGBeanInfo() {
return GBEAN_INFO;
}
}
1.1
incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/JettyWebAppHandler.java
Index: JettyWebAppHandler.java
===================================================================
/**
*
* 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.
*/
package org.apache.geronimo.jetty;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.jetty.servlet.WebApplicationHandler;
/**
* A class extension to <code>WebApplicationHandler</code> whose sole purpose
* is to override the implementation of <code>newServletHolder()</code> so
* that it returns an instance of <code>JettyServletHolder</code>. The class
* <code>JettyServletHolder</code> tracks which servlet is currently being
* handled by the current thread. This allows <code>JAASJettyRealm</code>
* to obtain the name of the servlet that is being handled so that it can
* generate the proper JACC permission.
*
* @version $Revision: 1.1 $ $Date: 2004/06/27 20:37:38 $
* @see org.apache.geronimo.jetty.JettyServletHolder
* @see
org.apache.geronimo.jetty.JAASJettyRealm#isUserInRole(java.security.Principal,
java.lang.String)
*/
public class JettyWebAppHandler extends WebApplicationHandler {
/**
* Return an instance of <code>JettyServletHolder</code>.
* <p/>
* This method overrides <code>WebApplicationHandler</code>'s
implementation.
*
* @param name The name of the servlet.
* @param servletClass The class name of the servlet.
* @param forcedPath If non null, the request attribute
* javax.servlet.include.servlet_path will be set to
this path before
* service is called.
* @return an instance of <code>JettyServletHolder</code>
* @see
org.mortbay.jetty.servlet.WebApplicationHandler#newServletHolder(java.lang.String,
java.lang.String, java.lang.String)
*/
public ServletHolder newServletHolder(String name, String servletClass,
String forcedPath) {
if (_nameMap.containsKey(name)) throw new
IllegalArgumentException("Named servlet already exists: " + name);
ServletHolder holder = new JettyServletHolder(this, name,
servletClass, forcedPath);
_nameMap.put(holder.getName(), holder);
return holder;
}
}
1.1
incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/JettyWebAppJACCContext.java
Index: JettyWebAppJACCContext.java
===================================================================
/**
*
* 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.jetty;
import javax.security.auth.Subject;
import javax.security.jacc.PolicyConfiguration;
import javax.security.jacc.PolicyConfigurationFactory;
import javax.security.jacc.PolicyContext;
import javax.security.jacc.PolicyContextException;
import javax.security.jacc.WebResourcePermission;
import javax.security.jacc.WebUserDataPermission;
import javax.transaction.TransactionManager;
import java.io.IOException;
import java.net.URI;
import java.security.AccessControlContext;
import java.security.AccessControlException;
import java.security.Principal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.mortbay.http.Authenticator;
import org.mortbay.http.HttpException;
import org.mortbay.http.HttpRequest;
import org.mortbay.http.HttpResponse;
import org.mortbay.http.PathMap;
import org.mortbay.http.SecurityConstraint;
import org.mortbay.http.UserRealm;
import org.mortbay.jetty.servlet.FormAuthenticator;
import org.mortbay.jetty.servlet.ServletHttpRequest;
import org.mortbay.util.LazyList;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.geronimo.gbean.GBeanInfo;
import org.apache.geronimo.gbean.GBeanInfoFactory;
import org.apache.geronimo.gbean.WaitingException;
import org.apache.geronimo.kernel.config.ConfigurationParent;
import org.apache.geronimo.naming.java.ReadOnlyContext;
import org.apache.geronimo.security.ContextManager;
import org.apache.geronimo.security.GeronimoSecurityException;
import org.apache.geronimo.security.IdentificationPrincipal;
import org.apache.geronimo.security.PrimaryRealmPrincipal;
import org.apache.geronimo.security.RealmPrincipal;
import org.apache.geronimo.security.SubjectId;
import org.apache.geronimo.security.deploy.DefaultPrincipal;
import org.apache.geronimo.security.deploy.Security;
import org.apache.geronimo.security.util.ConfigurationUtil;
import org.apache.geronimo.transaction.TrackedConnectionAssociator;
import org.apache.geronimo.transaction.UserTransactionImpl;
/**
* A class extension to <code>JettyWebAppContext</code> whose purpose is to
* provide JACC security checks.
*
* @version $Revision: 1.1 $ $Date: 2004/06/27 20:37:38 $
* @see
org.mortbay.jetty.servlet.WebApplicationContext#checkSecurityConstraints(java.lang.String,
org.mortbay.http.HttpRequest, org.mortbay.http.HttpResponse)
*/
public class JettyWebAppJACCContext extends JettyWebAppContext {
private static Log log = LogFactory.getLog(JettyWebAppJACCContext.class);
private final String policyContextID;
private final Security securityConfig;
private PolicyConfigurationFactory factory;
private PolicyConfiguration policyConfiguration;
private Map roleDesignates = new HashMap();
private JAASJettyPrincipal defaultPrincipal;
private PathMap _constraintMap = new PathMap();
public JettyWebAppJACCContext() {
this(null, null, null, null, null, null, null, null, null, null,
null, null);
}
public JettyWebAppJACCContext(ConfigurationParent config,
URI uri,
JettyContainer container,
ReadOnlyContext compContext,
String policyContextID,
Security securityConfig,
Set unshareableResources,
Set applicationManagedSecurityResources,
TransactionManager txManager,
TrackedConnectionAssociator associator,
UserTransactionImpl userTransaction,
ClassLoader classLoader) {
super(config, uri, container, compContext, unshareableResources,
applicationManagedSecurityResources,
txManager, associator, userTransaction, classLoader);
this.policyContextID = policyContextID;
this.securityConfig = securityConfig;
setConfiguration(new JettyXMLConfiguration(this));
defaultPrincipal = generateDefaultPrincipal(securityConfig);
/**
* We want to use our own web-app handler.
*/
addHandler(new JettyWebAppHandler());
}
public String getPolicyContextID() {
return policyContextID;
}
public Security getSecurityConfig() {
return securityConfig;
}
public Subject getRoleDesignate(String roleName) {
return (Subject) roleDesignates.get(roleName);
}
void setRoleDesignate(String roleName, Subject subject) {
roleDesignates.put(roleName, subject);
}
/**
* Handler request.
* Call each HttpHandler until request is handled.
*
* @param pathInContext Path in context
* @param pathParams Path parameters such as encoded Session ID
* @param httpRequest
* @param httpResponse
* @throws HttpException
* @throws IOException
*/
public void handle(String pathInContext,
String pathParams,
HttpRequest httpRequest,
HttpResponse httpResponse)
throws HttpException, IOException {
String savedPolicyContextID = PolicyContext.getContextID();
JettyWebAppJACCContext savedContext =
JettyServer.getCurrentWebAppContext();
try {
PolicyContext.setContextID(policyContextID);
JettyServer.setCurrentWebAppContext(this);
super.handle(pathInContext, pathParams, httpRequest,
httpResponse);
} finally {
JettyServer.setCurrentWebAppContext(savedContext);
PolicyContext.setContextID(savedPolicyContextID);
}
}
/**
* Keep our own copy of security constraints.<p/>
* <p/>
* We keep our own copy of security constraints because Jetty's copy is
* private. We use these constraints not for any authorization descitions
* but, to decide whether we should attempt to authenticate the request.
*
* @param pathSpec The path spec to which the secuiryt cosntraint applies
* @param sc the security constraint
* @todo Jetty to provide access to this map so we can remove this method
* @see
org.mortbay.http.HttpContext#addSecurityConstraint(java.lang.String,
org.mortbay.http.SecurityConstraint)
*/
public void addSecurityConstraint(String pathSpec, SecurityConstraint sc)
{
super.addSecurityConstraint(pathSpec, sc);
Object scs = _constraintMap.get(pathSpec);
scs = LazyList.add(scs, sc);
_constraintMap.put(pathSpec, scs);
if (log.isDebugEnabled()) log.debug("added " + sc + " at " +
pathSpec);
}
/**
* Check the security constraints using JACC.
*
* @param pathInContext path in context
* @param request HTTP request
* @param response HTTP response
* @return <code>true</code> if the path in context passes the security
* check, <code>false</code> if it fails or a redirection has
occured
* during authentication.
* @throws HttpException
* @throws IOException
*/
public boolean checkSecurityConstraints(String pathInContext, HttpRequest
request, HttpResponse response) throws HttpException, IOException {
try {
Principal user = obtainUser(pathInContext, request, response);
if (user == null) return false;
if (user == SecurityConstraint.__NOBODY) return true;
AccessControlContext acc = ContextManager.getCurrentContext();
ServletHttpRequest servletHttpRequest = (ServletHttpRequest)
request.getWrapper();
/**
* JACC v1.0 secion 4.1.1
*/
acc.checkPermission(new
WebUserDataPermission(servletHttpRequest));
/**
* JACC v1.0 secion 4.1.2
*/
acc.checkPermission(new
WebResourcePermission(servletHttpRequest));
} catch (HttpException he) {
response.sendError(he.getCode(), he.getReason());
return false;
} catch (AccessControlException ace) {
response.sendError(HttpResponse.__403_Forbidden);
return false;
}
return true;
}
/**
* Obtain an authenticated user, if one is required. Otherwise return the
* default principal.
* <p/>
* Also set the current caller for JACC security checks for the default
* principal. This is automatically done by <code>JAASJettyRealm</code>.
*
* @param pathInContext path in context
* @param request HTTP request
* @param response HTTP response
* @return <code>null</code> if there is no authenticated user at the
moment
* and security checking should not proceed and servlet handling
should also
* not proceed, e.g. redirect.
<code>SecurityConstraint.__NOBODY</code> if
* security checking should not proceed and servlet handling
should proceed,
* e.g. login page.
* @throws HttpException
* @throws IOException
*/
public Principal obtainUser(String pathInContext, HttpRequest request,
HttpResponse response) throws HttpException, IOException {
List scss = _constraintMap.getMatches(pathInContext);
String pattern = null;
boolean unauthenticated = false;
boolean forbidden = false;
if (scss != null && scss.size() > 0) {
// for each path match
// Add only constraints that have the correct method
// break if the matching pattern changes. This allows only
// constraints with matching pattern and method to be combined.
loop:
for (int m = 0; m < scss.size(); m++) {
Map.Entry entry = (Map.Entry) scss.get(m);
Object scs = entry.getValue();
String p = (String) entry.getKey();
for (int c = 0; c < LazyList.size(scs); c++) {
SecurityConstraint sc = (SecurityConstraint)
LazyList.get(scs, c);
if (!sc.forMethod(request.getMethod())) continue;
if (pattern != null && !pattern.equals(p)) break loop;
pattern = p;
// Check the method applies
if (!sc.forMethod(request.getMethod())) continue;
// Combine auth constraints.
if (sc.getAuthenticate()) {
if (!sc.isAnyRole()) {
List scr = sc.getRoles();
if (scr == null || scr.size() == 0) {
forbidden = true;
break loop;
}
}
} else {
unauthenticated = true;
break loop;
}
}
}
}
UserRealm realm = getRealm();
Authenticator authenticator = getAuthenticator();
Principal user = null;
if (!unauthenticated && !forbidden) {
if (realm == null) {
log.warn("Realm Not Configured");
throw new
HttpException(HttpResponse.__500_Internal_Server_Error, "Realm Not Configured");
}
// Handle pre-authenticated request
if (authenticator != null) {
// User authenticator.
user = authenticator.authenticate(realm, pathInContext,
request, response);
} else {
// don't know how authenticate
log.warn("Mis-configured Authenticator for " +
request.getPath());
throw new
HttpException(HttpResponse.__500_Internal_Server_Error, "Mis-configured
Authenticator for " + request.getPath());
}
return user;
} else if (authenticator instanceof FormAuthenticator &&
pathInContext.endsWith(FormAuthenticator.__J_SECURITY_CHECK)) {
/**
* This could be a post request to __J_SECURITY_CHECK.
*/
if (realm == null) {
log.warn("Realm Not Configured");
throw new
HttpException(HttpResponse.__500_Internal_Server_Error, "Realm Not Configured");
}
return authenticator.authenticate(realm, pathInContext, request,
response);
}
/**
* No authentication is required. Return the defaultPrincipal.
*/
ContextManager.setCurrentCaller(defaultPrincipal.getSubject());
return defaultPrincipal;
}
/**
* Generate the default principal from the security config.
*
* @param securityConfig The Geronimo security configuration.
* @return the default principal
* @throws GeronimoSecurityException
*/
protected JAASJettyPrincipal generateDefaultPrincipal(Security
securityConfig) throws GeronimoSecurityException {
JAASJettyPrincipal result = new JAASJettyPrincipal("default");
Subject defaultSubject = new Subject();
DefaultPrincipal principal = securityConfig.getDefaultPrincipal();
RealmPrincipal realmPrincipal =
ConfigurationUtil.generateRealmPrincipal(principal.getPrincipal(),
principal.getRealmName());
if (realmPrincipal == null) throw new
GeronimoSecurityException("Unable to create realm principal");
PrimaryRealmPrincipal primaryRealmPrincipal =
ConfigurationUtil.generatePrimaryRealmPrincipal(principal.getPrincipal(),
principal.getRealmName());
if (primaryRealmPrincipal == null) throw new
GeronimoSecurityException("Unable to create primary realm principal");
defaultSubject.getPrincipals().add(realmPrincipal);
defaultSubject.getPrincipals().add(primaryRealmPrincipal);
result.setSubject(defaultSubject);
return result;
}
public void doStart() throws WaitingException, Exception {
super.doStart();
/**
* Register our default principal with the ContextManager
*/
Subject defaultSubject = defaultPrincipal.getSubject();
ContextManager.registerSubject(defaultSubject);
SubjectId id = ContextManager.getSubjectId(defaultSubject);
defaultSubject.getPrincipals().add(new IdentificationPrincipal(id));
log.debug("Default subject " + id + " for JACC policy '" +
((JettyWebAppJACCContext) getHttpContext()).getPolicyContextID() + "'
registered.");
/**
* Get the JACC policy configuration that's associated with this
* web application and configure it with the geronimo security
* configuration. The work for this is done by the class
* JettyXMLConfiguration.
*/
try {
factory =
PolicyConfigurationFactory.getPolicyConfigurationFactory();
policyConfiguration =
factory.getPolicyConfiguration(policyContextID, true);
((JettyXMLConfiguration)
this.getConfiguration()).configure(policyConfiguration, securityConfig);
policyConfiguration.commit();
} catch (ClassNotFoundException e) {
// do nothing
} catch (PolicyContextException e) {
// do nothing
} catch (GeronimoSecurityException e) {
// do nothing
}
/**
* Register the role designates with the context manager.
*
* THIS MUST BE RUN AFTER JettyXMLConfiguration.configure()
*/
Iterator iter = roleDesignates.keySet().iterator();
while (iter.hasNext()) {
String roleName = (String) iter.next();
Subject roleDesignate = (Subject) roleDesignates.get(roleName);
ContextManager.registerSubject(roleDesignate);
id = ContextManager.getSubjectId(roleDesignate);
roleDesignate.getPrincipals().add(new
IdentificationPrincipal(id));
log.debug("Role designate " + id + " for role '" + roleName + "'
for JACC policy '" + ((JettyWebAppJACCContext)
getHttpContext()).getPolicyContextID() + "' registered.");
}
log.info("JettyWebAppJACCContext started with JACC policy '" +
policyContextID + "'");
}
public void doStop() throws WaitingException, Exception {
super.doStop();
/**
* Unregister the default principal and role designates
*/
log.debug("Default subject " +
ContextManager.getSubjectId(defaultPrincipal.getSubject()) + " for JACC policy
" + ((JettyWebAppJACCContext) getHttpContext()).getPolicyContextID() + "'
unregistered.");
ContextManager.unregisterSubject(defaultPrincipal.getSubject());
Iterator iter = roleDesignates.keySet().iterator();
while (iter.hasNext()) {
String roleName = (String) iter.next();
Subject roleDesignate = (Subject) roleDesignates.get(roleName);
ContextManager.unregisterSubject(roleDesignate);
log.debug("Role designate " +
ContextManager.getSubjectId(roleDesignate) + " for role '" + roleName + "' for
JACC policy '" + ((JettyWebAppJACCContext)
getHttpContext()).getPolicyContextID() + "' unregistered.");
}
/**
* Delete the policy configuration for this web application
*/
if (policyConfiguration != null) policyConfiguration.delete();
log.info("JettyWebAppJACCContext with JACC policy '" +
policyContextID + "' stopped");
}
public void doFail() {
super.doFail();
try {
if (policyConfiguration != null) policyConfiguration.delete();
} catch (PolicyContextException e) {
// do nothing
}
log.info("JettyWebAppJACCContext failed");
}
public static final GBeanInfo GBEAN_INFO;
static {
GBeanInfoFactory infoFactory = new GBeanInfoFactory("Jetty JACC
WebApplication Context", JettyWebAppJACCContext.class,
JettyWebAppContext.GBEAN_INFO);
infoFactory.addAttribute("SecurityConfig", Security.class, true);
infoFactory.addAttribute("PolicyContextID", String.class, true);
infoFactory.setConstructor(new String[]{
"Configuration",
"URI",
"JettyContainer",
"ComponentContext",
"PolicyContextID",
"SecurityConfig",
"UnshareableResources",
"ApplicationManagedSecurityResources",
"TransactionManager",
"TrackedConnectionAssociator",
"UserTransaction",
"classLoader"});
GBEAN_INFO = infoFactory.getBeanInfo();
}
public static GBeanInfo getGBeanInfo() {
return GBEAN_INFO;
}
}
1.12 +21 -7
incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/deployment/JettyModuleBuilder.java
Index: JettyModuleBuilder.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/jetty/src/java/org/apache/geronimo/jetty/deployment/JettyModuleBuilder.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- JettyModuleBuilder.java 22 Jun 2004 00:00:22 -0000 1.11
+++ JettyModuleBuilder.java 27 Jun 2004 20:37:38 -0000 1.12
@@ -52,7 +52,8 @@
import org.apache.geronimo.j2ee.deployment.Module;
import org.apache.geronimo.j2ee.deployment.ModuleBuilder;
import org.apache.geronimo.j2ee.deployment.WebModule;
-import org.apache.geronimo.jetty.JettyWebApplicationContext;
+import org.apache.geronimo.jetty.JettyWebAppContext;
+import org.apache.geronimo.jetty.JettyWebAppJACCContext;
import org.apache.geronimo.naming.deployment.ENCConfigBuilder;
import org.apache.geronimo.naming.java.ComponentContextBuilder;
import org.apache.geronimo.naming.java.ReadOnlyContext;
@@ -268,8 +269,16 @@
UserTransaction userTransaction = new UserTransactionImpl();
ReadOnlyContext compContext = buildComponentContext(earContext,
webModule, webApp, jettyWebApp, userTransaction, cl);
- GBeanMBean gbean = new
GBeanMBean(JettyWebApplicationContext.GBEAN_INFO, cl);
+ Security security = buildSecurityConfig(jettyWebApp);
+
+ GBeanMBean gbean;
try {
+ if (security == null) {
+ gbean = new GBeanMBean(JettyWebAppContext.GBEAN_INFO, cl);
+ } else {
+ gbean = new GBeanMBean(JettyWebAppJACCContext.GBEAN_INFO,
cl);
+ }
+
URI warRoot = null;
if (!webModule.getURI().equals(URI.create("/"))) {
warRoot = URI.create(webModule.getURI() + "/");
@@ -282,8 +291,10 @@
gbean.setAttribute("URI", warRoot);
gbean.setAttribute("ContextPath", webModule.getContextRoot());
gbean.setAttribute("ContextPriorityClassLoader",
Boolean.valueOf(jettyWebApp.getContextPriorityClassloader()));
- gbean.setAttribute("SecurityConfig",
buildSecurityConfig(jettyWebApp));
- gbean.setAttribute("PolicyContextID", PolicyContextID);
+ if (security != null) {
+ gbean.setAttribute("SecurityConfig", security);
+ gbean.setAttribute("PolicyContextID", PolicyContextID);
+ }
gbean.setAttribute("ComponentContext", compContext);
gbean.setAttribute("UserTransaction", userTransaction);
setResourceEnvironment(gbean, webApp.getResourceRefArray(),
jettyWebApp.getResourceRefArray());
@@ -343,10 +354,12 @@
}
private static Security buildSecurityConfig(JettyWebAppType jettyWebApp)
{
- Security security = new Security();
+ Security security = null;
JettySecurityType securityType = jettyWebApp.getSecurity();
if (securityType != null) {
+ security = new Security();
+
security.setUseContextHandler(securityType.getUseContextHandler());
JettyDefaultPrincipalType defaultPrincipalType =
securityType.getDefaultPrincipal();
@@ -378,7 +391,7 @@
role.getRealms().add(realm);
}
- security.getRollMappings().add(role);
+ security.getRoleMappings().add(role);
}
}
}
@@ -391,6 +404,7 @@
principal.setClassName(principalType.getClass1());
principal.setPrincipalName(principalType.getName());
+ principal.setDesignatedRunAs(principalType.isSetDesignatedRunAs());
return principal;
}
1.12 +5 -3
incubator-geronimo/modules/jetty/src/test/org/apache/geronimo/jetty/ApplicationTest.java
Index: ApplicationTest.java
===================================================================
RCS file:
/home/cvs/incubator-geronimo/modules/jetty/src/test/org/apache/geronimo/jetty/ApplicationTest.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- ApplicationTest.java 15 Jun 2004 21:37:39 -0000 1.11
+++ ApplicationTest.java 27 Jun 2004 20:37:38 -0000 1.12
@@ -53,13 +53,15 @@
private GBeanMBean tm;
private GBeanMBean ctc;
+ public void testDummy() throws Exception {
+ }
+
public void testApplication() throws Exception {
URL url =
Thread.currentThread().getContextClassLoader().getResource("deployables/war1/");
- GBeanMBean app = new
GBeanMBean(JettyWebApplicationContext.GBEAN_INFO);
+ GBeanMBean app = new GBeanMBean(JettyWebAppContext.GBEAN_INFO);
app.setAttribute("URI", URI.create(url.toString()));
app.setAttribute("ContextPath", "/test");
app.setAttribute("ComponentContext", null);
- app.setAttribute("PolicyContextID", null);
UserTransactionImpl userTransaction = new UserTransactionImpl();
app.setAttribute("UserTransaction", userTransaction);
app.setReferencePatterns("Configuration", Collections.EMPTY_SET);
1.1
incubator-geronimo/modules/jetty/src/test/org/apache/geronimo/jetty/SecurityTest.java
Index: SecurityTest.java
===================================================================
/**
*
* 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.jetty;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import junit.framework.TestCase;
import
org.apache.geronimo.connector.outbound.connectiontracking.ConnectionTrackingCoordinator;
import org.apache.geronimo.gbean.jmx.GBeanMBean;
import org.apache.geronimo.jetty.connector.HTTPConnector;
import org.apache.geronimo.kernel.Kernel;
import org.apache.geronimo.system.serverinfo.ServerInfo;
import org.apache.geronimo.transaction.GeronimoTransactionManager;
import org.apache.geronimo.transaction.UserTransactionImpl;
/**
* @version $Revision: 1.1 $ $Date: 2004/06/27 20:37:38 $
*/
public class SecurityTest extends TestCase {
private Kernel kernel;
private GBeanMBean container;
private ObjectName containerName;
private Set containerPatterns;
private ObjectName connectorName;
private MBeanServer mbServer;
private GBeanMBean connectorGBean;
private GBeanMBean serverInfoGBean;
private ObjectName serverInfoName;
private GBeanMBean jaasRealmGBean;
private ObjectName jaasRealmName;
private GBeanMBean propertiesRealmGBean;
private ObjectName propertiesRealmName;
private ObjectName loginServiceName;
private GBeanMBean loginServiceGBean;
private ObjectName appName;
private ObjectName tmName;
private ObjectName tcaName;
private GBeanMBean tm;
private GBeanMBean ctc;
public void testDummy() throws Exception {
}
public void XtestApplication() throws Exception {
URL url =
Thread.currentThread().getContextClassLoader().getResource("deployables/war3/");
GBeanMBean app = new GBeanMBean(JettyWebAppContext.GBEAN_INFO);
app.setAttribute("URI", URI.create(url.toString()));
app.setAttribute("ContextPath", "/test");
app.setAttribute("ComponentContext", null);
UserTransactionImpl userTransaction = new UserTransactionImpl();
app.setAttribute("UserTransaction", userTransaction);
app.setReferencePatterns("Configuration", Collections.EMPTY_SET);
app.setReferencePatterns("JettyContainer", containerPatterns);
app.setReferencePatterns("TransactionManager",
Collections.singleton(tmName));
app.setReferencePatterns("TrackedConnectionAssociator",
Collections.singleton(tcaName));
start(appName, app);
HttpURLConnection connection = (HttpURLConnection) new
URL("http://localhost:5678/test/protected/hello.txt").openConnection();
connection.setInstanceFollowRedirects(false);
assertEquals(HttpURLConnection.HTTP_MOVED_TEMP,
connection.getResponseCode());
String cookie = connection.getHeaderField("Set-Cookie");
String location = connection.getHeaderField("Location");
cookie = cookie.substring(0, cookie.lastIndexOf(';'));
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:5678/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();
}
private void start(ObjectName name, Object instance) throws Exception {
mbServer.registerMBean(instance, name);
mbServer.invoke(name, "start", null, null);
}
private void stop(ObjectName name) throws Exception {
mbServer.invoke(name, "stop", null, null);
mbServer.unregisterMBean(name);
}
protected void setUp() throws Exception {
containerName = new ObjectName("geronimo.jetty:role=Container");
containerPatterns = Collections.singleton(containerName);
connectorName = new ObjectName("geronimo.jetty:role=Connector");
appName = new ObjectName("geronimo.jetty:app=test");
tmName = new ObjectName("geronimo.test:role=TransactionManager");
tcaName = new
ObjectName("geronimo.test:role=ConnectionTrackingCoordinator");
kernel = new Kernel("geronimo.kernel", "test");
kernel.boot();
mbServer = kernel.getMBeanServer();
container = new GBeanMBean(JettyContainerImpl.GBEAN_INFO);
serverInfoGBean = new GBeanMBean(ServerInfo.GBEAN_INFO);
serverInfoName = new ObjectName("geronimo.system:role=ServerInfo");
serverInfoGBean.setAttribute("BaseDirectory", ".");
connectorGBean = new GBeanMBean(HTTPConnector.GBEAN_INFO);
connectorGBean.setAttribute("Port", new Integer(5678));
connectorGBean.setReferencePatterns("JettyContainer",
containerPatterns);
jaasRealmGBean = new
GBeanMBean("org.apache.geronimo.jetty.JAASJettyRealm");
jaasRealmName = new ObjectName("geronimo.jetty:role=JaasRealm");
jaasRealmGBean.setReferencePatterns("JettyContainer",
containerPatterns);
jaasRealmGBean.setAttribute("Name", "Test JAAS Realm");
jaasRealmGBean.setAttribute("LoginModuleName", "jaasTest");
loginServiceGBean = new
GBeanMBean("org.apache.geronimo.security.jaas.LoginService");
loginServiceName = new
ObjectName("geronimo.security:type=LoginService");
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");
propertiesRealmGBean = new
GBeanMBean("org.apache.geronimo.security.realm.providers.PropertiesFileSecurityRealm");
propertiesRealmName = new
ObjectName("geronimo.security:type=SecurityRealm,realm=demo-properties-realm");
propertiesRealmGBean.setReferencePatterns("ServerInfo",
Collections.singleton(serverInfoName));
propertiesRealmGBean.setAttribute("RealmName",
"demo-properties-realm");
propertiesRealmGBean.setAttribute("MaxLoginModuleAge", new Long(1 *
1000));
propertiesRealmGBean.setAttribute("UsersURI", (new File(new
File("."), "src/test-resources/data/users.properties")).toURI());
propertiesRealmGBean.setAttribute("GroupsURI", (new File(new
File("."), "src/test-resources/data/groups.properties")).toURI());
start(serverInfoName, serverInfoGBean);
start(propertiesRealmName, propertiesRealmGBean);
start(containerName, container);
start(loginServiceName, loginServiceGBean);
start(jaasRealmName, jaasRealmGBean);
start(connectorName, connectorGBean);
tm = new GBeanMBean(GeronimoTransactionManager.GBEAN_INFO);
Set patterns = new HashSet();
patterns.add(ObjectName.getInstance("geronimo.management:J2eeType=ManagedConnectionFactory,*"));
tm.setReferencePatterns("resourceManagers", patterns);
start(tmName, tm);
ctc = new GBeanMBean(ConnectionTrackingCoordinator.GBEAN_INFO);
start(tcaName, ctc);
}
protected void tearDown() throws Exception {
stop(tcaName);
stop(tmName);
stop(connectorName);
stop(jaasRealmName);
stop(loginServiceName);
stop(containerName);
stop(propertiesRealmName);
stop(serverInfoName);
kernel.shutdown();
}
}