You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2006/04/19 10:44:25 UTC

svn commit: r395178 - in /geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty: JAASJettyRealm.java JettyContainer.java JettyContainerImpl.java JettyServer.java JettyWebAppContext.java interceptor/SecurityContextBeforeAfter.java

Author: djencks
Date: Wed Apr 19 01:44:23 2006
New Revision: 395178

URL: http://svn.apache.org/viewcvs?rev=395178&view=rev
Log:
GERONIMO-1425 port from branch 1.2, correct security for access to unsecured pages after login

Modified:
    geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyRealm.java
    geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainer.java
    geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainerImpl.java
    geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServer.java
    geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyWebAppContext.java
    geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/interceptor/SecurityContextBeforeAfter.java

Modified: geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyRealm.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyRealm.java?rev=395178&r1=395177&r2=395178&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyRealm.java (original)
+++ geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JAASJettyRealm.java Wed Apr 19 01:44:23 2006
@@ -43,17 +43,17 @@
 public class JAASJettyRealm implements UserRealm {
     private static Log log = LogFactory.getLog(JAASJettyRealm.class);
 
-    private final String realmName;
-    private final String loginDomainName;
+    private final String webRealmName;
+    private final String geronimoRealmName;
     private final HashMap userMap = new HashMap();
 
-    public JAASJettyRealm(String realmName, String loginDomainName) {
-        this.realmName = realmName;
-        this.loginDomainName = loginDomainName;
+    public JAASJettyRealm(String realmName, String geronimoRealmName) {
+        this.webRealmName = realmName;
+        this.geronimoRealmName = geronimoRealmName;
     }
 
     public String getName() {
-        return realmName;
+        return webRealmName;
     }
 
     public Principal getPrincipal(String username) {
@@ -90,7 +90,7 @@
                 }
 
                 //set up the login context
-                LoginContext loginContext = new LoginContext(loginDomainName, callbackHandler);
+                LoginContext loginContext = new LoginContext(geronimoRealmName, callbackHandler);
                 loginContext.login();
                 callbackHandler.clear();
 
@@ -165,6 +165,18 @@
     public Principal popRole(Principal user) {
         ContextManager.setCurrentCaller(((JAASJettyPrincipal) user).pop());
         return user;
+    }
+
+    public int hashCode() {
+        return webRealmName.hashCode() * 37 ^ geronimoRealmName.hashCode();
+    }
+
+    public boolean equals(Object other) {
+        if (other == null || other.getClass() != JAASJettyRealm.class) {
+            return false;
+        }
+        JAASJettyRealm otherRealm = (JAASJettyRealm) other;
+        return webRealmName.equals(otherRealm.webRealmName) && geronimoRealmName.equals(otherRealm.geronimoRealmName);
     }
 
 }

Modified: geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainer.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainer.java?rev=395178&r1=395177&r2=395178&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainer.java (original)
+++ geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainer.java Wed Apr 19 01:44:23 2006
@@ -35,7 +35,7 @@
 
     void removeContext(HttpContext context);
 
-    void addRealm(UserRealm realm);
+    UserRealm addRealm(UserRealm realm);
 
     void removeRealm(UserRealm realm);
 

Modified: geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainerImpl.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainerImpl.java?rev=395178&r1=395177&r2=395178&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainerImpl.java (original)
+++ geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyContainerImpl.java Wed Apr 19 01:44:23 2006
@@ -145,8 +145,8 @@
         server.removeContext(context);
     }
 
-    public void addRealm(UserRealm realm) {
-        server.addRealm(realm);
+    public UserRealm addRealm(UserRealm realm) {
+        return server.addRealm(realm);
     }
 
     public void removeRealm(UserRealm realm) {

Modified: geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServer.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServer.java?rev=395178&r1=395177&r2=395178&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServer.java (original)
+++ geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyServer.java Wed Apr 19 01:44:23 2006
@@ -20,7 +20,6 @@
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.geronimo.security.ContextManager;
 import org.mortbay.http.HttpRequest;
 import org.mortbay.http.UserRealm;
 import org.mortbay.jetty.Server;
@@ -33,14 +32,9 @@
     private final Map realmDelegates = new HashMap();
 
     public UserRealm addRealm(UserRealm realm) {
-        RealmDelegate delegate = (RealmDelegate) realmDelegates.get(realm.getName());
-        if (delegate == null) {
-            delegate = new RealmDelegate(realm.getName());
-            realmDelegates.put(realm.getName(), delegate);
-        }
-        delegate.delegate = realm;
-
-        return delegate;
+        RealmDelegate delegate = (RealmDelegate) getRealm(realm.getName());
+        delegate.addDelegate(realm);
+        return delegate.delegate;
     }
 
     public UserRealm getRealm(String realmName) {
@@ -53,17 +47,37 @@
         return delegate;
     }
 
-    public void removeRealm(UserRealm realm) {
-        realmDelegates.remove(realm.getName());
+    public synchronized void removeRealm(UserRealm realm) {
+        RealmDelegate delegate = (RealmDelegate) realmDelegates.get(realm.getName());
+        if (delegate != null) {
+            if (delegate.removeDelegate() == 0) {
+                realmDelegates.remove(realm.getName());
+            }
+        }
     }
 
-    private class RealmDelegate implements UserRealm {
+    private static class RealmDelegate implements UserRealm {
 
         private UserRealm delegate;
         private final String name;
+        private int  count;
 
         private RealmDelegate(String name) {
             this.name = name;
+        }
+
+        private synchronized void addDelegate(UserRealm newDelegate) {
+            if (delegate != null && !delegate.equals(newDelegate)) {
+                throw new IllegalArgumentException("Inconsistent assigment of user realm: old: " + delegate + ", new: " + newDelegate);
+            }
+            if (delegate == null) {
+                delegate = newDelegate;
+            }
+            count++;
+        }
+
+        private int removeDelegate() {
+            return count--;
         }
 
         public String getName() {

Modified: geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyWebAppContext.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyWebAppContext.java?rev=395178&r1=395177&r2=395178&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyWebAppContext.java (original)
+++ geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/JettyWebAppContext.java Wed Apr 19 01:44:23 2006
@@ -45,10 +45,7 @@
 import org.apache.geronimo.transaction.TrackedConnectionAssociator;
 import org.apache.geronimo.transaction.context.OnlineUserTransaction;
 import org.apache.geronimo.transaction.context.TransactionContextManager;
-import org.mortbay.http.Authenticator;
-import org.mortbay.http.HttpException;
-import org.mortbay.http.HttpRequest;
-import org.mortbay.http.HttpResponse;
+import org.mortbay.http.*;
 import org.mortbay.jetty.servlet.AbstractSessionManager;
 import org.mortbay.jetty.servlet.Dispatcher;
 import org.mortbay.jetty.servlet.FilterHolder;
@@ -104,11 +101,15 @@
     private String sessionManager;
 
 
-    public class SessionManagerConfiguration implements WebApplicationContext.Configuration {
+    public static class SessionManagerConfiguration implements WebApplicationContext.Configuration {
 
         private WebApplicationContext webAppContext;
 
 
+        public SessionManagerConfiguration() {
+        }
+
+
         public void setWebApplicationContext(WebApplicationContext webAppContext) {
             this.webAppContext = webAppContext;
         }
@@ -126,9 +127,12 @@
 
         public void configureWebApp() throws Exception {
             //setup a SessionManager
-            if (getSessionManager() != null) {
-                Class clazz = Thread.currentThread().getContextClassLoader().loadClass(getSessionManager());
+            log.debug("About to configure a SessionManager");
+            String sessionManagerClassName = ((JettyWebAppContext) webAppContext).getSessionManager();
+            if (sessionManagerClassName != null) {
+                Class clazz = Thread.currentThread().getContextClassLoader().loadClass(sessionManagerClassName);
                 Object o = clazz.newInstance();
+                log.debug("Setting SessionManager type=" + clazz.getName() + " instance=" + o);
                 this.webAppContext.getServletHandler().setSessionManager((SessionManager) o);
             }
         }
@@ -260,14 +264,15 @@
         interceptor = new ThreadClassloaderBeforeAfter(interceptor, index++, index++, this.webClassLoader);
         interceptor = new WebApplicationContextBeforeAfter(interceptor, index++, this);
 //JACC
+
         if (securityRealmName != null) {
             if (roleDesignateSource == null) {
                 throw new IllegalArgumentException("RoleDesignateSource must be supplied for a secure web app");
             }
             Map roleDesignates = roleDesignateSource.getRoleDesignateMap();
             //set the JAASJettyRealm as our realm.
-            JAASJettyRealm realm = new JAASJettyRealm(realmName, securityRealmName);
-            setRealm(realm);
+            UserRealm realm = new JAASJettyRealm(realmName, securityRealmName);
+            realm = jettyContainer.addRealm(realm);
             this.securityInterceptor = new SecurityContextBeforeAfter(interceptor, index++, index++, policyContextID, defaultPrincipal, authenticator, checkedPermissions, excludedPermissions, roleDesignates, realm, classLoader);
             interceptor = this.securityInterceptor;
         } else {
@@ -374,7 +379,7 @@
         }
 
         if (securityInterceptor != null) {
-            securityInterceptor.stop();
+            securityInterceptor.stop(jettyContainer);
         }
         Object context = enterContextScope(null, null);
         try {

Modified: geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/interceptor/SecurityContextBeforeAfter.java
URL: http://svn.apache.org/viewcvs/geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/interceptor/SecurityContextBeforeAfter.java?rev=395178&r1=395177&r2=395178&view=diff
==============================================================================
--- geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/interceptor/SecurityContextBeforeAfter.java (original)
+++ geronimo/branches/1.1/modules/jetty/src/java/org/apache/geronimo/jetty/interceptor/SecurityContextBeforeAfter.java Wed Apr 19 01:44:23 2006
@@ -16,35 +16,29 @@
  */
 package org.apache.geronimo.jetty.interceptor;
 
-import java.io.IOException;
-import java.security.AccessControlContext;
-import java.security.AccessControlException;
-import java.security.PermissionCollection;
-import java.security.Principal;
-import java.util.Map;
-import javax.security.auth.Subject;
-import javax.security.jacc.PolicyContext;
-import javax.security.jacc.WebResourcePermission;
-import javax.security.jacc.WebUserDataPermission;
-import javax.servlet.http.HttpServletRequest;
-
-import org.mortbay.http.Authenticator;
-import org.mortbay.http.HttpException;
-import org.mortbay.http.HttpRequest;
-import org.mortbay.http.HttpResponse;
-import org.mortbay.http.SecurityConstraint;
-import org.mortbay.http.UserRealm;
-import org.mortbay.jetty.servlet.FormAuthenticator;
-import org.mortbay.jetty.servlet.ServletHttpRequest;
-
-import org.apache.geronimo.common.GeronimoSecurityException;
 import org.apache.geronimo.common.DeploymentException;
+import org.apache.geronimo.common.GeronimoSecurityException;
 import org.apache.geronimo.jetty.JAASJettyPrincipal;
+import org.apache.geronimo.jetty.JettyContainer;
 import org.apache.geronimo.security.ContextManager;
 import org.apache.geronimo.security.IdentificationPrincipal;
 import org.apache.geronimo.security.SubjectId;
 import org.apache.geronimo.security.deploy.DefaultPrincipal;
 import org.apache.geronimo.security.util.ConfigurationUtil;
+import org.mortbay.http.*;
+import org.mortbay.jetty.servlet.FormAuthenticator;
+import org.mortbay.jetty.servlet.ServletHttpRequest;
+
+import javax.security.auth.Subject;
+import javax.security.jacc.PolicyContext;
+import javax.security.jacc.WebResourcePermission;
+import javax.security.jacc.WebUserDataPermission;
+import java.io.IOException;
+import java.security.AccessControlContext;
+import java.security.AccessControlException;
+import java.security.PermissionCollection;
+import java.security.Principal;
+import java.util.Map;
 
 
 /**
@@ -77,8 +71,10 @@
                                       PermissionCollection checkedPermissions,
                                       PermissionCollection excludedPermissions,
                                       Map roleDesignates,
-                                      UserRealm realm, ClassLoader classLoader)
-    {
+                                      UserRealm realm, ClassLoader classLoader) {
+        assert realm != null;
+        assert authenticator != null;
+
         this.next = next;
         this.policyContextIDIndex = policyContextIDIndex;
         this.webAppContextIndex = webAppContextIndex;
@@ -107,17 +103,13 @@
         ContextManager.registerSubject(defaultSubject);
         SubjectId id = ContextManager.getSubjectId(defaultSubject);
         defaultSubject.getPrincipals().add(new IdentificationPrincipal(id));
-
-//        log.debug("Default subject " + id + " for JACC policy '" + policyContextID + "' registered.");
-
-
         this.realm = realm;
-//        log.debug("JettyWebAppJACCContext started with JACC policy '" + policyContextID + "'");
     }
 
-    public void stop() {
+    public void stop(JettyContainer jettyContainer) {
         Subject defaultSubject = this.defaultPrincipal.getSubject();
         ContextManager.unregisterSubject(defaultSubject);
+        jettyContainer.removeRealm(realm);
     }
 
     public void before(Object[] context, HttpRequest httpRequest, HttpResponse httpResponse) {
@@ -129,7 +121,7 @@
 
         if (httpRequest != null) {
             ServletHttpRequest request = (ServletHttpRequest) httpRequest.getWrapper();
-            PolicyContext.setHandlerData((HttpServletRequest) request);
+            PolicyContext.setHandlerData(request);
         }
 
         if (next != null) {
@@ -188,7 +180,18 @@
         }
 
         try {
-            Principal user = obtainUser(pathInContext, request, response);
+            ServletHttpRequest servletHttpRequest = (ServletHttpRequest) request.getWrapper();
+            String transportType;
+            if (request.isConfidential()) {
+                transportType = "CONFIDENTIAL";
+            } else if (request.isIntegral()) {
+                transportType = "INTEGRAL";
+            } else {
+                transportType = "NONE";
+            }
+            WebUserDataPermission wudp = new WebUserDataPermission(servletHttpRequest.getServletPath(), new String[]{servletHttpRequest.getMethod()}, transportType);
+            WebResourcePermission webResourcePermission = new WebResourcePermission(servletHttpRequest);
+            Principal user = obtainUser(pathInContext, request, response, webResourcePermission, wudp);
 
             if (user == null) {
                 return false;
@@ -198,27 +201,17 @@
             }
 
             AccessControlContext acc = ContextManager.getCurrentContext();
-            ServletHttpRequest servletHttpRequest = (ServletHttpRequest) request.getWrapper();
 
             /**
              * JACC v1.0 secion 4.1.1
              */
 
-            String transportType;
-            if (request.isConfidential()) {
-                transportType = "CONFIDENTIAL";
-            } else if (request.isIntegral()) {
-                transportType = "INTEGRAL";
-            } else {
-                transportType = "NONE";
-            }
-            WebUserDataPermission wudp = new WebUserDataPermission(servletHttpRequest.getServletPath(), new String[]{servletHttpRequest.getMethod()}, transportType);
             acc.checkPermission(wudp);
 
             /**
              * JACC v1.0 secion 4.1.2
              */
-            acc.checkPermission(new WebResourcePermission(servletHttpRequest));
+            acc.checkPermission(webResourcePermission);
         } catch (HttpException he) {
             response.sendError(he.getCode(), he.getReason());
             return false;
@@ -245,41 +238,29 @@
      *         security checking should not proceed and servlet handling should proceed,
      *         e.g. login page.
      */
-    private Principal obtainUser(String pathInContext, HttpRequest request, HttpResponse response) throws IOException, IOException {
-        ServletHttpRequest servletHttpRequest = (ServletHttpRequest) request.getWrapper();
-        WebResourcePermission resourcePermission = new WebResourcePermission(servletHttpRequest);
-        WebUserDataPermission dataPermission = new WebUserDataPermission(servletHttpRequest);
+    private Principal obtainUser(String pathInContext, HttpRequest request, HttpResponse response, WebResourcePermission resourcePermission, WebUserDataPermission dataPermission) throws IOException, IOException {
         boolean unauthenticated = !(checked.implies(resourcePermission) || checked.implies(dataPermission));
         boolean forbidden = excludedPermissions.implies(resourcePermission) || excludedPermissions.implies(dataPermission);
 
-//       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)) {
+            return authenticator.authenticate(realm, pathInContext, request, response);
+        } 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);
+        }
+
+        //attempt to access an unprotected resource that is not the j_security_check.
+        //if we are logged in, return the logged in principal.
+        if (request != null) {
+            //null response appears to prevent redirect to login page
+            Principal user = authenticator.authenticate(realm, pathInContext, request, null);
+            if (user != null) {
+                return user;
+            }
         }
 
         /**