Author: dblevins
Date: Thu Sep 27 18:48:35 2007
New Revision: 580192

URL: http://svn.apache.org/viewvc?rev=580192&view=rev
Log:
Added SecurityService.disassociate  and SecurityService.logout and revised 
associate
Added generics to the SecurityService interface.
Revised the usage in the TomcatSecurityService

Added:
    openejb/trunk/openejb3/assembly/openejb-standalone/README.html
Modified:
    
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatSecurityService.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/SecurityServiceImpl.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicPolicyConfiguration.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/ri/sp/PseudoSecurityService.java
    
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/spi/SecurityService.java
    
openejb/trunk/openejb3/container/openejb-jee/src/test/java/org/apache/openejb/jee/JeeTest.java
    
openejb/trunk/openejb3/server/openejb-ejbd/src/main/java/org/apache/openejb/server/ejbd/EjbRequestHandler.java

Added: openejb/trunk/openejb3/assembly/openejb-standalone/README.html
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-standalone/README.html?rev=580192&view=auto
==============================================================================
--- openejb/trunk/openejb3/assembly/openejb-standalone/README.html (added)
+++ openejb/trunk/openejb3/assembly/openejb-standalone/README.html Thu Sep 27 
18:48:35 2007
@@ -0,0 +1,48 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML><HEAD><TITLE>Apache OpenEJB 6.0.14</TITLE>
+<META http-equiv=Content-Type content="text/html">
+</HEAD>
+<BODY>
+<P>
+<H3>Apache OpenEJB 3.0-beta-1</H3>
+<P></P>
+<p><font color="red">OpenEJB 3.0-beta-1 requires JRE 5.0 (not compatible with 
JRE 6.0).  Read the <a href="RELEASE-NOTES.txt">RELEASE-NOTES</a> for more 
details.</font></p>
+
+<p>Packaging Details (or "What Should I Download?")
+  <ul>
+      <li>
+          OpenEJB Standlone Server:
+          <ul>
+              <li><a 
href="openejb-3.0-beta-1-bin.zip">openejb-3.0-beta-1-bin.zip</a></li>
+              <li><a 
href="openejb-3.0-beta-1-bin.tar.gz">openejb-3.0-beta-1-bin.tar.gz</a></li>
+          </ul>
+      </li>
+      <li>
+          OpenEJB for Tomcat (deploy into a Tomcat 6.x server):
+          <ul>
+              <li><a href="openejb.war">openejb.war</a></li>
+          </ul>
+      </li>
+      <li>
+          EJB 3.0 and other examples:
+          <ul>
+              <li><a 
href="examples-3.0-beta-1.zip">examples-3.0-beta-1.zip</a></li>
+              <li><a 
href="examples-3.0-beta-1.tar.gz">examples-3.0-beta-1.tar.gz</a></li>
+          </ul>
+      </li>
+      <li>
+          Source:
+          <ul>
+              <li><a 
href="openejb-3.0-beta-1-src.zip">openejb-3.0-beta-1-src.zip</a></li>
+              <li><a 
href="openejb-3.0-beta-1-src.tar.gz">openejb-3.0-beta-1-src.tar.gz</a></li>
+          </ul>
+      </li>
+  </ul>
+</p>
+
+<P>Thank you for using <A href="http://openejb.apache.org/";>OpenEJB</A>!.
+</P>
+<P><B>The Apache OpenEJB Project</B> <BR><A
+href="http://openejb.apache.org/";>http://openejb.apache.org/</A> </P>
+<P>
+<P></P></BODY></HTML>

Modified: 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatSecurityService.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatSecurityService.java?rev=580192&r1=580191&r2=580192&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatSecurityService.java
 (original)
+++ 
openejb/trunk/openejb3/assembly/openejb-tomcat/src/main/java/org/apache/openejb/tomcat/TomcatSecurityService.java
 Thu Sep 27 18:48:35 2007
@@ -32,6 +32,7 @@
 import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.LinkedList;
+import java.util.UUID;
 
 public class TomcatSecurityService  extends AbstractSecurityService {
     static protected final ThreadLocal<LinkedList<Subject>> runAsStack = new 
ThreadLocal<LinkedList<Subject>>() {
@@ -55,14 +56,14 @@
         }
     }
 
-    public Object login(String realmName, String username, String password) 
throws LoginException {
+    public UUID login(String realmName, String username, String password) 
throws LoginException {
         if (defaultRealm == null) {
             throw new LoginException("No Tomcat realm available");
         }
 
         Principal principal = defaultRealm.authenticate(username, password);
         Subject subject = createSubject(defaultRealm, principal);
-        Object token = registerSubject(subject);
+        UUID token = registerSubject(subject);
         return token;
     }
 
@@ -99,13 +100,20 @@
     }
 
     public Object enterWebApp(Realm realm, Principal principal, String runAs) {
-        Subject newSubject = null;
+        UUID newToken = null;
         if (principal != null) {
-            newSubject = createSubject(realm, principal);
+            Subject newSubject = createSubject(realm, principal);
+            newToken = registerSubject(newSubject);
+        }
+
+        UUID oldToken = disassociate();
+        WebAppState webAppState = new WebAppState(oldToken, runAs != null);
+        try {
+            associate(newToken);
+        } catch (LoginException e) {
+            throw new IllegalStateException("Subject was registered, but 
cannot be associated with the SecurityService", e);
         }
 
-        WebAppState webAppState = new WebAppState(clientIdentity.get(), runAs 
!= null);
-        clientIdentity.set(newSubject);
 
         if (runAs != null) {
             Subject runAsSubject = createRunAsSubject(runAs);
@@ -118,7 +126,12 @@
     public void exitWebApp(Object state) {
         if (state instanceof WebAppState) {
             WebAppState webAppState = (WebAppState) state;
-            clientIdentity.set(webAppState.oldSubject);
+            disassociate();
+            try {
+                if (webAppState.oldToken != null) 
associate(webAppState.oldToken);
+            } catch (LoginException e) {
+                throw new IllegalStateException("Subject was registered, but 
cannot be associated with the SecurityService", e);
+            }
             if (webAppState.hadRunAs) {
                 runAsStack.get().removeFirst();
             }
@@ -224,12 +237,12 @@
     }
 
     private static class WebAppState {
-        private final Subject oldSubject;
+        private final UUID oldToken;
         private final boolean hadRunAs;
 
 
-        public WebAppState(Subject oldSubject, boolean hadRunAs) {
-            this.oldSubject = oldSubject;
+        public WebAppState(UUID oldSubject, boolean hadRunAs) {
+            this.oldToken = oldSubject;
             this.hadRunAs = hadRunAs;
         }
     }

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java?rev=580192&r1=580191&r2=580192&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/AbstractSecurityService.java
 Thu Sep 27 18:48:35 2007
@@ -22,7 +22,9 @@
 import org.apache.openejb.core.ThreadContext;
 import org.apache.openejb.core.CoreDeploymentInfo;
 import org.apache.openejb.core.security.jacc.BasicJaccProvider;
+import org.apache.openejb.core.security.jacc.BasicPolicyConfiguration;
 import org.apache.openejb.InterfaceType;
+import org.apache.openejb.loader.SystemInstance;
 
 import javax.security.auth.Subject;
 import javax.security.auth.login.LoginException;
@@ -47,12 +49,16 @@
 import java.util.Map;
 import java.util.LinkedHashSet;
 import java.util.concurrent.ConcurrentHashMap;
-import java.io.Serializable;
 import java.lang.reflect.Method;
 
-public abstract class AbstractSecurityService implements SecurityService, 
ThreadContextListener {
+/**
+ * This security service chooses a UUID as its token as this can be serialized
+ * to clients, is mostly secure, and can be deserialized in a client vm without
+ * addition openejb-core classes.
+ */
+public abstract class AbstractSecurityService implements 
SecurityService<UUID>, ThreadContextListener, 
BasicPolicyConfiguration.RoleResolver {
     static private final Map<Object, Identity> identities = new 
ConcurrentHashMap<Object, Identity>();
-    static protected final ThreadLocal<Subject> clientIdentity = new 
ThreadLocal<Subject>();
+    static private final ThreadLocal<Identity> clientIdentity = new 
ThreadLocal<Identity>();
     protected final String defaultUser = "guest";
     protected final Subject defaultSubject;
     protected final SecurityContext defaultContext;
@@ -67,6 +73,8 @@
 
         defaultSubject = createSubject(defaultUser);
         defaultContext = new SecurityContext(defaultSubject);
+
+        
SystemInstance.get().setComponent(BasicPolicyConfiguration.RoleResolver.class, 
this);
     }
 
 
@@ -81,7 +89,7 @@
     public void init(Properties props) throws Exception {
     }
 
-    public Object login(String username, String password) throws 
LoginException {
+    public UUID login(String username, String password) throws LoginException {
         return login(realmName, username, password);
     }
 
@@ -110,10 +118,9 @@
 
         } else if (securityContext == null) {
 
-            Subject subject = clientIdentity.get();
-
-            if (subject != null){
-                securityContext = new SecurityContext(subject);
+            Identity identity = clientIdentity.get();
+            if (identity != null){
+                securityContext = new SecurityContext(identity.subject);
             } else {
                 securityContext = defaultContext;
             }
@@ -142,39 +149,41 @@
         }
     }
 
-    protected Object registerSubject(Subject subject) {
+    protected UUID registerSubject(Subject subject) {
         Identity identity = new Identity(subject);
-        Serializable token = identity.getToken();
+        UUID token = identity.getToken();
         identities.put(token, identity);
         return token;
     }
 
-    protected void unregisterSubject(Object securityIdentity) {
+    public void logout(UUID securityIdentity) throws LoginException {
+        Identity identity = identities.get(securityIdentity);
+        if (identity == null) throw new LoginException("Identity is not 
currently logged in: " + securityIdentity);
         identities.remove(securityIdentity);
     }
 
-    public Object associate(Object securityIdentity) throws LoginException {
-        Object oldIdentity = new SubjectHolder(clientIdentity.get());
-
-        Subject subject  = null;
-        if (securityIdentity != null) {
+    protected void unregisterSubject(Object securityIdentity) {
+        identities.remove(securityIdentity);
+    }
 
-            Identity identity = identities.get(securityIdentity);
-            if (identity == null) throw new LoginException("Identity does not 
exist: " + securityIdentity);
+    public void associate(UUID securityIdentity) throws LoginException {
+        if (clientIdentity.get() != null) throw new LoginException("Thread 
already associated with a client identity.  Refusing to overwrite.");
+        if (securityIdentity == null) throw new NullPointerException("The 
security token passed in is null");
 
-            subject = identity.subject;
-        }
-        clientIdentity.set(subject);
+        // The securityIdentity token must associated with a logged in Identity
+        Identity identity = identities.get(securityIdentity);
+        if (identity == null) throw new LoginException("Identity is not 
currently logged in: " + securityIdentity);
 
-        return oldIdentity;
+        clientIdentity.set(identity);
     }
 
-    public void disassociate(Object oldIdentity) {
-        if (!(oldIdentity instanceof SubjectHolder)) {
-            throw new IllegalArgumentException("oldIdentity is not an object 
returned from associate");
+    public UUID disassociate() {
+        try {
+            Identity identity = clientIdentity.get();
+            return (identity == null)? null: identity.getToken();
+        } finally {
+            clientIdentity.remove();
         }
-        SubjectHolder subjectHolder = (SubjectHolder) oldIdentity;
-        clientIdentity.set(subjectHolder.subject);
     }
 
     public boolean isCallerInRole(String role) {
@@ -287,7 +296,7 @@
             return subject;
         }
 
-        public Serializable getToken() {
+        public UUID getToken() {
             return token;
         }
     }
@@ -330,14 +339,6 @@
 
         public String getName() {
             return name;
-        }
-    }
-
-    private static class SubjectHolder {
-        private final Subject subject;
-
-        public SubjectHolder(Subject subject) {
-            this.subject = subject;
         }
     }
 }

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/SecurityServiceImpl.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/SecurityServiceImpl.java?rev=580192&r1=580191&r2=580192&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/SecurityServiceImpl.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/SecurityServiceImpl.java
 Thu Sep 27 18:48:35 2007
@@ -23,6 +23,7 @@
 import javax.security.auth.login.LoginContext;
 import javax.security.auth.login.LoginException;
 import java.net.URL;
+import java.util.UUID;
 
 /**
  * @version $Rev$ $Date$
@@ -54,7 +55,7 @@
         System.setProperty("java.security.auth.login.config", 
loginConfig.toExternalForm());
     }
 
-    public Object login(String realmName, String username, String password) 
throws LoginException {
+    public UUID login(String realmName, String username, String password) 
throws LoginException {
         if (realmName == null){
             realmName = getRealmName();
         }

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicPolicyConfiguration.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicPolicyConfiguration.java?rev=580192&r1=580191&r2=580192&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicPolicyConfiguration.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/security/jacc/BasicPolicyConfiguration.java
 Thu Sep 27 18:48:35 2007
@@ -63,8 +63,8 @@
         Principal[] principals = domain.getPrincipals();
         if (principals.length == 0) return false;
 
-        SecurityService securityService = 
SystemInstance.get().getComponent(SecurityService.class);
-        Set<String> roles = securityService.getLogicalRoles(principals, 
rolePermissionsMap.keySet());
+        RoleResolver roleResolver = 
SystemInstance.get().getComponent(RoleResolver.class);
+        Set<String> roles = roleResolver.getLogicalRoles(principals, 
rolePermissionsMap.keySet());
 
         for (String role : roles) {
             Permissions permissions = rolePermissionsMap.get(role);
@@ -180,5 +180,9 @@
 
     int getState() {
         return state;
+    }
+
+    public interface RoleResolver {
+        public Set<String> getLogicalRoles(Principal[] principals, Set<String> 
logicalRoles);
     }
 }

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/ri/sp/PseudoSecurityService.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/ri/sp/PseudoSecurityService.java?rev=580192&r1=580191&r2=580192&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/ri/sp/PseudoSecurityService.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/ri/sp/PseudoSecurityService.java
 Thu Sep 27 18:48:35 2007
@@ -49,8 +49,14 @@
         return Collections.emptySet();
     }
 
-    public Object associate(Object securityIdentity) throws LoginException {
+    public void associate(Object securityIdentity) throws LoginException {
+    }
+
+    public Object disassociate() {
         return null;
+    }
+
+    public void logout(Object securityIdentity) throws LoginException {
     }
 
     public boolean isCallerInRole(String role) {

Modified: 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/spi/SecurityService.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/spi/SecurityService.java?rev=580192&r1=580191&r2=580192&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/spi/SecurityService.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/spi/SecurityService.java
 Thu Sep 27 18:48:35 2007
@@ -18,32 +18,41 @@
 
 import org.apache.openejb.InterfaceType;
 
-import javax.security.auth.Subject;
 import javax.security.auth.login.LoginException;
 import java.lang.reflect.Method;
 import java.security.Principal;
-import java.util.Collection;
-import java.util.Set;
 
-public interface SecurityService extends Service {
+/**
+ * The generic value T is any serializable token of the SecurityService
+ * implementations choosing.   This token only needs to be understandable
+ * by the SecurityService internally and need not be a publicly usable class
+ * type.  No part of the outlying system will make any assumptions as to the
+ * type of the object.  The use of a java generic type is to express the
+ * required symmetry in the interface.  
+ *
+ */
+public interface SecurityService<T> extends Service {
     /**
-     * Active
+     *
      */
-    public Object login(String user, String pass) throws LoginException;
-    public Object login(String securityRealm, String user, String pass) throws 
LoginException;
+    public T login(String user, String pass) throws LoginException;
+
+    public T login(String securityRealm, String user, String pass) throws 
LoginException;
 
+    /**
+     * Active
+     */
+    public void associate(T securityIdentity) throws LoginException;
 
-    public Set<String> getLogicalRoles(Principal[] principals, Set<String> 
logicalRoles);
-    
     /**
      * Active
      */
-    public Object associate(Object securityIdentity) throws LoginException;
+    public T disassociate();
 
     /**
      * Active
      */
-//    public Object logout(Object securityIdentity) throws LoginException;
+    public void logout(T securityIdentity) throws LoginException;
 
     /**
      * Active

Modified: 
openejb/trunk/openejb3/container/openejb-jee/src/test/java/org/apache/openejb/jee/JeeTest.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-jee/src/test/java/org/apache/openejb/jee/JeeTest.java?rev=580192&r1=580191&r2=580192&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/container/openejb-jee/src/test/java/org/apache/openejb/jee/JeeTest.java
 (original)
+++ 
openejb/trunk/openejb3/container/openejb-jee/src/test/java/org/apache/openejb/jee/JeeTest.java
 Thu Sep 27 18:48:35 2007
@@ -18,6 +18,7 @@
 package org.apache.openejb.jee;
 
 import junit.framework.TestCase;
+import junit.framework.AssertionFailedError;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
@@ -30,6 +31,8 @@
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.FileOutputStream;
+import java.io.File;
 
 /**
  * @version $Revision$ $Date$
@@ -78,9 +81,27 @@
         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         marshaller.marshal(object, baos);
 
-        String actual = new String(baos.toByteArray());
+        byte[] bytes = baos.toByteArray();
+        String actual = new String(bytes);
 
-        assertEquals(expected, actual);
+        try {
+            assertEquals(expected, actual);
+        } catch (AssertionFailedError e) {
+            writeToTmpFile(bytes, xmlFileName);
+            throw e;            
+        }
+    }
+
+    private void writeToTmpFile(byte[] bytes, String xmlFileName) {
+        try {
+            File tempFile = File.createTempFile("jaxb-output", "xml");
+            FileOutputStream out = new FileOutputStream(tempFile);
+            out.write(bytes);
+            out.close();
+            System.out.println("Jaxb output of "+xmlFileName+" written to 
"+tempFile.getAbsolutePath());
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
     }
 
     private java.lang.String readContent(InputStream in) throws IOException {

Modified: 
openejb/trunk/openejb3/server/openejb-ejbd/src/main/java/org/apache/openejb/server/ejbd/EjbRequestHandler.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-ejbd/src/main/java/org/apache/openejb/server/ejbd/EjbRequestHandler.java?rev=580192&r1=580191&r2=580192&view=diff
==============================================================================
--- 
openejb/trunk/openejb3/server/openejb-ejbd/src/main/java/org/apache/openejb/server/ejbd/EjbRequestHandler.java
 (original)
+++ 
openejb/trunk/openejb3/server/openejb-ejbd/src/main/java/org/apache/openejb/server/ejbd/EjbRequestHandler.java
 Thu Sep 27 18:48:35 2007
@@ -105,9 +105,10 @@
             return;
         }
 
+        SecurityService securityService = 
SystemInstance.get().getComponent(SecurityService.class);
         try {
-            SecurityService securityService = 
SystemInstance.get().getComponent(SecurityService.class);
-            securityService.associate(req.getClientIdentity());
+            Object clientIdentity = req.getClientIdentity();
+            if (clientIdentity != null) 
securityService.associate(clientIdentity);
         } catch (Throwable t) {
             replyWithFatalError(out, t, "Security system failed to associate 
thread with the thread");
             return;
@@ -197,6 +198,7 @@
             } catch (java.io.IOException ie) {
                 logger.fatal("Couldn't write EjbResponse to output stream", 
ie);
             }
+            securityService.disassociate();
             call.reset();
             EJBHomeProxyHandle.resolver.set(null);
             EJBObjectProxyHandle.resolver.set(null);


Reply via email to