You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shiro.apache.org by bd...@apache.org on 2022/06/17 21:10:09 UTC

[shiro] 01/01: Reduce the scope of the ThreadLocals used in SecurityManagerTestSupport

This is an automated email from the ASF dual-hosted git repository.

bdemers pushed a commit to branch sec-manager-tests
in repository https://gitbox.apache.org/repos/asf/shiro.git

commit ca87a3a462207b4de93f49ba6463433257e254f2
Author: Brian Demers <bd...@apache.org>
AuthorDate: Fri Jun 17 17:10:02 2022 -0400

    Reduce the scope of the ThreadLocals used in SecurityManagerTestSupport
    
    Individual test methods can scope the usage of a SecurityManger and Subject to specific methods.
---
 .../authz/aop/PermissionAnnotationHandlerTest.java |   8 +-
 .../shiro/authz/aop/RoleAnnotationHandlerTest.java |   8 +-
 .../SubjectAwareExecutorServiceTest.java           |  10 +-
 .../shiro/concurrent/SubjectAwareExecutorTest.java |   2 +-
 .../shiro/test/SecurityManagerTestSupport.java     |  41 +++-
 .../BearerHttpFilterAuthenticationTest.groovy      |  76 ++++---
 .../authc/BasicHttpFilterAuthenticationTest.java   | 237 +++++++++++----------
 .../web/filter/authz/AuthorizationFilterTest.java  |  76 ++++---
 8 files changed, 263 insertions(+), 195 deletions(-)

diff --git a/core/src/test/java/org/apache/shiro/authz/aop/PermissionAnnotationHandlerTest.java b/core/src/test/java/org/apache/shiro/authz/aop/PermissionAnnotationHandlerTest.java
index a3c3e1f2..50294b7a 100644
--- a/core/src/test/java/org/apache/shiro/authz/aop/PermissionAnnotationHandlerTest.java
+++ b/core/src/test/java/org/apache/shiro/authz/aop/PermissionAnnotationHandlerTest.java
@@ -56,7 +56,9 @@ public class PermissionAnnotationHandlerTest extends SecurityManagerTestSupport
 	    }
         };
 
-        assertThrows(UnauthenticatedException.class, () -> handler.assertAuthorized(requiresPermissionAnnotation));
+        runWithSubject(subject -> {
+            assertThrows(UnauthenticatedException.class, () -> handler.assertAuthorized(requiresPermissionAnnotation));
+        });
     }
 
     //Added to satisfy SHIRO-146
@@ -82,7 +84,9 @@ public class PermissionAnnotationHandlerTest extends SecurityManagerTestSupport
 	    }
         };
 
-        assertThrows(UnauthenticatedException.class, () -> handler.assertAuthorized(requiresPermissionAnnotation));
+        runWithSubject(subject -> {
+            assertThrows(UnauthenticatedException.class, () -> handler.assertAuthorized(requiresPermissionAnnotation));
+        });
     }
 
 }
diff --git a/core/src/test/java/org/apache/shiro/authz/aop/RoleAnnotationHandlerTest.java b/core/src/test/java/org/apache/shiro/authz/aop/RoleAnnotationHandlerTest.java
index bcde9f49..0f34001a 100644
--- a/core/src/test/java/org/apache/shiro/authz/aop/RoleAnnotationHandlerTest.java
+++ b/core/src/test/java/org/apache/shiro/authz/aop/RoleAnnotationHandlerTest.java
@@ -61,7 +61,9 @@ public class RoleAnnotationHandlerTest extends SecurityManagerTestSupport {
             }
         };
 
-        assertThrows(UnauthenticatedException.class, () -> handler.assertAuthorized(requiresRolesAnnotation));
+        runWithSubject(subject -> {
+            assertThrows(UnauthenticatedException.class, () -> handler.assertAuthorized(requiresRolesAnnotation));
+        });
     }
 
     //Added to satisfy SHIRO-146
@@ -87,7 +89,9 @@ public class RoleAnnotationHandlerTest extends SecurityManagerTestSupport {
             }
         };
 
-        assertThrows(UnauthenticatedException.class, () -> handler.assertAuthorized(requiresRolesAnnotation));
+        runWithSubject(subject -> {
+            assertThrows(UnauthenticatedException.class, () -> handler.assertAuthorized(requiresRolesAnnotation));
+        });
     }
 
     @Test
diff --git a/core/src/test/java/org/apache/shiro/concurrent/SubjectAwareExecutorServiceTest.java b/core/src/test/java/org/apache/shiro/concurrent/SubjectAwareExecutorServiceTest.java
index 64e89a71..3b8e5ee6 100644
--- a/core/src/test/java/org/apache/shiro/concurrent/SubjectAwareExecutorServiceTest.java
+++ b/core/src/test/java/org/apache/shiro/concurrent/SubjectAwareExecutorServiceTest.java
@@ -47,11 +47,13 @@ public class SubjectAwareExecutorServiceTest extends SecurityManagerTestSupport
 
         final SubjectAwareExecutorService executor = new SubjectAwareExecutorService(mockExecutorService);
 
-        Runnable testRunnable = () -> System.out.println("Hello World");
+        runWithSubject(subject -> {
+            Runnable testRunnable = () -> System.out.println("Hello World");
 
-        executor.submit(testRunnable);
-        SubjectRunnable subjectRunnable = captor.getValue();
-        Assertions.assertNotNull(subjectRunnable);
+            executor.submit(testRunnable);
+            SubjectRunnable subjectRunnable = captor.getValue();
+            Assertions.assertNotNull(subjectRunnable);
+        });
     }
 
     private static class DummyFuture<V> implements Future<V> {
diff --git a/core/src/test/java/org/apache/shiro/concurrent/SubjectAwareExecutorTest.java b/core/src/test/java/org/apache/shiro/concurrent/SubjectAwareExecutorTest.java
index bf506253..7147dc48 100644
--- a/core/src/test/java/org/apache/shiro/concurrent/SubjectAwareExecutorTest.java
+++ b/core/src/test/java/org/apache/shiro/concurrent/SubjectAwareExecutorTest.java
@@ -42,7 +42,7 @@ public class SubjectAwareExecutorTest extends SecurityManagerTestSupport {
         final SubjectAwareExecutor executor = new SubjectAwareExecutor(targetMockExecutor);
 
         Runnable work = () -> System.out.println("Hello World");
-        executor.execute(work);
+        runWithSubject(subject -> executor.execute(work));
 
         //* ensure the target Executor receives a SubjectRunnable instance that retains the subject identity:
         //(this is what verifies the test is valid):
diff --git a/core/src/test/java/org/apache/shiro/test/SecurityManagerTestSupport.java b/core/src/test/java/org/apache/shiro/test/SecurityManagerTestSupport.java
index 486406ff..2bbbc788 100644
--- a/core/src/test/java/org/apache/shiro/test/SecurityManagerTestSupport.java
+++ b/core/src/test/java/org/apache/shiro/test/SecurityManagerTestSupport.java
@@ -26,8 +26,8 @@ import org.apache.shiro.mgt.SecurityManager;
 import org.apache.shiro.realm.text.IniRealm;
 import org.apache.shiro.subject.Subject;
 import org.apache.shiro.util.ThreadContext;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
+
+import java.util.Objects;
 
 /**
  * Utility methods for use by Shiro test case subclasses.  You can use these methods as examples for your own
@@ -64,13 +64,38 @@ public class SecurityManagerTestSupport {
         return SecurityUtils.getSubject();
     }
 
-    @BeforeEach
-    public void setup() {
-        createAndBindTestSubject();
+    protected Subject createSubject() {
+        SecurityManager securityManager = createTestSecurityManager();
+        return new Subject.Builder(securityManager).buildSubject();
+    }
+
+    /**
+     * Associates the {@code consumer} with the {@code subject} and executes. If an exeception was thrown by the
+     * consumer, it is re-thrown by this method.
+     * @param subject The subject to bind to the current thread.
+     * @param consumer The block of code to run under the context of the subject.
+     * @throws Exception propagates any exception thrown by the consumer.
+     */
+    protected void runWithSubject(Subject subject, SubjectConsumer consumer) {
+        Exception exception = subject.execute(() -> {
+            try {
+                consumer.accept(subject);
+                return null;
+            } catch (Exception e) {
+                return e;
+            }
+        });
+        if (Objects.nonNull(exception)) {
+            throw new RuntimeException("Test execution threw exception", exception);
+        }
+    }
+
+    protected void runWithSubject(SubjectConsumer consumer) {
+        runWithSubject(createSubject(), consumer);
     }
 
-    @AfterEach
-    public void teardown() {
-        ThreadContext.remove();
+    @FunctionalInterface
+    protected interface SubjectConsumer {
+        void accept(Subject subject) throws Exception;
     }
 }
diff --git a/web/src/test/groovy/org/apache/shiro/web/filter/authc/BearerHttpFilterAuthenticationTest.groovy b/web/src/test/groovy/org/apache/shiro/web/filter/authc/BearerHttpFilterAuthenticationTest.groovy
index ac7ffea3..dde709a1 100644
--- a/web/src/test/groovy/org/apache/shiro/web/filter/authc/BearerHttpFilterAuthenticationTest.groovy
+++ b/web/src/test/groovy/org/apache/shiro/web/filter/authc/BearerHttpFilterAuthenticationTest.groovy
@@ -43,10 +43,12 @@ class BearerHttpFilterAuthenticationTest extends SecurityManagerTestSupport {
 
         HttpServletRequest request = mockRequest()
         HttpServletResponse response = mockResponse()
-        
-        AuthenticationToken token = testFilter.createToken(request, response)
-        assertThat(token, CoreMatchers.instanceOf(BearerToken.class))
-        assertThat(token.getPrincipal(), Matchers.is(""))
+
+        runWithSubject({
+            AuthenticationToken token = testFilter.createToken(request, response)
+            assertThat(token, CoreMatchers.instanceOf(BearerToken.class))
+            assertThat(token.getPrincipal(), Matchers.is(""))
+        })
 
         verify(request, response)
     }
@@ -57,10 +59,12 @@ class BearerHttpFilterAuthenticationTest extends SecurityManagerTestSupport {
 
         HttpServletRequest request = mockRequest("")
         HttpServletResponse response = mockResponse()
-        
-        AuthenticationToken token = testFilter.createToken(request, response)
-        assertThat(token, CoreMatchers.instanceOf(BearerToken.class))
-        assertThat(token.getPrincipal(), Matchers.is(""))
+
+        runWithSubject({
+            AuthenticationToken token = testFilter.createToken(request, response)
+            assertThat(token, CoreMatchers.instanceOf(BearerToken.class))
+            assertThat(token.getPrincipal(), Matchers.is(""))
+        })
 
         verify(request, response)
     }
@@ -72,9 +76,11 @@ class BearerHttpFilterAuthenticationTest extends SecurityManagerTestSupport {
         HttpServletRequest request = mockRequest("some-value")
         HttpServletResponse response = mockResponse()
 
-        AuthenticationToken token = testFilter.createToken(request, response)
-        assertThat(token, CoreMatchers.instanceOf(BearerToken.class))
-        assertThat(token.getPrincipal(), Matchers.is("some-value"))
+        runWithSubject({
+            AuthenticationToken token = testFilter.createToken(request, response)
+            assertThat(token, CoreMatchers.instanceOf(BearerToken.class))
+            assertThat(token.getPrincipal(), Matchers.is("some-value"))
+        })
 
         verify(request, response)
     }
@@ -86,9 +92,11 @@ class BearerHttpFilterAuthenticationTest extends SecurityManagerTestSupport {
         HttpServletRequest request = mockRequest("  ")
         HttpServletResponse response = mockResponse()
 
-        AuthenticationToken token = testFilter.createToken(request, response)
-        assertThat(token, CoreMatchers.instanceOf(BearerToken.class))
-        assertThat(token.getPrincipal(), Matchers.is(""))
+        runWithSubject({
+            AuthenticationToken token = testFilter.createToken(request, response)
+            assertThat(token, CoreMatchers.instanceOf(BearerToken.class))
+            assertThat(token.getPrincipal(), Matchers.is(""))
+        })
 
         verify(request, response)
     }
@@ -104,9 +112,11 @@ class BearerHttpFilterAuthenticationTest extends SecurityManagerTestSupport {
         HttpServletResponse response = createMock(HttpServletResponse.class)
         replay(response)
 
-        String[] methods =  [ "POST", "PUT", "DELETE" ]
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, methods)
-        assertThat("Access not allowed for GET", accessAllowed)
+        runWithSubject({
+            String[] methods = ["POST", "PUT", "DELETE"]
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, methods)
+            assertThat("Access not allowed for GET", accessAllowed)
+        })
         verify(request, response)
     }
     
@@ -120,9 +130,11 @@ class BearerHttpFilterAuthenticationTest extends SecurityManagerTestSupport {
         
         HttpServletResponse response = mockResponse()
 
-        String[] methods =  [ "POST", "PUT", "DELETE" ]
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, methods)
-        assertThat("Access allowed for POST", !accessAllowed)
+        runWithSubject({
+            String[] methods = ["POST", "PUT", "DELETE"]
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, methods)
+            assertThat("Access allowed for POST", !accessAllowed)
+        })
     }
 
     @Test
@@ -135,9 +147,11 @@ class BearerHttpFilterAuthenticationTest extends SecurityManagerTestSupport {
 
         HttpServletResponse response = mockResponse()
 
-        String[] mappedValue = ["permissive"]
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, mappedValue)
-        assertThat("Access allowed for GET", !accessAllowed) // login attempt should always be false
+        runWithSubject({
+            String[] mappedValue = ["permissive"]
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, mappedValue)
+            assertThat("Access allowed for GET", !accessAllowed) // login attempt should always be false
+        })
     }
 
     @Test
@@ -152,9 +166,11 @@ class BearerHttpFilterAuthenticationTest extends SecurityManagerTestSupport {
 
         HttpServletResponse response = mockResponse()
 
-        String[] mappedValue = ["permissive"]
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, mappedValue)
-        assertThat("Access should be allowed for GET", accessAllowed) // non-login attempt, return true
+        runWithSubject({
+            String[] mappedValue = ["permissive"]
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, mappedValue)
+            assertThat("Access should be allowed for GET", accessAllowed) // non-login attempt, return true
+        })
     }
 
     @Test
@@ -167,9 +183,11 @@ class BearerHttpFilterAuthenticationTest extends SecurityManagerTestSupport {
 
         HttpServletResponse response = mockResponse()
 
-        String[] mappedValue = ["permissive", "POST", "PUT", "DELETE" ]
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, mappedValue)
-        assertThat("Access allowed for POST", !accessAllowed)
+        runWithSubject({
+            String[] mappedValue = ["permissive", "POST", "PUT", "DELETE"]
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, mappedValue)
+            assertThat("Access allowed for POST", !accessAllowed)
+        })
     }
 
     static private String createAuthorizationHeader(String token) {
diff --git a/web/src/test/java/org/apache/shiro/web/filter/authc/BasicHttpFilterAuthenticationTest.java b/web/src/test/java/org/apache/shiro/web/filter/authc/BasicHttpFilterAuthenticationTest.java
index 07607756..997dd9f9 100644
--- a/web/src/test/java/org/apache/shiro/web/filter/authc/BasicHttpFilterAuthenticationTest.java
+++ b/web/src/test/java/org/apache/shiro/web/filter/authc/BasicHttpFilterAuthenticationTest.java
@@ -45,71 +45,71 @@ public class BasicHttpFilterAuthenticationTest extends SecurityManagerTestSuppor
 
     BasicHttpAuthenticationFilter testFilter;
 
-    @BeforeEach
-    public void setUp() {
-    }
-
     @Test
-    public void createTokenNoAuthorizationHeader() throws Exception {
+    public void createTokenNoAuthorizationHeader() {
         testFilter = new BasicHttpAuthenticationFilter();
         HttpServletRequest request = mock(HttpServletRequest.class);
         when(request.getHeader("Authorization")).then(args -> null);
         when(request.getRemoteHost()).then(args -> "localhost");
-        
+
         HttpServletResponse response = mock(HttpServletResponse.class);
-        
-		AuthenticationToken token = testFilter.createToken(request, response);
-		assertNotNull(token);
-		assertTrue(token instanceof UsernamePasswordToken, "Token is not a username and password token.");
-		assertEquals("", token.getPrincipal());
-		
-		verify(request).getHeader("Authorization");
-		verify(request).getRemoteHost();
+
+        runWithSubject(subject -> {
+            AuthenticationToken token = testFilter.createToken(request, response);
+            assertNotNull(token);
+            assertTrue(token instanceof UsernamePasswordToken, "Token is not a username and password token.");
+            assertEquals("", token.getPrincipal());
+
+            verify(request).getHeader("Authorization");
+            verify(request).getRemoteHost();
+        });
     }
 
     @Test
-    public void createTokenNoUsername() throws Exception {
+    public void createTokenNoUsername() {
         testFilter = new BasicHttpAuthenticationFilter();
         HttpServletRequest request = mock(HttpServletRequest.class);
         when(request.getHeader("Authorization")).then(args -> createAuthorizationHeader("", ""));
         when(request.getRemoteHost()).then(args -> "localhost");
-        
+
         HttpServletResponse response = mock(HttpServletResponse.class);
-        
-        
-		AuthenticationToken token = testFilter.createToken(request, response);
-		assertNotNull(token);
-		assertTrue(token instanceof UsernamePasswordToken, "Token is not a username and password token.");
-		assertEquals("", token.getPrincipal());
-
-        verify(request).getHeader("Authorization");
-        verify(request).getRemoteHost();
+
+        runWithSubject(subject -> {
+            AuthenticationToken token = testFilter.createToken(request, response);
+            assertNotNull(token);
+            assertTrue(token instanceof UsernamePasswordToken, "Token is not a username and password token.");
+            assertEquals("", token.getPrincipal());
+
+            verify(request).getHeader("Authorization");
+            verify(request).getRemoteHost();
+        });
     }
 
     @Test
-    public void createTokenNoPassword() throws Exception {
+    public void createTokenNoPassword() {
         testFilter = new BasicHttpAuthenticationFilter();
         HttpServletRequest request = mock(HttpServletRequest.class);
         when(request.getHeader("Authorization")).then(args -> createAuthorizationHeader("pedro", ""));
         when(request.getRemoteHost()).then(args -> "localhost");
-        
+
         HttpServletResponse response = mock(HttpServletResponse.class);
-        
-        
-		AuthenticationToken token = testFilter.createToken(request, response);
-		assertNotNull(token);
-		assertTrue(token instanceof UsernamePasswordToken, "Token is not a username and password token.");
-		
-		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
-		assertEquals("pedro", upToken.getUsername());
-		assertEquals(0, upToken.getPassword().length, "Password is not empty.");
-
-        verify(request).getHeader("Authorization");
-        verify(request).getRemoteHost();
+
+        runWithSubject(subject -> {
+            AuthenticationToken token = testFilter.createToken(request, response);
+            assertNotNull(token);
+            assertTrue(token instanceof UsernamePasswordToken, "Token is not a username and password token.");
+
+            UsernamePasswordToken upToken = (UsernamePasswordToken) token;
+            assertEquals("pedro", upToken.getUsername());
+            assertEquals(0, upToken.getPassword().length, "Password is not empty.");
+
+            verify(request).getHeader("Authorization");
+            verify(request).getRemoteHost();
+        });
     }
 
     @Test
-    public void createTokenColonInPassword() throws Exception {
+    public void createTokenColonInPassword() {
         testFilter = new BasicHttpAuthenticationFilter();
         HttpServletRequest request = mock(HttpServletRequest.class);
         when(request.getHeader("Authorization")).then(args -> createAuthorizationHeader("pedro", "pass:word"));
@@ -117,102 +117,113 @@ public class BasicHttpFilterAuthenticationTest extends SecurityManagerTestSuppor
 
         HttpServletResponse response = mock(HttpServletResponse.class);
 
+        runWithSubject(subject -> {
+            AuthenticationToken token = testFilter.createToken(request, response);
+            assertNotNull(token);
+            assertTrue(token instanceof UsernamePasswordToken, "Token is not a username and password token.");
 
-		AuthenticationToken token = testFilter.createToken(request, response);
-		assertNotNull(token);
-		assertTrue(token instanceof UsernamePasswordToken, "Token is not a username and password token.");
-
-		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
-		assertEquals("pedro", upToken.getUsername());
-		assertEquals("pass:word", new String(upToken.getPassword()));
+            UsernamePasswordToken upToken = (UsernamePasswordToken) token;
+            assertEquals("pedro", upToken.getUsername());
+            assertEquals("pass:word", new String(upToken.getPassword()));
 
-        verify(request).getHeader("Authorization");
-        verify(request).getRemoteHost();
+            verify(request).getHeader("Authorization");
+            verify(request).getRemoteHost();
+        });
     }
     
     @Test
-    public void httpMethodDoesNotRequireAuthentication() throws Exception {
+    public void httpMethodDoesNotRequireAuthentication() {
         testFilter = new BasicHttpAuthenticationFilter();
-        
+
         HttpServletRequest request = mock(HttpServletRequest.class);
         when(request.getMethod()).then(args -> "GET");
-        
+
         HttpServletResponse response = mock(HttpServletResponse.class);
-        
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[] { "POST", "PUT", "DELETE" });
-        assertTrue(accessAllowed, "Access not allowed for GET");
+
+        runWithSubject(subject -> {
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[]{"POST", "PUT", "DELETE"});
+            assertTrue(accessAllowed, "Access not allowed for GET");
+        });
     }
     
     @Test
-    public void httpMethodRequiresAuthentication() throws Exception {
+    public void httpMethodRequiresAuthentication() {
         testFilter = new BasicHttpAuthenticationFilter();
-        
+
         HttpServletRequest request = mock(HttpServletRequest.class);
         when(request.getHeader("Authorization")).then(args -> createAuthorizationHeader("pedro", ""));
         when(request.getRemoteHost()).then(args -> "localhost");
         when(request.getMethod()).then(args -> "POST");
-        
+
         HttpServletResponse response = mock(HttpServletResponse.class);
-        
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[] { "POST", "PUT", "DELETE" });
-        assertFalse(accessAllowed, "Access allowed for POST");
+
+        runWithSubject(subject -> {
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[]{"POST", "PUT", "DELETE"});
+            assertFalse(accessAllowed, "Access allowed for POST");
+        });
     }
     
     @Test
-    public void httpMethodsAreCaseInsensitive() throws Exception {
+    public void httpMethodsAreCaseInsensitive() {
         testFilter = new BasicHttpAuthenticationFilter();
-        
+
         HttpServletRequest request = mock(HttpServletRequest.class);
         when(request.getMethod()).then(args -> "GET");
         when(request.getHeader("Authorization")).then(args -> createAuthorizationHeader("pedro", ""));
         when(request.getRemoteHost()).then(args -> "localhost");
-        
+
         HttpServletResponse response = mock(HttpServletResponse.class);
-        
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[] { "POST", "put", "delete" });
-        assertTrue(accessAllowed, "Access not allowed for GET");
 
-        when(request.getMethod()).then(args -> "post");
-        accessAllowed = testFilter.isAccessAllowed(request, response, new String[] { "post", "put", "delete" });
-        assertFalse(accessAllowed, "Access allowed for POST");
+        runWithSubject(subject -> {
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[]{"POST", "put", "delete"});
+            assertTrue(accessAllowed, "Access not allowed for GET");
+
+            when(request.getMethod()).then(args -> "post");
+            accessAllowed = testFilter.isAccessAllowed(request, response, new String[]{"post", "put", "delete"});
+            assertFalse(accessAllowed, "Access allowed for POST");
+        });
     }
     
     @Test
-    public void allHttpMethodsRequireAuthenticationIfNoneConfigured() throws Exception {
+    public void allHttpMethodsRequireAuthenticationIfNoneConfigured() {
         testFilter = new BasicHttpAuthenticationFilter();
-        
+
         HttpServletRequest request = mock(HttpServletRequest.class);
         when(request.getHeader("Authorization")).then(args -> createAuthorizationHeader("pedro", ""));
         when(request.getRemoteHost()).then(args -> "localhost");
         when(request.getMethod()).then(args -> "GET");
         when(request.getMethod()).then(args -> "POST");
-        
-        HttpServletResponse response = mock(HttpServletResponse.class);
-        
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[0]);
-        assertFalse(accessAllowed, "Access allowed for GET");
-        
-        accessAllowed = testFilter.isAccessAllowed(request, response, new String[0]);
-        assertFalse(accessAllowed, "Access allowed for POST");
+
+        runWithSubject(subject -> {
+            HttpServletResponse response = mock(HttpServletResponse.class);
+
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[0]);
+            assertFalse(accessAllowed, "Access allowed for GET");
+
+            accessAllowed = testFilter.isAccessAllowed(request, response, new String[0]);
+            assertFalse(accessAllowed, "Access allowed for POST");
+        });
     }
     
     @Test
-    public void allHttpMethodsRequireAuthenticationIfNullConfig() throws Exception {
+    public void allHttpMethodsRequireAuthenticationIfNullConfig() {
         testFilter = new BasicHttpAuthenticationFilter();
-        
+
         HttpServletRequest request = mock(HttpServletRequest.class);
         when(request.getHeader("Authorization")).then(args -> createAuthorizationHeader("pedro", ""));
         when(request.getRemoteHost()).then(args -> "localhost");
         when(request.getMethod()).then(args -> "GET");
         when(request.getMethod()).then(args -> "POST");
-        
-        HttpServletResponse response = mock(HttpServletResponse.class);
-        
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, null);
-        assertFalse(accessAllowed, "Access allowed for GET");
-        
-        accessAllowed = testFilter.isAccessAllowed(request, response, null);
-        assertFalse(accessAllowed, "Access allowed for POST");
+
+        runWithSubject(subject -> {
+            HttpServletResponse response = mock(HttpServletResponse.class);
+
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, null);
+            assertFalse(accessAllowed, "Access allowed for GET");
+
+            accessAllowed = testFilter.isAccessAllowed(request, response, null);
+            assertFalse(accessAllowed, "Access allowed for POST");
+        });
     }
 
     /**
@@ -229,9 +240,11 @@ public class BasicHttpFilterAuthenticationTest extends SecurityManagerTestSuppor
 
         HttpServletResponse response = mock(HttpServletResponse.class);
 
-        String[] mappedValue = {"permissive"};
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, mappedValue);
-        assertFalse(accessAllowed, "Access allowed for GET"); // login attempt should always be false
+        runWithSubject(subject -> {
+            String[] mappedValue = {"permissive"};
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, mappedValue);
+            assertFalse(accessAllowed, "Access allowed for GET"); // login attempt should always be false
+        });
     }
 
     /**
@@ -239,18 +252,20 @@ public class BasicHttpFilterAuthenticationTest extends SecurityManagerTestSuppor
      */
     @Test
     public void permissiveEnabledTest() {
-        testFilter = new BasicHttpAuthenticationFilter();
+        runWithSubject(subject -> {
+            testFilter = new BasicHttpAuthenticationFilter();
 
-        HttpServletRequest request = mock(HttpServletRequest.class);
-        when(request.getHeader("Authorization")).then(args -> null);
-        when(request.getRemoteHost()).then(args -> "localhost");
-        when(request.getMethod()).then(args -> "GET");
+            HttpServletRequest request = mock(HttpServletRequest.class);
+            when(request.getHeader("Authorization")).then(args -> null);
+            when(request.getRemoteHost()).then(args -> "localhost");
+            when(request.getMethod()).then(args -> "GET");
 
-        HttpServletResponse response = mock(HttpServletResponse.class);
+            HttpServletResponse response = mock(HttpServletResponse.class);
 
-        String[] mappedValue = {"permissive"};
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, mappedValue);
-        assertTrue(accessAllowed, "Access should be allowed for GET"); // non-login attempt, return true
+            String[] mappedValue = {"permissive"};
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, mappedValue);
+            assertTrue(accessAllowed, "Access should be allowed for GET"); // non-login attempt, return true
+        });
     }
 
     /**
@@ -258,17 +273,19 @@ public class BasicHttpFilterAuthenticationTest extends SecurityManagerTestSuppor
      */
     @Test
     public void httpMethodRequiresAuthenticationWithPermissive() throws Exception {
-        testFilter = new BasicHttpAuthenticationFilter();
+        runWithSubject(subject -> {
+            testFilter = new BasicHttpAuthenticationFilter();
 
-        HttpServletRequest request = mock(HttpServletRequest.class);
-        when(request.getHeader("Authorization")).then(args -> createAuthorizationHeader("pedro", ""));
-        when(request.getRemoteHost()).then(args -> "localhost");
-        when(request.getMethod()).then(args -> "POST");
+            HttpServletRequest request = mock(HttpServletRequest.class);
+            when(request.getHeader("Authorization")).then(args -> createAuthorizationHeader("pedro", ""));
+            when(request.getRemoteHost()).then(args -> "localhost");
+            when(request.getMethod()).then(args -> "POST");
 
-        HttpServletResponse response = mock(HttpServletResponse.class);
+            HttpServletResponse response = mock(HttpServletResponse.class);
 
-        boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[] {"permissive", "POST", "PUT", "DELETE" });
-        assertFalse(accessAllowed, "Access allowed for POST");
+            boolean accessAllowed = testFilter.isAccessAllowed(request, response, new String[]{"permissive", "POST", "PUT", "DELETE"});
+            assertFalse(accessAllowed, "Access allowed for POST");
+        });
     }
 
     private String createAuthorizationHeader(String username, String password) {
diff --git a/web/src/test/java/org/apache/shiro/web/filter/authz/AuthorizationFilterTest.java b/web/src/test/java/org/apache/shiro/web/filter/authz/AuthorizationFilterTest.java
index c02f1d22..ef27aba8 100644
--- a/web/src/test/java/org/apache/shiro/web/filter/authz/AuthorizationFilterTest.java
+++ b/web/src/test/java/org/apache/shiro/web/filter/authz/AuthorizationFilterTest.java
@@ -18,10 +18,8 @@
  */
 package org.apache.shiro.web.filter.authz;
 
-import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.authc.UsernamePasswordToken;
 import org.apache.shiro.test.SecurityManagerTestSupport;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInstance;
 
@@ -29,7 +27,6 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
 
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.mock;
@@ -39,62 +36,63 @@ import static org.mockito.Mockito.when;
 /**
  * Test cases for the {@link AuthorizationFilter} class.
  */
-@TestInstance(TestInstance.Lifecycle.PER_CLASS)
 public class AuthorizationFilterTest extends SecurityManagerTestSupport {
 
     @Test
-    @Disabled
-    public void testUserOnAccessDeniedWithResponseError() throws IOException {
+    public void testUserOnAccessDeniedWithResponseError() {
         // Tests when a user (known identity) is denied access and no unauthorizedUrl has been configured.
         // This should trigger an HTTP response error code.
 
         //log in the user using the account provided by the superclass for tests:
-        SecurityUtils.getSubject().login(new UsernamePasswordToken("test", "test"));
+        runWithSubject(subject -> {
+            subject.login(new UsernamePasswordToken("test", "test"));
         
-        AuthorizationFilter filter = new AuthorizationFilter() {
-            @Override
-            protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
-                return false; //for this test case
-            }
-        };
-
-        HttpServletRequest request = mock(HttpServletRequest.class);
-        HttpServletResponse response = mock(HttpServletResponse.class);
-
-        // response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
-        filter.onAccessDenied(request, response);
-        verify(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
+            AuthorizationFilter filter = new AuthorizationFilter() {
+                @Override
+                protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
+                    return false; //for this test case
+                }
+            };
+
+            HttpServletRequest request = mock(HttpServletRequest.class);
+            HttpServletResponse response = mock(HttpServletResponse.class);
+
+            // response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+            filter.onAccessDenied(request, response);
+            verify(response).sendError(HttpServletResponse.SC_UNAUTHORIZED);
+        });
     }
 
     @Test
-    @Disabled
-    public void testUserOnAccessDeniedWithRedirect() throws IOException {
+    public void testUserOnAccessDeniedWithRedirect() {
         // Tests when a user (known identity) is denied access and an unauthorizedUrl *has* been configured.
         // This should trigger an HTTP redirect
 
         //log in the user using the account provided by the superclass for tests:
-        SecurityUtils.getSubject().login(new UsernamePasswordToken("test", "test"));
+        runWithSubject(subject -> {
+            subject.login(new UsernamePasswordToken("test", "test"));
 
-        String unauthorizedUrl = "unauthorized.jsp";
+            String unauthorizedUrl = "unauthorized.jsp";
 
-        AuthorizationFilter filter = new AuthorizationFilter() {
-            @Override
-            protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
-                return false; //for this test case
-            }
-        };
-        filter.setUnauthorizedUrl(unauthorizedUrl);
+            AuthorizationFilter filter = new AuthorizationFilter() {
+                @Override
+                protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
+                    return false; //for this test case
+                }
+            };
+            filter.setUnauthorizedUrl(unauthorizedUrl);
 
-        HttpServletRequest request = mock(HttpServletRequest.class);
-        HttpServletResponse response = mock(HttpServletResponse.class);
+            HttpServletRequest request = mock(HttpServletRequest.class);
+            HttpServletResponse response = mock(HttpServletResponse.class);
 
-        String encoded = "/" + unauthorizedUrl;
-        when(response.encodeRedirectURL(unauthorizedUrl)).thenReturn(encoded);
-        response.sendRedirect(encoded);
+            String encoded = "/" + unauthorizedUrl;
+            when(response.encodeRedirectURL(unauthorizedUrl)).thenReturn(encoded);
+            response.sendRedirect(encoded);
 
-        filter.onAccessDenied(request, response);
+            filter.onAccessDenied(request, response);
 
-        verify(response, atLeastOnce()).sendRedirect(encoded);
-        verify(response).encodeRedirectURL(unauthorizedUrl);
+            verify(response, atLeastOnce()).sendRedirect(encoded);
+            verify(response).encodeRedirectURL(unauthorizedUrl);
+        });
     }
 }