JSEC-22 - implemented fix for DelegatingSubject to retain the SecurityManager instance (not null it out) upon logout for continued re-use.  Accompanied by DefaultSecurityManagerTest.testSubjectReuseAfterLogout() test case to verify.

git-svn-id: https://svn.apache.org/repos/asf/incubator/jsecurity/trunk@738004 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/core/src/org/jsecurity/subject/DelegatingSubject.java b/core/src/org/jsecurity/subject/DelegatingSubject.java
index af5166d..df60986 100644
--- a/core/src/org/jsecurity/subject/DelegatingSubject.java
+++ b/core/src/org/jsecurity/subject/DelegatingSubject.java
@@ -299,8 +299,14 @@
             this.session = null;
             this.principals = null;
             this.authenticated = false;
-            this.inetAddress = null;
-            this.securityManager = null;
+            //Don't set securityManager to null here - the Subject can be continued to be
+            //used, it is just considered anonymous at this point.  The SecurityManager instance is
+            //necessary if the subject would log in again or acquire a new session.  This is in response to
+            //https://issues.apache.org/jira/browse/JSEC-22
+            //this.securityManager = null;
+
+            //also keep the inetAddress to retain their location:
+            //this.inetAddress = null;
         }
     }
 
diff --git a/core/test/org/jsecurity/mgt/DefaultSecurityManagerTest.java b/core/test/org/jsecurity/mgt/DefaultSecurityManagerTest.java
index 254b76a..701ad31 100644
--- a/core/test/org/jsecurity/mgt/DefaultSecurityManagerTest.java
+++ b/core/test/org/jsecurity/mgt/DefaultSecurityManagerTest.java
@@ -18,6 +18,7 @@
  */
 package org.jsecurity.mgt;
 
+import org.jsecurity.SecurityUtils;
 import org.jsecurity.authc.AuthenticationToken;
 import org.jsecurity.authc.UsernamePasswordToken;
 import org.jsecurity.realm.text.PropertiesRealm;
@@ -45,17 +46,19 @@
         ThreadContext.clear();
         sm = new DefaultSecurityManager();
         sm.setRealm(new PropertiesRealm());
+        SecurityUtils.setSecurityManager(sm);
     }
 
     @After
     public void tearDown() {
+        SecurityUtils.setSecurityManager(null);
         sm.destroy();
         ThreadContext.clear();
     }
 
     @Test
     public void testDefaultConfig() {
-        Subject subject = sm.getSubject();
+        Subject subject = SecurityUtils.getSubject();
 
         AuthenticationToken token = new UsernamePasswordToken("guest", "guest");
         subject.login(token);
@@ -80,7 +83,7 @@
      */
     @Test
     public void testAutoCreateSessionAfterInvalidation() {
-        Subject subject = sm.getSubject();
+        Subject subject = SecurityUtils.getSubject();
         Session session = subject.getSession();
         Serializable origSessionId = session.getId();
 
@@ -103,4 +106,46 @@
         Object aValue = session.getAttribute(key);
         assertNull(aValue);
     }
+
+    /**
+     * Test that validates functionality for issue
+     * <a href="https://issues.apache.org/jira/browse/JSEC-22">JSEC-22</a>
+     */
+    public void testSubjectReuseAfterLogout() {
+
+        Subject subject = SecurityUtils.getSubject();
+
+        AuthenticationToken token = new UsernamePasswordToken("guest", "guest");
+        subject.login(token);
+        assertTrue(subject.isAuthenticated());
+        assertTrue("guest".equals(subject.getPrincipal()));
+        assertTrue(subject.hasRole("guest"));
+
+        Session session = subject.getSession();
+        Serializable firstSessionId = session.getId();
+
+        session.setAttribute("key", "value");
+        assertEquals(session.getAttribute("key"), "value");
+
+        subject.logout();
+
+        assertNull(subject.getSession(false));
+        assertNull(subject.getPrincipal());
+        assertNull(subject.getPrincipals());
+
+        subject.login( new UsernamePasswordToken("lonestarr", "vespa") );
+        assertTrue(subject.isAuthenticated());
+        assertTrue("lonestarr".equals(subject.getPrincipal()));
+        assertTrue(subject.hasRole("goodguy") );
+
+        assertNotNull( subject.getSession() );
+        assertFalse( firstSessionId.equals(subject.getSession().getId() ) );
+
+        subject.logout();
+
+        assertNull(subject.getSession(false));
+        assertNull(subject.getPrincipal());
+        assertNull(subject.getPrincipals());
+
+    }
 }